c語言min函式的使用方法_C語言qsort()函式的使用
技術標籤:c語言min函式的使用方法
qsort()函式是 C 庫中實現的快速排序演算法,包含在 stdlib.h
標頭檔案中,其時間複雜度為 O(nlogn)。函式原型如下:
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
此函式需要四個引數。
第一個引數是需要排序的陣列的基地址,因為是 void *
型別,所以此函式可以給任何型別的陣列進行排序;
第二個引數是待排序的數量(size_t 是一種特別的資料型別,可以近似理解為 int 型);
第三個是單個數組元素的大小,即位元組數,例如 int 型就是 4 或者 sizeof(int)
(sizeof 的返回值型別就是 sizeof
),char 型就是 1 或者
sizeof(char)
。因為為了適用於各種資料結構,第一個引數將指向陣列的指標強轉成了 void *
型別,也即此時函式並不知道將要進行排序的陣列記憶體儲的是什麼元素,因此我們需要顯式地告訴它單個元素所佔的長度;
第四個引數是一個指向函式的指標,其作用是規定排序的規則,即按照什麼樣的方式進行排序。
下面我們對一個整型陣列排序為例:
#include<stdio.h> #include<stdlib.h> //比較函式原型 int mycmp(const void* p1, const void* p2); int main() { int num[10] = {32, -4, 89, 232, 2, 12, -32, 0, -4, 89}; qsort(num, 10, sizeof(int), mycmp); for(int i=0; i<10; i++) printf("%d ", num[i]); printf("n"); return 0; } //比較函式 int mycmp(const void* p1, const void* p2){ const int * a = (const int *) p1; const int * b = (const int *) p2; int value = 0; if(*a < *b) value = -1; else if(*a == *b) value = 0; else value = 1; return value; }
執行結果如下所示:
使用 qsort
最重要的是比較函式的編寫。
首先,qsort
函式的原型中已經對此元素的原型有了明確的規定:int (*compar)(const void *, const void *)
,需要傳入指向兩個元素的指標。
與上文增加第三個引數的原因相同,比較函式的引數指標是 void *
型別,這個引數同樣不知道元素實際的大小,因此我們需要進行型別的強轉,轉換成元素實際型別對應的指標,例如上文中為了給一個 int
型陣列排序:
const int * a = (const int *) p1; const int * b = (const int *) p2;
然後,兩個元素之間的比較結果無非 > 、= 、< ,我們要給希望成立的結果返回 1,例如:如果希望從小到大排列,則 *a < *b
成立時返回 1;如果希望從大到小排列,則 *a > *b
返回 1,相應的 *a == *b
返回 0,*a < *b
返回 -1.
因此如果將上述程式的 1 和 -1 顛倒位置,結果就會變成降序排列:
因為可以任意編寫比較函式,當比較具有優先順序時我們也可以從容解決。
例如:
定義了這樣一個表示時間的結構體:
struct Time {
int hour;
int min;
int sec;
};
如果對此型別的陣列元素進行升序排列,那麼比較函式應該為:
int mycomp(const void * p1, const void * p2){
const Time * a = (const Time *) p1;
const Time * b = (const Time *) p2;
int value = 0;
if(a->hour > b->hour)
value = 1;
else if(a->hour < b->hour)
value = -1;
else{
if(a->min > b->min)
value = 1;
else if(a->min < b->min)
value = -1;
else{
if(a->sec > b->sec)
value = 1;
else if(a->sec < b->sec)
value = -1;
else value = 0;
}
}
return value;
}