快速排序的时间复杂度分析
快速排序的時間復雜度分析
先說結論:
最壞情況:O(N2)O(N^{2})O(N2)
最好情況和平均情況:O(NlogN)O(NlogN)O(NlogN)
下面開始分析。
假設一個序列共有 N 個元素,基本的快速排序的關系式是:
T(N)=T(i)+T(N?i?1)+cNT(N) = T(i) + T(N -i -1) + cN T(N)=T(i)+T(N?i?1)+cN
其中 i 表示一次劃分后,樞紐所在的位置。對一個有 N 個元素的序列排序,其時間可以劃分為 3 部分:
1)把樞紐放到合適的位置,即其左邊的數都小于等于它,右邊的數都大于等于它
2)對左邊的部分(共有 iii 個元素)應用快速排序
3)對右邊的部分(共有 N?i?1N-i-1N?i?1 個元素)應用快速排序
要想把樞紐元放到合適的位置,需要從兩端向中間遍歷數組,花費的時間和數組規模成正比例,設為 cNcNcN
于是就有了最上面的公式。
當子序列沒有元素或者僅有 1 個元素,處理時間為常數。所以可以認為 :
T(0)=T(1)=1T(0) = T(1)=1T(0)=T(1)=1
最壞情況
樞紐始終是最小元素。此時 i=0i = 0i=0,那么遞推關系是:
T(N)=T(0)+T(N?1)+cN,T(N) = T(0) + T(N -1) + cN , T(N)=T(0)+T(N?1)+cN, (N>1)(N>1)(N>1)
忽略掉 T(0)=1T(0)=1T(0)=1 這樣的常數項,上面的式子就是:
T(N)=T(N?1)+cNT(N) = T(N -1) + cN T(N)=T(N?1)+cN (1)
反復使用上面的式子,得到
T(N?1)=T(N?2)+c(N?1)T(N-1) = T(N -2) + c(N-1) T(N?1)=T(N?2)+c(N?1) (2)
T(N?2)=T(N?3)+c(N?2)T(N-2) = T(N -3) + c(N-2) T(N?2)=T(N?3)+c(N?2) (3)
…
最后把 N=2N=2N=2 帶入:
T(2)=T(1)+c(2)T(2) = T(1) + c(2) T(2)=T(1)+c(2) (4)
把從 (1) 到 (4)還有省略號,這些式子加起來,消除共同的項,得到:
T(N)=T(1)+c∑i=2Ni=O(N2)T(N) = T(1) + c\sum_{i=2}^{N} i=O(N^{2})T(N)=T(1)+ci=2∑N?i=O(N2)
最好情況
最幸運的是,樞紐恰好位于序列的中間。
為了方便分析,假設數組有奇數個元素,N=2n+1,(n>=1)N = 2n+1,(n>=1)N=2n+1,(n>=1)
所以有
T(N)=T(n)+T(n)+cN,T(N) = T(n) + T(n) + cN , T(N)=T(n)+T(n)+cN, (N>1)(N>1)(N>1)
因為 n=N?12n = \frac{N-1}{2}n=2N?1?,忽略到無關緊要的常數,再簡化一下,n=N2n = \frac{N}{2}n=2N?,代入上式
T(N)=T(N/2)+T(N/2)+cN,T(N) = T(N/2) + T(N/2) + cN , T(N)=T(N/2)+T(N/2)+cN, (N>1)(N>1)(N>1)
也就是
T(N)=2T(N/2)+cN,T(N) = 2T(N/2) + cN , T(N)=2T(N/2)+cN, (N>1)(N>1)(N>1)
兩邊同時除以 NNN
T(N)N=T(N/2)N/2+c\frac{T(N)}{N} =\frac{T(N/2)}{N/2} + cNT(N)?=N/2T(N/2)?+c (1)
反復套用這個式子
T(N/2)N/2=T(N/4)N/4+c\frac{T(N/2)}{N/2} =\frac{T(N/4)}{N/4} + cN/2T(N/2)?=N/4T(N/4)?+c (2)
T(N/4)N/4=T(N/8)N/8+c\frac{T(N/4)}{N/4} =\frac{T(N/8)}{N/8} + cN/4T(N/4)?=N/8T(N/8)?+c (3)
…
最后把 N=2N=2N=2 帶入
T(2)2=T(1)1+c\frac{T(2)}{2} =\frac{T(1)}{1} + c2T(2)?=1T(1)?+c (4)
把從 (1) 到 (4)還有省略號,這些式子加起來,消除共同的項,得到:
T(N)N=T(1)1+cx\frac{T(N)}{N} =\frac{T(1)}{1} + cxNT(N)?=1T(1)?+cx (5)
xxx 表示這些式子有多少個,我們算一下
其個數就是等比數列 2,4,8,16,32,…,N 的個數
根據等比數列的通項公式 an=a1qn?1a_{n} = a_{1}q^{n-1} an?=a1?qn?1
帶入 a1=2,an=N,q=2a_{1} =2 , a_{n} = N, q=2a1?=2,an?=N,q=2 得到
N=2nN =2^{n} N=2n
所以 n=log?2Nn = \log_{2}Nn=log2?N
所以式子(5)是
T(N)N=T(1)1+clog?2N\frac{T(N)}{N} =\frac{T(1)}{1} + c\log_{2}NNT(N)?=1T(1)?+clog2?N (6)
由此得到
T(N)=N+cNlog?2NT(N) = N + cN\log_{2}NT(N)=N+cNlog2?N
忽略系數 ccc 和低階項 NNN,得到
T(N)=O(NlogN)T(N) = O(NlogN)T(N)=O(NlogN)
平均情況
這是最難的部分。
T(N)=T(i)+T(N?i?1)+cNT(N) = T(i) + T(N -i -1) + cN T(N)=T(i)+T(N?i?1)+cN (1)
依然從上面的遞推關系式入手。
對于平均情況,很難說每一次劃分樞紐元會出現在哪里,也許出現在第 000 個位置,也許出現在第 (N?1)(N-1)(N?1)個位置,但是平均來說,每個位置出現的概率相等,都是 N/1N/1N/1
所以上式的 T(i)T(i)T(i) 要換成 (1/N)∑i=0N?1T(i)(1/N)\sum_{i=0}^{N-1}T(i)(1/N)∑i=0N?1?T(i)
同理,T(N?i?1)T(N -i -1)T(N?i?1) 也可以換成 (1/N)∑i=0N?1T(i)(1/N)\sum_{i=0}^{N-1}T(i)(1/N)∑i=0N?1?T(i)
于是(1)變為
T(N)=(2/N)[∑i=0N?1T(i)]+cN,N>=2T(N) = (2/N)[\sum_{i=0}^{N-1}T(i)]+ cN , N>=2T(N)=(2/N)[i=0∑N?1?T(i)]+cN,N>=2 (2)
兩邊同時乘以 N
NT(N)=2[∑i=0N?1T(i)]+cN2NT(N) = 2[\sum_{i=0}^{N-1}T(i)]+ cN^2 NT(N)=2[i=0∑N?1?T(i)]+cN2 (3)
用 N?1N-1N?1 來替換 NNN
(N?1)T(N?1)=2[∑i=0N?2T(i)]+c(N?1)2(N-1)T(N-1) = 2[\sum_{i=0}^{N-2}T(i)]+ c(N-1)^2 (N?1)T(N?1)=2[i=0∑N?2?T(i)]+c(N?1)2 (4)
(3) 減去(4) 得到
NT(N)?(N?1)T(N?1)=2T(N?1)+2cN?cNT(N) -(N-1)T(N-1) = 2T(N-1)+2cN-cNT(N)?(N?1)T(N?1)=2T(N?1)+2cN?c (5)
移項
NT(N)=(2+N?1)T(N?1)+2cN?cNT(N) = (2+N-1)T(N-1)+2cN-cNT(N)=(2+N?1)T(N?1)+2cN?c (6)
化簡,并忽略常數 c
NT(N)=(N+1)T(N?1)+2cNNT(N) = (N+1)T(N-1)+2cNNT(N)=(N+1)T(N?1)+2cN (7)
兩邊同時除以 N(N+1)N(N+1)N(N+1)
T(N)N+1=T(N?1)N+2cN+1\frac{T(N)}{N+1} =\frac{T(N-1)}{N} + \frac{2c}{N+1}N+1T(N)?=NT(N?1)?+N+12c? (8) 現在可以進行疊縮,不斷套用式子(8)
T(N?1)N=T(N?2)N?1+2cN\frac{T(N-1)}{N} =\frac{T(N-2)}{N-1} + \frac{2c}{N}NT(N?1)?=N?1T(N?2)?+N2c? (9)
T(N?2)N?1=T(N?3)N?2+2cN?1\frac{T(N-2)}{N-1} =\frac{T(N-3)}{N-2} + \frac{2c}{N-1}N?1T(N?2)?=N?2T(N?3)?+N?12c? (10)
…
把 N=2N=2N=2 帶入 (8)
T(2)3=T(1)2+2c3\frac{T(2)}{3} =\frac{T(1)}{2} + \frac{2c}{3}3T(2)?=2T(1)?+32c? (11)
把 (8,9,10,11) 和省略號的式子加起來
T(N)N+1=T(1)2+2c∑i=3N+1(1/i)\frac{T(N)}{N+1} =\frac{T(1)}{2} + 2c\sum_{i=3}^{N+1}(1/i)N+1T(N)?=2T(1)?+2ci=3∑N+1?(1/i) (12)
忽略常數 T(1)2\frac{T(1)}{2}2T(1)? 和系數 2c,我們研究一下 ∑i=3N+1(1/i)\sum_{i=3}^{N+1}(1/i)∑i=3N+1?(1/i)
這個式子就是
13+14+15+...+1N+1\frac{1}{3} + \frac{1}{4} + \frac{1}{5}+...+\frac{1}{N+1}31?+41?+51?+...+N+11? (13)
當 n 很大時
1+12+13+...+1n=ln(n)+γ1 + \frac{1}{2} + \frac{1}{3} + ...+\frac{1}{n} = ln(n)+ \gamma1+21?+31?+...+n1?=ln(n)+γ (14)
其中的 γ\gammaγ 是歐拉常數,近似值是 0.57721566490153286060651209,目前還不知道它是有理數還是無理數。
對比(14)和(13),當(13)中的 NNN 很大時,它的和近似等于
ln(N+1)+γ?3/2ln(N+1)+ \gamma - 3/2ln(N+1)+γ?3/2
結合式子 (12)得出:
T(N)N+1=O(logN)\frac{T(N)}{N+1} = O(logN)N+1T(N)?=O(logN) (12)
從而,
T(N)=O(NlogN)T(N) = O(NlogN)T(N)=O(NlogN)
參考資料:
《數據結構與算法分析——C語言描述》(機械工業出版社)
總結
以上是生活随笔為你收集整理的快速排序的时间复杂度分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件测试nodejs面试题,nodejs
- 下一篇: 强符号与弱符号