【c/c++程序設計技巧】十大排序算法——快速排序

d在對于剛接觸編程這個領域的同學,對排序還沒有一定的了解的時候,就光是聽到快速排序這個名稱就會覺得很有吸引力,這個名字取得粗魯且自信,讓人不得不想去了解一下他自信的來源


快速排序其實是對冒泡排序的一種改進,名字里面的快速兩個字得確也有自信的實力,它相對于其他幾種排序來說效率較高,速度更快,但對于初學者而言,快速排序還是很難理解的,因為快速排序的一些特殊性,現在很多公司也會去選擇它作為面試的考題,如果僅僅是依靠背代碼,默寫的方式的話估計很難去把快速排序寫好,所以我們這個時候就得知道思路的一個重要性,只有把它的思想理解到位,我們才能更快的把快速排序學會。


首先,我們先來看一下快速排序的一個概念

快速排序是指通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行之前的操作,以此達到整個數據變成有序序列。


我們根據它的概念來詳細看一下快速排序的思路

第一步如圖1-1所示,先得去找一個基準數,一般來說數組第一個為基準數,現在可以理解為數組第一個數賦值給了key,成為基準數,數組的第一個位置產生了空缺(有位置沒人坐)

int key = a[i];

再去找到一個最左邊的下標,一個最右邊的下標(其實就是長度減一)

int left = 0, int right = 6;



圖1-1




因為左右兩個下標是不會變動的,所以后期為了我們數組左右兩邊的數能夠和基準數更好的進行比對,我們再去定義兩個下標i,j分別等于left,right(如圖1-2所示)

int i = left,j = right;

i 和 j就會一個從左邊進行比較,一個從右邊進行比較,記錄每次比較之后的下標



圖1-2


接下來從右邊第一個數開始和基準數對比,該數如果大于基準數的話(a[j] > key),它的位置則不變,繼續下一個數的對比(j--),如果小于基準數的話(a[j] < key),就結束右邊的對比,該數就放到空缺的位置上面去(a[i] = a[j]),新的空缺位產生 (如圖1-3所示)

while( (a[j] > key))

{

j--;

}

a[i] = a[j];



圖1-3

(若出稿請在素材中更換此圖,刪除本句話)




接下來再從左邊的數開始和基準數對比,如果該數比基準數小(a[i] < key),則位置保持不變,繼續下一個數的對比(i++),如果比基準數大(a[i] > key)則結束左邊的對比,該數移到空缺位(a[j] = a[i]),新的空缺位產生(如圖1-4所示)

while( (a[i] < key))

{

i++;

}

a[j] = a[i];



圖1-4

(若出稿請在素材中更換此圖,刪除本句話)



繼續從右邊上一次的位置進行之前相同的操作(如圖1-5所示)


圖1-5

(若出稿請在素材中更換此圖,刪除本句話)



現在就回到了左邊,我們可以清晰的看到i 和 j已經相遇了那這個時候第一次對比結束,將基準數放回最后的空缺位置,a[i] = key;

第一次快排結束(如圖1-6所示)

這時候聰明的同學就會發現一個隱藏條件,也是循環的退出條件i < j


圖1-6

(若出稿請在素材中更換此圖,刪除本句話)


第一次快排結束之后整個排序并沒有結束,接下來我們通過遞歸繼續剩下來的對比,由之前這個基準數為界,劃分為左右兩部分,兩部分同時進行第一次快排相同的步驟,直到全部比較完變成一個有序的數組

sort(a,left,i-1);

sort(a,i+1,right);



以上呢,是數組實現快速排序的基本步驟,一些重點的代碼部分也寫了出來,為的就是讓同學們學會將思想轉化為代碼


那接下來我們來一起看看快速排序的完整代碼


#include <stdio.h>



void sort(int a[],int left,int right)

{

int i = left,j = right;

int key = a[i];

if(left?>= right)//左邊始終要小于我們的右邊,如果等于結束整個程序

return;

while(i < j)// ?每次快排退出條件

{

while((i < j) && (a[j] > key))

{

j--;

}

a[i] = a[j];

??? while((i < j) && (a[i] < key))// 這里的i < j防止上面的j減過頭導致程序出現錯誤

{

i++;

}

a[j] = a[i];

}

a[i] = key;

sort(a,left,i-1);//遞歸將數組分成兩部分同時進行快排

sort(a,i+1,right);// ?i ?就是第一次快排相遇的下標位置

}


int main()

{

int i;

int a[]={2,1,5,4,6,3};

int len = sizeof(a)/sizeof(a[0]);

sort(a,0,len-1);//傳參,left = 0,right = 長度 - 1

for(i = 0; i < len; i++)

{

printf("%d",a[i]);

}

printf("\n");

return 0;

}


?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容