函數概述 qsort 為quick sort的簡寫,意為快速排序,主要用於對各種數組的排序,在頭文件stdlib.h中。 因為數組的元素可能是任何類型的,甚至是結構或者聯合,所以必須高數函數qsort如何確定兩個數組元素哪一個“更小”,這就需要我們給出比較的規則,即什麼算大,什麼算小。 通過編寫比較 ...
函數概述
qsort 為quick sort的簡寫,意為快速排序,主要用於對各種數組的排序,在頭文件stdlib.h中。
因為數組的元素可能是任何類型的,甚至是結構或者聯合,所以必須高數函數qsort如何確定兩個數組元素哪一個“更小”,這就需要我們給出比較的規則,即什麼算大,什麼算小。
通過編寫比較函數可以為函數qsort提供這些信息。當給定兩個指向數組元素的指針p和q時,比較函數必須返回一個整數。如果*p小於*q,那麼返回的數為負數;如果*p等於*q,那麼返回0.如果*p大於*q,返回正數。
函數原型
void qsort(void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *))
函數描述
函數的形式參數從左到右分別為:
指向要排序數組的第一個元素的指針base(如果只是要對數組的一段區域進行排序,那麼要是base指向這段區域的第一個元素。)在一般情況下,base就是數組的名字;
nmemb是要排序元素的數量(不一定是數組中元素的數量);
size是每個數組元素的大小,用位元組來衡量;
compar為指向比較函數的指針。
比較函數的實現
比較函數的實現是qsort函數能否正確實現的重點。
編寫比較函數並沒有想象中的那麼容易。函數qsort要求它的形式參數類型為void *,但我們不能通過void *型的指針訪問數組的成員;我們需要指向要比較元素的類型的指針。為瞭解決這個問題,我們將在比較函數內部把p與q賦給相應對應類型的指針變數。由於常量指針不能賦值給變數。所以在聲明對應指針變數時應該加上const關鍵字。
下麵是一個比較整型數組的比較函數的例子。
int compare(const void *p, const void *q)
{
const int *p1 = p;
const int *q1 = q;
if (*p1 < *q1)
return -1;
else if (*p1 == *q1)
return 0;
else
return 1;
}
當然除了把用const指針變數的方法,還可以使用強制類型轉換的方式來達到這個目的。
int compare(const void *p,const void *q)
{
if(*(int *)p<*(int *)q)
return -1;
else if(*(int *)p==*(int *)q)
return 0;
else
return 1;
}
還可以進一步精簡
int compare(const void *p,const void *q)
{
return *(int *)p-*(int *)q;
}
需要註意的點:比較元素是指針的比較函數的實現。
如果待比較的元素是指針(雖然我們一般不會比較指針的大小,但是我們經常需要對指針代表的空間比較大小,比如比較一個字元串數組的大小,每個字元串都由一個指針代表),那麼比較函數的實現就比較麻煩了。
首先我們需要明確的是,比較函數中的兩個指針必須要指向需要比較的兩個元素。如果這兩個元素是指針而不是一個實體,那麼這兩個指針應該是指向指針的指針。
這裡我們以一個比較字元串的比較函數舉例:
int compare(const void *p,const void *q)
{
return strcmp(*(char **)p,*(char **)q);
}