快速排序,終極研究

2021-09-30 09:01:04 字數 2343 閱讀 8004

快速排序由霍爾 (hoare) 提出,它是一種對氣泡排序的改正。由於其排序速度快,故稱快速排序 (quick sort) 。快速排序方法的實質是將一組關鍵字 [k 1 ,k 2 ,…,k n ] 進行分割槽交換排序。 

1.演算法思路

①以第乙個關鍵字 k 1 為控制字,將 [k 1 ,k 2 ,…,k n ] 分成兩個子區,使左區所有關鍵字小於等於 k 1 ,右區所有關鍵字大於等於 k 1 ,最後控制字居兩個子區中間的適當位置。在子區內資料尚處於無序狀態。 

②將右區首、尾指標 ( 記錄的下標號 ) 儲存入棧,對左區進行與第①步相類似的處理,又得到它的左子區和右子區,控制字居中。 

③重複第①、②步,直到左區處理完畢。然後退棧對乙個個右子區進行相類似的處理,直到棧空。 

由以上三步可以看出:快速排序演算法總框架是進行多趟的分割槽處理;而對某一特定子區,則應把它看成又是乙個待排序的檔案,控制字總是取子區中第乙個記錄的關鍵字。現在設計乙個函式 hoare ,它僅對某一待排序檔案進行左、右子區的劃分,使控制字居中;再設計乙個主體框架函式 quicksort ,在這裡多次呼叫 hoare 函式以實現對整個檔案的排序。 

2.快速排序演算法分析

快速排序的非遞迴演算法引用了輔助棧,它的深度為 log2n 。假設每一次分割槽處理所得的兩個子區長度相近,那麼可入棧的子區長度分別為:n/21n/22,n/23 ,n/24, … ,n/2k ,又因為 n/2k=1, 所以 k= log2n 。分母中 2 的指數恰好反映出需要入棧的子區個數,它就是 log2n ,也即棧的深度。在最壞情況下,比如原檔案關鍵字已經有序,每次分割槽處理僅能得到乙個子區。可入的子區個數接近 n, 此時棧的最大深度為 n. 

快速排序主體演算法時間運算量約 o(log2n) ,劃分子區函式運算量約 o(n) ,所以總的時間複雜度為 o(nlog2n) ,它顯然優於氣泡排序 o(n2). 可是演算法的優勢並不是絕對的。試分析,當原檔案關鍵字有序時,快速排序時間複雜度是 o(n2), 這種情況下快速排序不快。而這種情況的氣泡排序是 o(n), 反而很快。在原檔案記錄關鍵字無序時的多種排序方法中,快速排序被認為是最好的一種排序方法。

【例】: 試用 [6,7,5 1 ,2,5 2 ,8] 進行快速排序。

排序過程簡述如下:

6    7   51   2   52  8      初始狀態

[52   7   51]  6  [7   8] 

[2]  52  [51]  6   7  [8] 

[2   52   51   6   7   8]     最後狀態 

從這個例子可以分析出快速排序法的穩定性問題,其中51和52表示兩個關鍵字的值相同,都是5。51表示排序之前它位於 52的前面。從結果中可以看出原先位於51之後的52在排序之後移到了51的前面,所以說快速排序是不穩定的。

3.快速排序執行過程

快速排序執行的全過程可用遞迴樹來描述。

分析: 

(1)遞迴執行的路線如圖中帶箭頭的包絡線所示。

(2) 遞迴樹上每一結點左旁方括號表示當前待排序的區間,結點內的關鍵字是劃分的基準關鍵字

注意:葉結點對應的子區間只有乙個關鍵字,無須劃分,故葉結點內沒有基準關鍵字

(3) 劃分後得到的左、右兩個子區間分別標在該結點的左、右兩個孩子結點的左邊方括號內。

【例】根結點左旁方括號[49,38,65,97,76,13,27,49]表示初始待排序的關鍵字,根內的49表示所選的劃分基準記錄的關鍵字,劃分結果是[27,28,13]49[76,97,65,49_],其左右子區間分別標在根結點的兩個孩子的左邊。

(4) 每個分支結點右旁圓括號中的內容表示對該結點左旁區間的排序過程結束之後返回的結果。它是其左右孩子對應的區間排序完成之後,將左右孩子對應的排序結果分別放在該分支結點的關鍵字前後所得到的關鍵字序列。

【例】分支結點76的左右孩子對應的區間排序後的結果分別是(49_,65)和(97),將它們分別放在76的前後即得(49,65,76,97),這是對結點76左旁區間[76,97,,65,49]排序的結果。

(5) 演算法的執行順序是遞迴樹中的箭頭順序,實際上當把劃分操作視為訪問結點的操作時,快速排序的執行過程相當於是先序遍歷其遞迴樹。

注意:任何遞迴演算法均可用遞迴樹來描述其執行過程。

5、快速排序各次劃分後的狀態變化

[49 38 65 97 76 13 27 49

] //初始關鍵字

[27 38 13] 49 [76 97 65 49

] //第1次劃分完成之後,對應遞迴樹第2層

[13] 27 [38] 49 [

49 65] 76 [97] //對上一層各無序區劃分完成後,對應遞迴樹第3層

13 27 38 49 49

[65] 76 97 //對上一層各無序區劃分完成後,對應遞迴樹第4層

13 27 38 49 49 65 76 97 //最後的排序結果

快速排序及快速選擇終極版

快速排序 quick sort 是一種非常經典高效的排序演算法,採用了基於比較的遞迴分治策略,平均情況下複雜度為o nlogn 但最壞情況下會退化到o n 2 在筆試面試過程中經常會問到有關於快速排序的問題,甚至要求面試者當場手寫 本文將簡單介紹快排原理並提供具體的 實現,以及其在求第n小的數中的經...

鍊錶快速排序終極版

快速排序1 演算法只交換節點的val值,平均時間複雜度o nlogn 不考慮遞迴棧空間的話空間複雜度是o 1 這裡的partition我們參考陣列快排partition的第二種寫法 選取第乙個元素作為樞紐元的版本,因為鍊錶選擇最後一元素需要遍歷一遍 具體可以參考here 這裡我們還需要注意的一點是陣...

演算法研究之快速排序

快速排序 quicksort 是對氣泡排序的一種改進。由c.a.r.hoare在1962年提出。它的基本思想是 通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變...