使用递归式求解算法时间复杂度

部分整理自:《算法导论》–机械工业出版社;MIT的《算法导论》公开课。

0 渐进记号(满足某种条件的函数的集合)

直接上图(自 机械工业出版社《算法导论》第三版):
常用的渐进符号直观图

(a). Θ Θ 渐进紧确界(asymptotically tight bound)

存在正常量 n0,c1,c2 n 0 , c 1 , c 2 使得:

c1g(n)f(n)c2g(n)wherenn0 c 1 g ( n ) ≤ f ( n ) ≤ c 2 g ( n ) w h e r e n ≥ n 0
那么称为 g(n) g ( n ) f(n) f ( n ) 的渐进紧确界,记为:
f(n)=Θ(g(n)) f ( n ) = Θ ( g ( n ) )

例如: f(n)=n2+3n,g(n)=n2 f ( n ) = n 2 + 3 n , g ( n ) = n 2 , 则 f(n)=Θ(g(n))=Θ(n2) f ( n ) = Θ ( g ( n ) ) = Θ ( n 2 )
c1n2n2+3nc2n2=>c11+3nc2 c 1 n 2 ≤ n 2 + 3 n ≤ c 2 n 2 => c 1 ≤ 1 + 3 n ≤ c 2

可知 c1=1,c2=2,n0=3 c 1 = 1 , c 2 = 2 , n 0 = 3 满足上面的不等式。
将上面的 g(n) g ( n ) 改成 g(n)=n3 g ( n ) = n 3 ,那么:
c1n3n2+3nc2n3=>c1n3n2+3n=>c1n2n3 c 1 n 3 ≤ n 2 + 3 n ≤ c 2 n 3 => c 1 n 3 ≤ n 2 + 3 n => c 1 n 2 − n ≤ 3
由于 c1 c 1 为正,那么当 n12c1 n ≥ 1 2 c 1 , c1n2n c 1 n 2 − n 为增函数,特别地,当 n>12c1+1+12c1,c1n2n>3 n > 12 c 1 + 1 + 1 2 c 1 , c 1 n 2 − n > 3 所以 f(n)Θ(n) f ( n ) ≠ Θ ( n )

(b) . O O 渐进上界(asymptotically upper bound)

存在正常量 c,n0 c , n 0 , 使得:

0f(n)cg(n)wherenn0 0 ≤ f ( n ) ≤ c g ( n ) w h e r e n ≥ n 0
那么称为 g(n) g ( n ) f(n) f ( n ) 的渐进上界,记为:
f(n)=O(g(n)) f ( n ) = O ( g ( n ) )

(c) . Ω Ω 渐进下界(asymptotically lower bound)

存在正常量 c,n0 c , n 0 , 使得:

0g(n)cf(n)wherenn0 0 ≤ g ( n ) ≤ c f ( n ) w h e r e n ≥ n 0
那么称为 g(n) g ( n ) f(n) f ( n ) 的渐进下界,记为:
f(n)=Ω(g(n)) f ( n ) = Ω ( g ( n ) )

注意:有些资料上将 O O 记为渐进紧确界,而在《算法导论》中 O O 仅仅为渐进上界而非紧确上界,如:

n=O(n2) n = O ( n 2 )


1 为什么使用递归式

通常情况下,分析一段代码的时间复杂度,特别是递归调用,可以通过代码很方便地写出递归式。

partition(A,p,r)
x = A[r]                     // 1
i = p-1                      // 1
for j = p to r-1             // 3*(r-p)
    if A[j]<=x               
        i = i +1             
        exchange A[i] with A[j] 
exchange A[i+1] with A[r]     // 1
return i+1                    //1    

quick_sort(A,p,r)
if p < r
    q = partition(A,p,r) //划分到子规模,规模为 r-p,代价 f(r-p)
    quick_sort(A,p,q-1)  //递归调用,子规模为 q-1-p, 代价 T(q-1-p)
    quick_sort(A,q+1,r)  //递归调用,子规模为 r-q-1, 代价 T(r-q-1)

以上为快排序代码,其中 rp r − p 为排序的规模,那么快排序的时间递归式就可以写成:

