主方法
主方法是一个算法复杂度分析的一个很好的方法,但是只能用于特定的递归上,适合的递归形式为:
T(n) = a*T(n/b)+f(n)
其中,a >=1 ; b >1 ; f(n) : 非递归函数,f(n)渐进趋正,渐进趋正的意思是当n足够大是,f(n)为正数,记:对于n>=n0时,f(n)>0,其中n0为足够大正数。
判断n^log b (a)与f(n)的大小关系
(1) 如果n^log b (a) = Θ(f(n)),那么该方法的复杂度为 Θ(f(n)*(log b (n)^(k+1))),其中k>=0
(2) 如果n^log b (a) > Θ(f(n)),那么该方法的复杂度为 Θ(n^(log b (a)))
(3) 如果n^log b (a) < Θ(f(n)),那么该方法复杂度为 Θ(f(n))
下面我们分析下,上面的三种情况是如何得到的
图1
每一个结点都有a个子递归,整棵树的高度很显然是log b (n), 递归终端的时间肯定是O(1),故最后一层的时间为 a^h=a^log b (n)=n^log b (a)
我们知道,算法的总时间是图1中所有层的总和,即f(n)+a*f(n/b)+...+a^h,对于第(1)种情况,由于n^log b (a) = Θ(f(n)),所以每一层的时间是相等的,故总时间是f(n)*h=f(n)*log b (n)。对于第(2)种情况,由于n^log b (a) > Θ(f(n)), 所以总时间为n^log b (a)乘上一个常数,所以为Θ(n^(log b (a))),当然,如果n^log b (a) 只比 Θ(f(n))大一丁点的话,是不行的,从上层到下层,要呈几何递增。对于第(3)种情况,n^log b (a) < Θ(f(n)),从上层到下层,时间成几何递减,故总时间复杂度为Θ(f(n))。
上面的图已经用到了递归树。下面介绍递归树
递归树
递归树规则
<1>每层的结点T(n)中的f(n)在当前n/b下的值。
<2>每个节点的分支数为a。
<3>每层的右侧标出当前层中所有结点的和。
<4>总时间为每层所有结点和的总和。
例如:T(n)=T(n/4)+T(3n/4)+n
每一层的结点和为n,从根到叶结点的最长路径为n -> (3/4)*n -> (3/4)^2*n -> ... -> 1,故a=log 3/2 (n)
所以时间复杂度为Θ(f(n)*(log 3/2 (n)))
小结:
当f(n)为常数时
当f(n)为c*n,c为常数,时
当f(n)为其他函数时,用递归树进行分析。
对本博文的技术探讨及建议请发邮件至:technique_echo@163.com
邮件标题:网名-博文名称-日期
谢谢!