補(bǔ)充知識(shí):qsort的使用

C/C++中有一個(gè)快速排序的標(biāo)準(zhǔn)庫函數(shù) qsort ,在stdlib.hcstdlib 中聲明种玛,其原型為:

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

使用該函數(shù)尔当,可以對(duì)任何類型的一維數(shù)組排序配喳。

  • base是待排序數(shù)組的起始地址;
  • nelem是待排序數(shù)組的元素個(gè)數(shù);
  • width 是待排序數(shù)組的每個(gè)元素的大凶寤础(以字節(jié)為單位);
  • pfCompare 是一個(gè)函數(shù)指針辫红,它指向一個(gè)“比較函數(shù)”凭涂。
    排序就是一個(gè)不斷比較并交換位置的過程qsort 如何在連元素的類型是什么都不知道的情況下贴妻,比較兩個(gè)元素并判斷哪個(gè)應(yīng)該在前呢切油?
    答案是:qsort 函數(shù)在執(zhí)行期間,會(huì)通過pfCompare指針調(diào)用一個(gè) “比較函數(shù)”名惩,用以判斷兩個(gè)元素哪個(gè)更應(yīng)該排在前面白翻。這個(gè)“比較函數(shù)”不是C/C++的庫函數(shù),而是由使用qsort 的程序員編寫的绢片。在調(diào)用qsort 時(shí), 將“比較函數(shù)”的名字作為實(shí)參傳遞給pfCompare滤馍。程序員當(dāng)然清楚該按什么規(guī)則決定哪個(gè)元素應(yīng)該在前,哪個(gè)元素應(yīng)該在后底循,這個(gè)規(guī)則就體現(xiàn)在“比較函數(shù)”中巢株。

qsort 函數(shù)的用法規(guī)定,“比較函數(shù)”的原型應(yīng)是:int 函數(shù)名(const void * elem1, const void * elem2);該函數(shù)的兩個(gè)參數(shù)熙涤,elem1elem2阁苞,分別指向待比較的兩個(gè)元素。也就是說祠挫, * elem1* elem2 就是待比較的兩個(gè)元素那槽。該函數(shù)必須具有以下行為:

  • 如果 * elem1 應(yīng)該排在 * elem2 前面,則函數(shù)返回值是負(fù)整數(shù)(任何負(fù)整數(shù)都行);
  • 如果 * elem1* elem2 哪個(gè)排在前面都行等舔,那么函數(shù)返回0;
  • 如果* elem1 應(yīng)該排在* elem2 后面骚灸,則函數(shù)返回值是正整數(shù)(任何正整數(shù)都行)。

例如:

#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;
} 

再如:

下面的程序慌植,功能是調(diào)用qsort 庫函數(shù)甚牲,將一個(gè)unsigned int 數(shù)組按照個(gè)位數(shù)從小到大進(jìn)行排序。比如 8蝶柿,23丈钙,15 三個(gè)數(shù),按個(gè)位數(shù)從小到大排序交汤,就應(yīng)該是 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;
} 

上面程序的輸出結(jié)果是:

10 11 123 4 8

qsort 函數(shù)執(zhí)行期間芙扎,需要比較兩個(gè)元素哪個(gè)應(yīng)在前面時(shí)星岗,就以兩個(gè)元素的地址作為參數(shù),調(diào)用 MyCompare 函數(shù)纵顾。如果返回值小于0伍茄,則qsort 就得知第一個(gè)元素應(yīng)該在前栋盹,如果返回值大于0施逾,則第一個(gè)元素應(yīng)該在后敷矫。如果返回值等于0,則哪個(gè)在前都行汉额。
對(duì)語句6 解釋如下:由于elem1const void * 類型的曹仗,是void 指針,那么表達(dá)式*elem1是沒有意義的蠕搜。elem1 應(yīng)指向待比較的元素怎茫,即一個(gè)unsigned int 類型的變量,所以要經(jīng)過強(qiáng)制類型轉(zhuǎn)換妓灌,將elem1 里存放的地址賦值給 p1轨蛤,這樣,* p1 就是待比較的第一個(gè)元素了虫埂。語句7 同理祥山。語句8 體現(xiàn)了排序的規(guī)則。如果 *p1 的個(gè)位數(shù)小于 *p2 的個(gè)位數(shù)掉伏,那么就返回負(fù)值缝呕。其他兩種情況不再贅述。

轉(zhuǎn)載鏈接:https://www.cnblogs.com/CCBB/archive/2010/01/15/1648827.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斧散,一起剝皮案震驚了整個(gè)濱河市供常,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸡捐,老刑警劉巖栈暇,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異箍镜,居然都是意外死亡瞻鹏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門鹿寨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來新博,“玉大人,你說我怎么就攤上這事脚草『涨模” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵馏慨,是天一觀的道長埂淮。 經(jīng)常有香客問我,道長写隶,這世上最難降的妖魔是什么倔撞? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮慕趴,結(jié)果婚禮上痪蝇,老公的妹妹穿的比我還像新娘鄙陡。我一直安慰自己,他們只是感情好躏啰,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布趁矾。 她就那樣靜靜地躺著,像睡著了一般给僵。 火紅的嫁衣襯著肌膚如雪毫捣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天帝际,我揣著相機(jī)與錄音蔓同,去河邊找鬼。 笑死蹲诀,一個(gè)胖子當(dāng)著我的面吹牛牌柄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播侧甫,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼珊佣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了披粟?” 一聲冷哼從身側(cè)響起咒锻,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎守屉,沒想到半個(gè)月后惑艇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拇泛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年滨巴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俺叭。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恭取,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出熄守,到底是詐尸還是另有隱情蜈垮,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布裕照,位于F島的核電站攒发,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏晋南。R本人自食惡果不足惜惠猿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望负间。 院中可真熱鬧偶妖,春花似錦姜凄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玩祟。三九已至腹缩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間空扎,已是汗流浹背藏鹊。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留转锈,地道東北人盘寡。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像撮慨,于是被迫代替她去往敵國和親竿痰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容