1. 程式人生 > >【4】快排及隨機化演算法

【4】快排及隨機化演算法

快排(Quicksort)

  • 分治演算法
  • 原地排序(就在原來的資料區域內進行重排,像插入排序,在原來的區域完成排序,歸併排序額外的空間進行排序)

分治

  • 分,快速排序將資料劃分為幾份,所以快排通過選取一個關鍵資料,再根據它的大小把原資料分為兩個子陣列(第一個陣列的元素都比這個主元素小,第一個陣列的元素都比這個主元素大或相等)
  • 治,用遞迴處理兩個子陣列的排序
  • 合併,連線

在這裡插入圖片描述

(A,p,q)(A,p,q)

定義(A,p,q)(A,p,q)演算法,表示從元素p到元素q的快速排序,輸出結果為將小於主元素(位置p的元素)排在主元素之前,將大於等於主元素(位置p的元素)排在主元素之後。 在這裡插入圖片描述

(A,p,q)(A,p,q)例子

在這裡插入圖片描述

Pseudocode for quicksort

在這裡插入圖片描述

快排分析

  • 假設元素都不相同
  • 當有重複元素的時候也可以執行,但有更好的演算法
  • 最壞情況分析
    • 每次主元素都是大於或者小於其他元素,T(n)=T(0)+T(n1)+Θ(n)=Θ(1)+T(n1)+Θ(n)=T(n1)+Θ(n)=Θ(n2)T(n)=T(0)+T(n-1)+\Theta(n)=\Theta(1)+T(n-1)+\Theta(n)=T(n-1)+\Theta(n)=\Theta(n^2) ,儘管最差情況下的快速排序演算法和插入排序的演算法複雜度是一樣的,但是快排仍然是一個好演算法,因為快排的平均演算法複雜度小

最壞情況下的快排

在這裡插入圖片描述

最好情況下的快排

在這裡插入圖片描述

正常情況下的快排(以1:9為例)

T(n)T(n)的上下屆都趨近於Θ(nlgn)\Theta(nlgn) cnlog10n+Θ(n)T(n)cnlog10/9n+Θ(n)cnlog_{10}n+\Theta(n) \le T(n) \le cnlog_{10/9}n+\Theta(n) 在這裡插入圖片描述

正常情況下的快排(好壞情況交替發生)

現在我們考慮好壞情況交替發生的情況,

  • 好的情況:L(n)=2U(n/2)+Θ(n)L(n)=2U(n/2)+\Theta(n)
  • 壞的情況:U(n)=L(n1)+Θ(n)U(n)=L(n-1)+\Theta(n)U(n)U(n)L(n)L(n)替換,得L(n)=2(L(n/21)+Θ(n/2))+Θ(n)=2L(n/21)+Θ(n)=Θ(n)L(n)=2(L(n/2-1)+\Theta(n/2))+\Theta(n)=2L(n/2-1)+\Theta(n)=\Theta(n)

在這裡插入圖片描述

綜上,隨機選擇主元——隨機化快速排序。

隨機化快速排序(Randomized quicksort)

簡介

其執行時間不依賴於輸入序列的順序(與打亂輸入同理)。演算法的效率與輸入順序無關。原始的快速排序在輸入順序和逆序序列時很慢,在隨機的序列表現很好。隨機化快速排序隨機選取主元素也能達到這種效果且無需對分佈做任何假設(沒有一種分佈會引起最差的結果) 在這裡插入圖片描述

分析(數學高能預警)

T(n)T(n)為執行時間的隨機變數,假設隨機數(主元素)是獨立的。 為了進行分析,k表示選取的主元素(0,1,n10,1,\dots n-1)。在我們選擇一個特定分劃的情況下當產生k:(nk1)k:(n-k-1)分劃時,隨機變數Xk=1X_k=1Xk=1X_k=1表示劃分的結果是左邊k個元素,右邊(n-k-1)個元素)。 在這裡插入圖片描述 在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述 在這裡插入圖片描述

實戰中

  • 隨機化快排的期望E(T(n))=Θ(nlgn)E(T(n))=\Theta(nlgn)
  • 隨機化快排通常比歸併排序快兩三倍(程式設計優化)
  • 在虛擬記憶體的快取中效能比較好