《演算法導論》學習筆記之Chapter7快速排序

2021-08-13 02:00:57 字數 1983 閱讀 8376

第七章 快速排序

對於包含n個數的陣列來說,快速排序是一種最壞情況時間複雜度為θ(n.^2)的排序演算法。雖然最壞情況時間複雜度很很差,但快速排序通常是實際排序應用中最好的選擇,因為他的平均效能非常好:它的期望時間複雜度為θ(nlogn),而且θ(nlogn)中隱含的常數因子非常小。同時,快速排序還能夠進行原址排序,甚至在虛存環境中也能很好的工作。

其中基於隨機抽樣的快排演算法,期望時間複雜度較好,而且沒有什麼特殊的輸入會導致最壞情況發生。

與歸併排序一樣,快速排序也使用了分治思想。只是裡面最重要的乙個環節是:分解參照節點的選擇,也即「主元」的選擇。下面的快速排序演算法是按照最後乙個元素作為主元,對陣列進行分解。

public void quicksort(int a, int p, int r)	}	

public int partition(int a, int p, int r)

} swap(a, i + 1, r);

return i + 1;

}

快速排序的效能取決於劃分是否平衡。

最壞的情況是,劃分結果為n-1:0,此時時間複雜度為θ(n.^2)。

最好地情況是兩個子問題的規模都不大於n/2,此時時間複雜度為θ(nlogn)。

而快排的平均執行時間更接近於最好地情況。

7.3 快速排序的隨機化版本

與上面版本的區別在於:選擇主元方式不同,隨機版本是指:在陣列0 - n-1元素之間隨機選擇乙個元素作為主元,與最後乙個元素交換。其他部分相同。

**如下:

public int randompartition(int a, int p, int r)

快速排序的最壞情況基於每次劃分對主元的選擇。基本的快速排序選取第乙個或者最後乙個元素作為主元。這樣在陣列已經有序的情況下,每次劃分將得到最壞的結果。一種比較常見的優化方法是隨機化演算法,即隨機選取乙個元素作為主元。這種情況下雖然

最壞情況仍然是o(n^2)

,但最壞情況不再依賴於輸入資料,而是由於隨機函式取值不佳。實際上,

隨機化快速排序得到理論最壞情況的可能性僅為1/(2^n)。

所以隨機化快速排序可以對於絕大多數輸入資料達到

o(nlogn

)的期望時間複雜度。

其實,針對快速排序的劃分方法,還有乙個版本,**如下:

// 適用於線性時間選擇的partition方法

private static int partition(int a, int l, int r, int pivot)

a[l] = a[j];

a[j] = pivot;

return j;

}

上述劃分方法多了乙個引數pivot,這個引數

pivot就是你選擇的主元的數值大小。在你已經選擇好主元的前提下,使用此劃分方法。這個方法會在後續介紹線性選擇演算法時介紹,這個過程中你選擇的

pivot大小一般是中位數,該劃分方法產生的劃分結果應該是好的,是均衡的,對快排的速度有很好地保證θ(n)。

快速排序中的-尾遞迴

在最初的partition函式中,是遞迴呼叫本身兩次,但是第二次遞迴呼叫不是必須的,可以通過乙個迴圈控制結構來代替,這種技術叫做  尾遞迴。尾遞迴過程中是利用棧來儲存遞迴執行過程中的相關資訊,包括每次遞迴呼叫的相關引數等。最新呼叫的資訊存在棧的頂部,第一次呼叫的資訊存在棧的底部,操作過程也就是棧的壓入彈出操作了。如果棧是用指標來指示的,則每次過程呼叫只需要o(1)的棧空間,棧深度是在一次計算過程中呼叫到的棧空間的最大值。**實現如下:

public void tailrecursivequicksort(int a, int p, int r) 

}

此外,快排的主元選擇還有一種方案:三數取中,即隨機選取三個數,選取三數中的中位數作為主元。該方法改變的只是時間複雜度o(nlogn)中的常量因子c的大小,總體時間複雜度仍是o(nlogn)。

演算法導論學習筆記之演算法基礎篇

一 插入排序 插入排序屬於原址排序,演算法在陣列a中重排元素,演算法思想與玩撲克牌時依次將抓到的牌放到手中合適的位置一致,當輸入完成時,手中的牌即已完成排序。插入排序 a for j 2.a.length setp 1 a 下標從 1 開始計數 key a j i j 1 while i 0 a i...

《演算法導論》學習筆記

4.5.1 二分查詢 乙個經典的問題 如何在乙個嚴格遞增序列a中找出給定的數x 最直接的辦法是 線性掃瞄序列中的所有元素,如果當前元素恰好為x,則表明查詢成功 如果掃瞄完整個序列都沒有發現給定的數x,則表明查詢失敗,說明序列中不存在數x。這種順序查詢的時間複雜度為o n 更好的辦法便是使用二分查詢 ...

演算法導論之快速排序 學習筆記

或者你也可以打個比喻,想象一下,假設r為主元素,j元素為前方開路元素,和主元素進行比較,如果大於主元素則繼續開路 如果小於主元素則i元素加1之後和j元素交換之後,j元素繼續開路直到最後。書中給出了劃分的偽 1 partition a,p,r 2 x a r 將最後乙個元素作為主元素 3 i p 1 ...