关于递归程序的时间复杂度
主定理
递归中,一个规模为n的问题分成a个规模为n/b的问题,额外计算复杂度为c*n^d,那么
T(n)=O(ndlogn)(a=bd) T ( n ) = O ( n d log n ) ( a = b d )
T(n)=O(nd)(a<bd) T ( n ) = O ( n d ) ( a < b d )
T(n)=O(nlogba)(a>bd) T ( n ) = O ( n log b a ) ( a > b d )
证明
我们画出递归树,则递归树共有logb(n)+1层。对于第j层,有a^j个子问题,每个子问题规模为n/b^j。
则第j层所用时间为
ajc(nbj)d=cnd(abd)j a j c ( n b j ) d = c n d ( a b d ) j
接下来求所有层的和
TotalWork=cnd∑j=0logbn(a/bd)j T o t a l W o r k = c n d ∑ j = 0 log b n ( a / b d ) j
根据a与b^d的大小讨论,易得主定理中结论
tip
若不为平均分,则设最大的一部分为p*n(0 < p < 1),则树的深度为
log1/p(n)+1 log 1 / p ( n ) + 1
又由于
log1/p(n)=log(n)log(1/p) l o g 1 / p ( n ) = l o g ( n ) l o g ( 1 / p )
所以深度依旧是log(n)级别
快排复杂度分析
由于快排分割随机,所以我们考虑平均复杂度
T(n)=T(i)+T(n−i)+cn T ( n ) = T ( i ) + T ( n − i ) + c n
E(T(i))=1n∑j=0n−1T(j) E ( T ( i ) ) = 1 n ∑ j = 0 n − 1 T ( j )
所以有
E(T(n−i))=E(T(i)) E ( T ( n − i ) ) = E ( T ( i ) )
T(n)=2n∑j=0n−1T(j)+cn T ( n ) = 2 n ∑ j = 0 n − 1 T ( j ) + c n
两边同乘以n
nT(n)=2∑j=0n−1T(j)+cn2([1]) n T ( n ) = 2 ∑ j = 0 n − 1 T ( j ) + c n 2 ( [ 1 ] )
又有
(n−1)T(n−1)=2∑j=0n−2T(j)+c(n−1)2([2]) ( n − 1 ) T ( n − 1 ) = 2 ∑ j = 0 n − 2 T ( j ) + c ( n − 1 ) 2 ( [ 2 ] )
[1] - [2] 得
nT(n)=(n+1)T(n−1)+2cn+c n T ( n ) = ( n + 1 ) T ( n − 1 ) + 2 c n + c
两边同除n*(n+1)得
T(n)n+1=T(n−1)n+2cn+1+cn(n+1) T ( n ) n + 1 = T ( n − 1 ) n + 2 c n + 1 + c n ( n + 1 )
累加求和,得
T(n)n+1=T(1)2+2cln(n)+2cγ T ( n ) n + 1 = T ( 1 ) 2 + 2 c l n ( n ) + 2 c γ
//γ为欧拉常数
所以
T(n)≈2cnlnn T ( n ) ≈ 2 c n l n n