基本思想:被排序陣列為a,用陣列首元素作為標準將a分成前後兩部分,比首元素小的元素構成陣列的前部分,比首元素大的部分構成陣列的後部分。這兩部分構成兩個新的子問題,演算法接著對這兩個陣列進行遞迴。
quicksort(a,p,r) //p,r分別為陣列a的首元素和尾元素的下標
輸入:陣列a[p..r],1<=p<=r<=n
輸出:從a[p]到a[r]按遞增順序排好序的陣列a
if pa[q]
quicksort(a,p,q-1)
quicksort(a,q+1,r)
partition是劃分的過程
x
i j
while true do
repeat j
until a[j] <= x
repeat i
until a[i] > x
if i < j
then a[i] a[j]
else return j
下面舉乙個例子
演算法的時間複雜度分析
每個元素都要和首元素進行一次比較(在i,j相遇位置附近的元素可能比較2次),所以劃分過程的工作量是o(n)。
兩個子問題遞迴呼叫的工作量
1.均等劃分子問題
先看均等劃分的例子,如果每次劃分得到的子問題大小都相等,即每個子問題的規模都等於n/2,那麼在當前例項下時間複雜度函式的遞推方程是:
\[\left\ t(n)=2t(n/2)+o(n) & \\ t(1)=0& \end \right. \]
根據主定理,該方程的解\(t(n)=o(nlogn)\),這是一種比較好的情況。
2.子問題規模不同,但遵從一定比例
即使子問題規模不一樣,但兩個子問題的規模遵從一定的比例,比如1:9,那麼時間複雜度函式的遞推方程為:
c是常數
這棵樹不均衡,從樹根到最左邊樹葉的路徑最短,在這條路徑上,每層的子節點的值是父節點值的1/10,設樹根是第0層,每層為第k層,
\(\frac\)
kn代表當前第k層的值,即子問題規模。
\(\frac\)
0n=n,代表第0層值為n,
當\(\frac\)
k*n=1,即子問題規模為1,到達樹葉時,k=\(\log\)
10(\(x\))。
同理得到最右邊路徑長度是log10/9n,為了表示時間漸進的上界,不妨取最長路徑作為樹的層次,即所有節點的數值之和為
t(n) = c\(n\log\)
10/9
\(n\) = o(\(n\log(n)\))
這說明,即使子問題規模不均衡,但是只要比例一定,快速排序演算法的時間複雜度仍舊是\(o(n\log(n))\)。
3.下面介紹極端不均衡的情況
即劃分後兩個子問題的規模乙個是0,另乙個是\(n-1\)的情況,當陣列元素是按從小到大正排序或從大到小逆排列時,就會呈現這種劃分。
\[\left\ w(n)=w(n-1)+o(n) & \\ w(1)=0& \end \right. \]
根據迭代歸納,此時\(w(n)=o(n^2)\)
但最壞情況出現的概率很低,它的平均效能還是不錯的。
4.平均情況
假設交換後,陣列a的首元素在排好序後處在\(n\)個位置中的任何位置都是等可能的,即它處在任何位置的概率都是\(1/n\)。如果它處在位置\(i\)(\(i\)=1,2,...,\(n\)),那麼劃分後的兩個子問題規模分別是\(i-1\)和\(n-1\)。考慮到\(t(0)=0\),因此可以得到
當把\(o(n)\)看作\(n-1\)時,這個方程的解是\(t(n)=o(nlogn)\)。
對於排序問題,平均情況下效率最高的演算法就是時間複雜度為\(o(nlogn)\)的演算法。在這個情況下,快速排序演算法是平均情況下效率最高的演算法之一。
分治策略 快速排序
快速排序演算法是基於分治策略的另乙個排序演算法。其基本思想是 對輸入的子陣列a p r 按以下三個步驟進行排序。1 分解 divide 以a p 為基準元素將a p r 劃分成3段a p q 1 a q 和a q 1 r 使得a p q 1 中任何乙個元素小於等於a q 而a q 1 r 中任何乙個...
Nearth 分治策略007 快速排序演算法
快速排序演算法是基於分治策略的另乙個排序演算法。其基本思想是,對於 輸入的子陣列a p r 按以下三個步驟進行排序 1,分解 以a p 為基準元素將a p r 劃分成3段,分別是a p q 1 a q a q 1 r 使a p q 1 中任何乙個元素小於等於a q 而a q 1 r 中任何乙個元素大...
分治演算法 快速排序
一.演算法思想 假設要對某陣列進行由小 大排序 1 分解 對於亂序陣列a r 訪問範圍 0 r 有r 1個數 取乙個基準元素a p 一般以第乙個數即a 0 為基準 確定某個partition 位置 q 使a q 右邊的數都大於等於a p a q 左邊的數都小於等於a p 2 遞迴分治 分解之後,陣列...