T(rp)=T(q1p)+T(rq1)+f(rp)where f is the cost of partition T ( r − p ) = T ( q − 1 − p ) + T ( r − q − 1 ) + f ( r − p ) where  f  is the cost of  p a r t i t i o n

假设每次划分都能划分成相同规模的两个子规模,即 q1p=rq1=(rp)/2 q − 1 − p = r − q − 1 = ( r − p ) / 2 ,令 rp=n r − p = n ,那么递归式可以写成这样:
T(n)=2T(n/2)+f(n) T ( n ) = 2 T ( n / 2 ) + f ( n )

partition p a r t i t i o n 代码可以得出 f(n)=3n+4=Θ(n) f ( n ) = 3 n + 4 = Θ ( n )
所以,快排序的时间递归式最终为:
T(n)=2T(n/2)+Θ(n) T ( n ) = 2 T ( n / 2 ) + Θ ( n )


2 算法时间递归式

一般情况下,算法的时间递归式都可以写成如下形式:

T(n)=aT(n/b)+f(n) T ( n ) = a T ( n / b ) + f ( n )

表示为:规模为 n n ,算法所耗费的时间等于划分时间 f(n) f ( n ) 加上同样算法作用在规模为 n/b n / b 的时间 T(n/b) T ( n / b ) a a 倍。
将递归式一直写下去:
T(n)=aT(n/b)+f(n)=a2T(n/b2)+af(n/b)+f(n) T ( n ) = a T ( n / b ) + f ( n ) = a 2 T ( n / b 2 ) + a f ( n / b ) + f ( n )

T(n)=a3T(n/b3)+a2f(n/b2)+af(n/b)+f(n) T ( n ) = a 3 T ( n / b 3 ) + a 2 f ( n / b 2 ) + a f ( n / b ) + f ( n )

T(n)=a4T(n/b4)+a3f(n/b3)+a2f(n/b2)+af(n/b)+f(n) T ( n ) = a 4 T ( n / b 4 ) + a 3 f ( n / b 3 ) + a 2 f ( n / b 2 ) + a f ( n / b ) + f ( n )

T(n)=amT(n/bm)+am1f(n/bm1)+...+a3f(n/b3)+a2f(n/b2)+af(n/b)+f(n) T ( n ) = a m T ( n / b m ) + a m − 1 f ( n / b m − 1 ) + . . . + a 3 f ( n / b 3 ) + a 2 f ( n / b 2 ) + a f ( n / b ) + f ( n )

bm=n b m = n m=lognb m = l o g b n ,子规模下降到 1 1 , 递归式变成:
T(n)=alognbT(1)+j=0lognb1ajf(n/bj) T ( n ) = a l o g b n T ( 1 ) + ∑ j = 0 l o g b n − 1 a j f ( n / b j )

alognb=nlogabT(1)=Θ(1) a l o g b n = n l o g b a , T ( 1 ) = Θ ( 1 ) , 递归式变成:
T(n)=Θ(nlogab)+Θ{(j=0lognb1ajf(n/bj)}.....(1) T ( n ) = Θ ( n l o g b a ) + Θ { ( ∑ j = 0 l o g b n − 1 a j f ( n / b j ) } . . . . . ( 1 )

证明: alognb=nlogab a l o g b n = n l o g b a :

if:a=b>0=>loga=logb i f : a = b > 0 => l o g a = l o g b

lognlogabb=logablognb l o g b n l o g b a = l o g b a l o g b n

logalognbb=lognblogab l o g b a l o g b n = l o g b n l o g b a


3 使用递归式计算快排序的时间复杂度

从写递归式:

T(n)=2T(n/2)+Θ(n) T ( n ) = 2 T ( n / 2 ) + Θ ( n )

代入式(1)得到:
=>T(n)=Θ(n)+Θ(j=0logn21n)=Θ(n)+Θ(nlogn2)=Θ(nlogn2)=Ω(nlgn) => T ( n ) = Θ ( n ) + Θ ( ∑ j = 0 l o g 2 n − 1 n ) = Θ ( n ) + Θ ( n l o g 2 n ) = Θ ( n l o g 2 n ) = Ω ( n l g n )


4 常见函数的规模增长速度

1<n<lgn<nlgn<n2<n3 1 < n < l g n < n l g n < n 2 < n 3

你可能感兴趣的:(算法与数据结构)