演算法用兩個字形容,好玩,三個字形容,有意思。
假設我們現在對「6 1 2 7 9 3 4 5 10 8」這個10個數進行排序。首先在這個序列中隨便找乙個數作為基準數,為了方便,就讓第乙個數6作為基準數吧(最好為第乙個數,至於為什麼,自己可以好好想想)。
在初始狀態下,數字6在序列的第1位。我們的目標是將6挪到序列中間的某個位置,假設這個位置是x。現在就需要尋找這個x,並且以第x位為分界點,即左邊的數都小於等於6,右邊的數都大於等於6。
方法其實也不是很難:分別從初始序列兩端開始「探測」。假設有兩個變數(m和n)在序列上蹦躂,m從左往右蹦躂,n從右往左蹦躂。因為此處設定的基準數是最左邊的數,所以需要n先出動,這一點非常重要(請一定想一想為什麼)。n先從右往左找乙個小於基準數的數,然後m再從左往右找乙個大於基準數的數,然後交換他們。如果m和n相遇了,那麼太好了,說明此時「探測」結束。最後我們將基準數和相遇的位置數進行交換就好了。
此時第一輪的「探測」就算完結了,此時的序列順序應該是3 1 2 5 4 6 9 7 10 8。這時以基準數6為分界點,6左邊的數都小於等於6,6右邊的數都大於等於6。回顧一下剛才的過程,其實n的使命就是要找小於基準數的數,而m的使命就是要找大於基準數的數,直到m和n碰頭為止。
那麼現在基準數6已經歸位,它正好處在序列的第6位。此時我們已經將原來的序列,以6為分界點拆分成了兩個序列,左邊的序列是「3 1 2 5 4」,右邊的序列是「9 7 10 8」。接下來還需要分別處理這兩個序列,方法同上。
左邊的序列是「3 1 2 5 4」。請將這個序列以3為基準數進行調整,使得3左邊的數都小於等於3,3右邊的數都大於等於3。自己算算,如果算完的序列順序為2 1 3 5 4就對了。
好了,現在3已經歸位。接下來需要處理3左邊的序列「2 1」和右邊的序列「5 4」。對序列「2 1」以2為基準數進行調整,處理完畢之後的序列為「1 2」,到此2已經歸位。序列「1」只有乙個數,也不需要進行任何處理。至此我們對序列「2 1」已全部處理完畢,得到序列是「1 2」。序列「5 4」的處理也仿照此方法,最後得到的序列如下:1 2 3 4 5 6 9 7 10 8。
對於序列「9 7 10 8」也模擬剛才的過程,直到不可拆分出新的子串行為止。最終將會得到這樣的序列:1 2 3 4 5 6 7 8 9 10。
到此,排序完全結束。細心的同學可能已經發現,快速排序的每一輪處理其實就是將這一輪的基準數歸位,直到所有的數都歸位為止,排序就結束了。廢話不多說,上個圖來瞅瞅。
快速排序由 c. a. r. hoare(東尼霍爾,charles antony richard hoare)在2023年提出,之後又有許多人做了進一步的優化。東尼霍爾就是下圖這個人。
快速排序是基於一種叫做「二分」的思想。相比氣泡排序,快速排序之所比較快,是因為它每次交換是跳躍式的。每次排序的時候設定乙個基準點,將小於等於基準點的數全部放到基準點的左邊,將大於等於基準點的數全部放到基準點的右邊。這樣在每次交換的時候就不會像氣泡排序一樣每次只能在相鄰的數之間進行交換,交換的距離就大的多了。因此總的比較和交換次數就少了,速度自然就提高了。
#include
int a[101],n;//定義全域性變數,這兩個變數需要在子函式中使用
void quicksort(int left,int right)
int main()
排序演算法 快速排序演算法
網際網路的大型公司還在火熱招聘中,參與了一次又一次的筆試,都不通過,我還是太菜!作為程式設計人員,需要邁過去 資料結構與演算法 這個坎,畢竟,筆試不會真的很虧,加油吧,少些水,多點實操。一 快速排序演算法思想 從一組資料中找出乙個基準值,一般是選擇中間值作為基準值,然後從左到右將值與基準值進行比較,...
演算法 排序演算法 快速排序
快速排序是對冒泡法排序的一種改進。快速排序演算法 的基本思想是 將所要進行排序的數分為左右兩個部分,其中一部分的所有資料都比另外一 部分的資料小,然後將所分得的兩部分資料進行同樣的劃分,重複執行以上的劃分操作,直 到所有要進行排序的資料變為有序為止。可能僅根據基本思想對快速排序的認識並不深,接下來以...
演算法設計 快速排序 隨機快速排序演算法
1.演算法流程 快速排序的時間複雜性分析 1.最壞情況劃分 當劃分產生的兩個子問題分別包含了n 1個元素和0個元素時,快速排序是最壞情況,假如每次遞迴呼叫,總是出現最不平衡劃分,這是最不平衡劃分。劃分操作時間複雜度為 n 則演算法執行時間的遞迴表示式為t n t n 1 t 0 n 利用代入法可以求...