d在對于剛接觸編程這個領域的同學,對排序還沒有一定的了解的時候,就光是聽到快速排序這個名稱就會覺得很有吸引力,這個名字取得粗魯且自信,讓人不得不想去了解一下他自信的來源
快速排序其實是對冒泡排序的一種改進,名字里面的快速兩個字得確也有自信的實力,它相對于其他幾種排序來說效率較高,速度更快,但對于初學者而言,快速排序還是很難理解的,因為快速排序的一些特殊性,現在很多公司也會去選擇它作為面試的考題,如果僅僅是依靠背代碼,默寫的方式的話估計很難去把快速排序寫好,所以我們這個時候就得知道思路的一個重要性,只有把它的思想理解到位,我們才能更快的把快速排序學會。
首先,我們先來看一下快速排序的一個概念
快速排序是指通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行之前的操作,以此達到整個數據變成有序序列。
我們根據它的概念來詳細看一下快速排序的思路
第一步如圖1-1所示,先得去找一個基準數,一般來說數組第一個為基準數,現在可以理解為數組第一個數賦值給了key,成為基準數,數組的第一個位置產生了空缺(有位置沒人坐)
int key = a[i];
再去找到一個最左邊的下標,一個最右邊的下標(其實就是長度減一)
int left = 0, int right = 6;
因為左右兩個下標是不會變動的,所以后期為了我們數組左右兩邊的數能夠和基準數更好的進行比對,我們再去定義兩個下標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;
}