c語言qsort函數(快速排序)
創(chuàng)新互聯公司是專業(yè)的孝南網站建設公司,孝南接單;提供成都網站制作、網站設計、外貿網站建設,網頁設計,網站設計,建網站,PHP網站建設等專業(yè)做網站服務;采用PHP框架,可快速的進行孝南網站開發(fā)網頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網站,專業(yè)的做網站團隊,希望更多企業(yè)前來合作!在學習c語言時我們常常會遇到一些排序的問題,在遇到這些排序的問題的時候,我們當然可以自己選擇寫出自己的排序方法來進行排序。但是我們今天要介紹的是c語言庫函數中所提供的一個快排函數。這個函數可以直接提供給我們快排這樣一個工具,在面對一些情況的時候會起到事半功倍的效果。此外,它能夠排序任意數據類型的數組其中包括整形,浮點型,字符串甚至還有自定義的結構體類型,合理使用時非常方便。
一.qsort函數的參數下圖為cplusplus.com的標準庫函數說明
其函數聲明如下
void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
1.首元素地址base我們要排序一組數據,首先我們需要找到這組數據在哪,因此我們直接將首元素的地址傳給qsort函數的指針void*來確定從這個數組的哪個地方開始排序。
2.元素的個數num我們將需要排序的元素的個數傳給qsort函數來確定一組數據。這是因為我們知道了從哪開始,也要知道在哪結束才能確定一組需要排序的數據,但是我們不方便直接將結尾元素的地址傳入函數。
3.元素大小size我們需要將元素大小傳入qsort函數。qsort函數能排序任意數據類型的一組數據,因此我們用void*類型的指針來接收元素,但是我們知道void*類型的指針不能進行加減操作,也就是說無法移動。那么在函數內部我們究竟用什么類型的指針來操作變量呢?其實在函數內部,我們可以將void*類型的指針強制類型轉換成char*類型的指針后來逐個字節(jié)地來操作元素,因為char*類型的指針移動的單位字節(jié)長度是1個字節(jié),我們只需要知道需要操作的數據是幾個字節(jié)就可以實現指針從一個元素恰好能夠移動到下一個元素。
4.用戶自定義的比較函數compar我們需要告訴qsort函數我們希望數據按照怎么的方式進行比較。同需要傳遞元素個數的道理一樣,qsort函數能排序任意數據類型的一組數據,因此庫函數用void*類型的指針來指定我們我們編寫的比較方式,可以起到不把函數寫死,根據實際情況的需要寫的作用。同時我們可以看到編寫的函數的返回值大于零時,qsort函數會將數組里面前一個元素放在后一個元素后面,也就是兩個元素進行調換。
二.比較函數的書寫qsort函數給cmpar函數規(guī)定了特定的參數const void* 。因此我們自定義函數時要嚴格遵守其參數設定。
如果你需要比較的是整形數組,你需要將比較函數中void*強制轉換成int *,同時如果你希望qsort
進行升序快排,我們需要使得前一個數字比后一個數字大的時候返回1.
int compar(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
同理如果需要進行降序快排的話
int compar(const void* e1, const void* e2)
{
return *(int*)e2 - *(int*)e1;
}
比較的是字符串的大小,并進行升序快排的話:
int compare_str(const void* e1, const void* e2)
{
return strcmp((char*)e1, (char*)e2);
}
比較的是字符串的長度,并進行升序快排的話:
int cmp_str_len(const void* e1, const void* e2)
{
return strlen((char*)e1)-strlen((char*)e2);
}
比較結構體時需要指明需要比較的具體變量,就像我們不能比較一個人,除非有相應的標準:
int cmp_struct_stu_name(const void* e1, const void* e2)
{
return strcmp( ((struct stu*)e1)->name, ((struct stu*)e2)->name );
}
int cmp_struct_stu_GPA(const void* e1, const void* e2)
{
return ( ((struct stu*)e2)->GPA - ((struct stu*)e1)->GPA );
}
三.實例演示#define _CRT_SECURE_NO_WARNINGS 1
#include#includestruct stu
{
char name[20];
float GPA;
};
int compare_str(const void* e1, const void* e2)
{
return strcmp((char*)e1, (char*)e2);
}
int cmp_str_len(const void* e1, const void* e2)
{
return strlen((char*)e1) - strlen((char*)e2);
}
int cmp_struct_stu_name(const void* e1, const void* e2)
{
return strcmp( ((struct stu*)e1)->name, ((struct stu*)e2)->name );
}
int cmp_struct_stu_GPA(const void* e1, const void* e2)
{
return ( ((struct stu*)e2)->GPA - ((struct stu*)e1)->GPA );
}
int main()
{
int i = 0;
struct stu s[3] = { {"zhangsan",3.4} ,{"zhangmazi",4.0} ,{"dingzhen",1.0} };
qsort(s, 3, sizeof(s[0]), cmp_struct_stu_name);
for (i = 0; i< 3; i++)
{
printf("%s %f\n", s[i].name, s[i].GPA);
}
qsort(s, 3, sizeof(s[0]), cmp_struct_stu_GPA);
for (i = 0; i< 3; i++)
{
printf("%s %f\n", s[i].name, s[i].GPA);
}
}
可以看到只需要我們按要求寫好參數qsort函數就能夠幫我們對元素進行排序。
四.函數所需要的頭文件包含在stdlib.h頭文件中,函數一共有四個參數,沒有返回值。
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