快速排序(quicksort)是對氣泡排序的一種改進。由c. a. r. hoare在2023年提出。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。
設要排序的陣列是a[0]……a[n-1],首先任意選取乙個資料(通常選用第乙個資料)作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。
一趟快速排序的演算法是:
1)設定兩個變數i、j,排序開始的時候:i=0,j=n-1;
2)以第乙個陣列元素作為關鍵資料,賦值給key,即 key=a[0];
3)從j開始向前搜尋,即由後開始向前搜尋(j -- ),找到第乙個小於key的值a[j],a[i]與a[j]交換;
4)從i開始向後搜尋,即由前開始向後搜尋(i ++ ),找到第乙個大於key的a[i],a[i]與a[j]交換;
5)重複第3、4、5步,直到 i=j; (3,4步是在程式中沒找到時候j=j-1,i=i+1,直至找到為止。找到並交換的時候i, j指標位置不變。另外當i=j這過程一定正好是i+或j-完成的最後令迴圈結束。)
示例待排序的陣列a的值分別是:(初始關鍵資料:key=49) 注意關鍵key永遠不變,永遠是和key進行比較,無論在什麼位置,最後的目的就是把key放在中間,小的放前面大的放後面。
a[0] a[1] a[2] a[3] a[4] a[5] a[6]
49 38 65 97 76 13 27
進行第一次交換後:27 38 65 97 76 13 49
( 按照演算法的第三步從後面開始找,此時:j=6)
進行第二次交換後:27 38 49 97 76 13 65
( 按照演算法的第四步從前面開始找》key的值,65>49,兩者交換,此時:i=2 )
進行第三次交換後:27 38 13 97 76 49 65
( 按照演算法的第五步將又一次執行演算法的第三步從後開始找
進行第四次交換後:27 38 13 49 76 97 65
( 按照演算法的第四步從前面開始找大於key的值,97>49,兩者交換,此時:i=3,j=5 )
此時再執行第三步的時候就發現i=j=3,從而結束一趟快速排序,那麼經過一趟快速排序之後的結果是:27 38 13 49 76 97 65,即所有大於key49的數全部在49的後面,所有小於key(49)的數全部在key(49)的前面。
源**如下:
private function quicksort(temparr:array, left:int, right:uint):void
temparr[low] = temparr[high];
while(low < high && temparr[low] < key)
temparr[high] = temparr[low];
}temparr[low] = key;
quicksort(temparr, left, low -1);
quicksort(temparr, low + 1, right);}}
變種演算法
快速排序(quicksort)有幾個值得一提的變種演算法,這裡進行一些簡要介紹:
1、隨機化快排:快速排序的最壞情況基於每次劃分對主元的選擇。基本的快速排序選取第乙個元素作為主元。這樣在陣列已經有序的情況下,每次劃分將得到最壞的結果。一種比較常見的優化方法是隨機化演算法,即隨機選取乙個元素作為主元。這種情況下雖然最壞情況仍然是o(n^2),但最壞情況不再依賴於輸入資料,而是由於隨機函式取值不佳。實際上,隨機化快速排序得到理論最壞情況的可能性僅為1/(2^n)。所以隨機化快速排序可以對於絕大多數輸入資料達到o(nlogn)的期望時間複雜度。一位前輩做出了乙個精闢的總結:「隨機化快速排序可以滿足乙個人一輩子的人品需求。」
隨機化快速排序的唯一缺點在於,一旦輸入資料中有很多的相同資料,隨機化的效果將直接減弱。對於極限情況,即對於n個相同的數排序,隨機化快速排序的時間複雜度將毫無疑問的降低到o(n^2)。解決方法是用一種方法進行掃瞄,使沒有交換的情況下主元保留在原位置。
2、平衡快排(balanced quicksort):每次盡可能地選擇乙個能夠代表中值的元素作為關鍵資料,然後遵循普通快排的原則進行比較、替換和遞迴。通常來說,選擇這個資料的方法是取開頭、結尾、中間3個資料,通過比較選出其中的中值。取這3個值的好處是在實際問題(例如資訊學競賽……)中,出現近似順序資料或逆序資料的概率較大,此時中間資料必然成為中值,而也是事實上的近似中值。萬一遇到正好中間大兩邊小(或反之)的資料,取的值都接近最值,那麼由於至少能將兩部分分開,實際效率也會有2倍左右的增加,而且利於將資料略微打亂,破壞退化的結構。
3、外部快排(external quicksort):與普通快排不同的是,關鍵資料是一段buffer,首先將之前和之後的m/2個元素讀入buffer並對該buffer中的這些元素進行排序,然後從被排序陣列的開頭(或者結尾)讀入下乙個元素,假如這個元素小於buffer中最小的元素,把它寫到最開頭的空位上;假如這個元素大於buffer中最大的元素,則寫到最後的空位上;否則把buffer中最大或者最小的元素寫入陣列,並把這個元素放在buffer裡。保持最大值低於這些關鍵資料,最小值高於這些關鍵資料,從而避免對已經有序的中間的資料進行重排。完成後,陣列的中間空位必然空出,把這個buffer寫入陣列中間空位。然後遞迴地對外部更小的部分,迴圈地對其他部分進行排序。
4、三路基數快排(three-way radix quicksort,也稱作multikey quicksort、multi-key quicksort):結合了基數排序(radix sort,如一般的字串比較排序就是基數排序)和快排的特點,是字串排序中比較高效的演算法。該演算法被排序陣列的元素具有乙個特點,即multikey,如乙個字串,每個字母可以看作是乙個key。演算法每次在被排序陣列中任意選擇乙個元素作為關鍵資料,首先僅考慮這個元素的第乙個key(字母),然後把其他元素通過key的比較分成小於、等於、大於關鍵資料的三個部分。然後遞迴地基於這乙個key位置對「小於」和「大於」部分進行排序,基於下乙個key對「等於」部分進行排序。
排序演算法 快速排序演算法
網際網路的大型公司還在火熱招聘中,參與了一次又一次的筆試,都不通過,我還是太菜!作為程式設計人員,需要邁過去 資料結構與演算法 這個坎,畢竟,筆試不會真的很虧,加油吧,少些水,多點實操。一 快速排序演算法思想 從一組資料中找出乙個基準值,一般是選擇中間值作為基準值,然後從左到右將值與基準值進行比較,...
演算法 排序演算法 快速排序
快速排序是對冒泡法排序的一種改進。快速排序演算法 的基本思想是 將所要進行排序的數分為左右兩個部分,其中一部分的所有資料都比另外一 部分的資料小,然後將所分得的兩部分資料進行同樣的劃分,重複執行以上的劃分操作,直 到所有要進行排序的資料變為有序為止。可能僅根據基本思想對快速排序的認識並不深,接下來以...
演算法設計 快速排序 隨機快速排序演算法
1.演算法流程 快速排序的時間複雜性分析 1.最壞情況劃分 當劃分產生的兩個子問題分別包含了n 1個元素和0個元素時,快速排序是最壞情況,假如每次遞迴呼叫,總是出現最不平衡劃分,這是最不平衡劃分。劃分操作時間複雜度為 n 則演算法執行時間的遞迴表示式為t n t n 1 t 0 n 利用代入法可以求...