04-快速排序
數據結構和算法
基于《算法圖解》—Aditya Bhargava 和《數據結構》—嚴蔚敏
第4章 快速排序
4.1 分而治之
divide and conquer , 簡稱D&C:一種著名的遞歸式問題解決方法。
例子1:
假設你是農場主,有一小塊土地。要求將這塊地均勻地分成方塊,且分出的方塊要盡可能大。
使用D&C解決問題的過程包括兩個步驟:
(1)找出基線條件,這種條件必須盡可能簡單。
(2)不斷將問題分解(或者說縮小規模),直到復合基線條件。
在分土地問題中,我們設定基線條件為:一條邊的長度是另一條邊的整數倍。
根據D&C的定義,每次遞歸調用都必須縮小問題的規模。因此,我們首先找出這塊可容納的最大方塊。
可以將這塊地劃出連個640m×640m的方塊。
余下一塊640m×400m的土地
按照上述方法繼續劃分;
最終得出對于最初的那塊土地,適用的最大方塊為80m×80m。
也就是說,適用于小塊地的最大方塊,也是適用于整塊地的最大方塊。
例子2:
重申D&C工作原理:
(1)找出簡單的基線條件。
(2)確定如何縮小問題的規模,使其符合基線條件。
注意:D&C并非可用于解決問題的算法,而是一種解決問題的思路。
練習:
4.1 請編寫前述sum函數的代碼。
4.2 編寫一個遞歸函數來計算列表包含的元素數。
4.3 找出列表最大的數字。
4.4 找出二分查找算法的基線條件和遞歸條件。
4.2 快速排序
使用D&C的排序算法:需要將數組分解,直到滿足基線條件。
工作原理:從數組中選擇一個元素,作為基準值(pivot)。
基線條件:數組為空或只包含一個元素。(因為這種情況下,只需要返回數組——不需要排序)。
假設一個包含三個元素的數組:
首先確定元素15用作基準值。
對包含三個元素的數組進行排序的步驟:
那么,對于包含四個、五個…的數組呢?
同樣,選擇一個合適的基準,進行分區,每個區對其遞歸地調用快速排序。
4.3 再談大O表示法
快速排序的獨特之處在于,其速度取決于選擇的基準值。
幾種常見的大O運行時間:(橫坐標為次數,縱坐標為時間)
4.3.1 常量的影響
- 對于大O運行時間相同的兩種算法影響大,比如合并排序和快速排序,運行時間都為O(n log n),快速排序更快。
- 對于大O運行時間不同的兩種算法影響則忽略不計,這種常量將無關緊要。
4.3.2 平均情況和最糟情況
快速排序的性能高度依賴于你選擇的基準值。
假設總是以第一個元素用作基準值:
實際上數組并沒有被分成兩半,其中一個子數組始終為空,實在是一種浪費,導致調用棧達到最大長度,棧高也就是層數為O(n)。
假設總是將中間元素用作基準值:
調用棧直接減半,棧高也就是層數為O(n log n),因為每次都將數組分成兩半,不需要那么多遞歸調用,很快就達到了基線條件。
在調用棧的每一層都涉及O(n)個元素,因此,完成每層所需的時間都為O(n):
最佳情況:調用棧高度為O(log n),每層需要的時間為O(n);因此整個算法需要的時間為:O(n)*O(log n)=O(n log n)。
最糟情況:調用棧高度為O(n),每層所需時間為O(n);整個時間為:O(n2)。
最佳情況也是平均情況,快速排序時最快的排序算法之一,也是D&C典范。
練習:
4.5 打印數組中每個元素的值。
4.6 將數組中每個元素的值都乘以2。
4.7 只將數組中第一個元素的值乘以2。
4.8 根據數組包含的元素創建一個乘法表,即如果數組為[2,3,7,8,10],首先將每個元素都乘以2,再將每個元素都乘以3,然后每個元素都乘以7,以此類推。
4.4 小結
- D&C將問題逐步分解。編寫涉及數組的遞歸函數時,基線條件通常是數組為空或只包含一個元素。
- 實現快速排序時,請隨機地選擇用作基準值的元素。快速排序的平均運行時間為O(n log n)。
- 比較二分查找和簡單查找時,常量幾乎無關緊要,因為列表很長時,O(log n)的速度比O(n)快很多。
——持續修改完善中…
總結
- 上一篇: 03-递归
- 下一篇: Hadoop完全分子式环境搭建—问题及解