快速排序函數qsort介紹

來自:http://www.cnblogs.com/CCBB/archive/2010/01/15/1648827.html

C/C++中有一個快速排序的標準庫函數 qsort ,在stdlib.h 中聲明,其原型爲:

void qsort(void *base, int nelem, unsigned int width, int ( * pfCompare)( const void *, const void *));

  使用該函數,可以對任何類型的一維數組排序。該函數參數中,base 是待排序數組的起始地址,nelem 是待排序數組的元素個數,width 是待排序數組的每個元素的大小(以字節爲單位),最後一個參數 pfCompare 是一個函數指針,它指向一個“比較函數”。排序就是一個不斷比較並交換位置的過程。qsort 如何在連元素的類型是什麼都不知道的情況下,比較兩個元素並判斷哪個應該在前呢?答案是,qsort 函數在執行期間,會通過pfCompare指針調用一個 “比較函數”,用以判斷兩個元素哪個更應該排在前面。這個“比較函數”不是C/C++的庫函數,而是由使用qsort 的程序員編寫的。在調用qsort 時, 將“比較函數”的名字作爲實參傳遞給pfCompare。程序員當然清楚該按什麼規則決定哪個元素應該在前,哪個元素應該在後,這個規則就體現在“比較函數”中。

qsort 函數的用法規定,“比較函數”的原型應是:int 函數名(const void * elem1, const void * elem2);該函數的兩個參數,elem1 和elem2,指向待比較的兩個元素。也就是說, * elem1 和* elem2 就是待比較的兩個元素。該函數必須具有以下行爲:

  1) 如果 * elem1 應該排在 * elem2 前面,則函數返回值是負整數(任何負整數都行)。

  2) 如果 * elem1 和* elem2 哪個排在前面都行,那麼函數返回0

  3) 如果 * elem1 應該排在 * elem2 後面,則函數返回值是正整數(任何正整數都行)。

例如:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

int compare(const void *a, const void *b)
{
    int *pa = (int*)a;
    int *pb = (int*)b;
    return (*pa )- (*pb);  //從小到大排序
}

void main()
{
    int a[10] = {5, 6, 4, 3, 7, 0 ,8, 9, 2, 1};
    qsort(a, 10, sizeof(int), compare);
    for (int i = 0; i < 10; i++)
        cout << a[i] << " " << endl;

再如:

下面的程序,功能是調用qsort 庫函數,將一個unsigned int 數組按照個位數從小到大進行排序。比如 8,23,15 三個數,按個位數從小到大排序,就應該是 23,15,8:

#include <stdio.h>
#include <stdlib.h>
int MyCompare( const void * elem1, const void * elem2
{
  unsigned int * p1, * p2;
  p1 = (unsigned int *) elem1;  //語句6
  p2 = (unsigned int *) elem2;  //語句7
  return (* p1 % 10) - (* p2 % 10 );  //語句8
}
#define NUM 5
int main()
{
  unsigned int an[NUM] = { 8,123,11,10,4 };
  qsort( an, NUM, sizeof(unsigned int), MyCompare);
  for( int i = 0;i < NUM; i ++ )
    printf("%d ", an[i]);
  return 0;

上面程序的輸出結果是:
10 11 123 4 8

qsort 函數執行期間,需要比較兩個元素哪個應在前面時,就以兩個元素的地址作爲參數,調用 MyCompare 函數。如果返回值小於0,則qsort 就得知第一個元素應該在前,如果返回值大於0,則第一個元素應該在後。如果返回值等於0,則哪個在前都行。
對語句6 解釋如下:由於elem1 是 const void * 類型的,是void 指針,那麼表達式“*elem1”是沒有意義的。elem1 應指向待比較的元素,即一個unsigned int 類型的變量,所以要經過強制類型轉換,將elem1 裏存放的地址賦值給 p1,這樣,* p1 就是待比較的第
一個元素了。語句7 同理。語句8 體現了排序的規則。如果 *p1 的個位數小於 *p2 的個位數,那麼就返回負值。其他兩種情況不再贅述。 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章