关于递归程序的时间复杂度

关于递归程序的时间复杂度


主定理

递归中,一个规模为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=cndj=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(ni)+cn T ( n ) = T ( i ) + T ( n − i ) + c n

E(T(i))=1nj=0n1T(j) E ( T ( i ) ) = 1 n ∑ j = 0 n − 1 T ( j )

所以有
E(T(ni))=E(T(i)) E ( T ( n − i ) ) = E ( T ( i ) )

T(n)=2nj=0n1T(j)+cn T ( n ) = 2 n ∑ j = 0 n − 1 T ( j ) + c n

两边同乘以n
nT(n)=2j=0n1T(j)+cn2([1]) n T ( n ) = 2 ∑ j = 0 n − 1 T ( j ) + c n 2 ( [ 1 ] )

又有
(n1)T(n1)=2j=0n2T(j)+c(n1)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(n1)+2cn+c n T ( n ) = ( n + 1 ) T ( n − 1 ) + 2 c n + c

两边同除n*(n+1)得
T(n)n+1=T(n1)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

你可能感兴趣的:(时间复杂度)