算法导论二-递归

一,递归式
递归算法是采用分治的方法,把一个“大问题”分解出若干个相似的“小问题”求解。

二,代换法解递归

  • 利用数学归纳法证明递归式的时间复杂度是否符合上界或下界。
  • 步骤1: 根据递归式猜解
  • 步骤2:数学归纳验证
  • 由于 步骤1 是比较麻烦的, 并且需要经验,所以代换法常用来做验证, 和下面的递归树法配合使用。 通过递归树得出解, 然后使用代换法进行验证。
  • 例子: T(n) = 4(n/2) + n , 渐近上界:O(n³) 和 O(n²)。

三,递归树法解递归

  • 在递归树中,每一个结点都代表一个子代价,每层的代价是该层所有子代价的总和,总问题的代价就是所有层的代价总和。 所以,我们利用递归树求解代价,需要知道,一个是每一层的代价,一个是树的高度。
  • 如图: 可得最终解为: Θ(n)= n²。
  • 例子:T(n) = T(n/2) + T(n/4) + n²
    算法导论二-递归_第1张图片

四,主定理法解递归

  • 主方法为如下形式的递归式提供了一种“菜谱”式的求解方法:
    T(n)=aT(n/b)+f(n)
    其中a≥1和b>1是常数,f(n)是渐近正函数.
  • 这个递推式将规模为n的问题分解为a个子问题,每个子问题的规模为n/b,a个子问题递归地求解,每个花费时间T(n/b)。函数f(n)包含了问题分解和子问题解合并的代价。 同样,这个递归式也没有考虑上取整、下取整、边界条件等,结果不会影响递归式的渐近性质。
  • 有如下规则(不满足形式和规则的使用代换法和递归树解)
    算法导论二-递归_第2张图片
    简单理解就是:f(n) 和 n^㏒ьa渐进比较。
    • f(n)小,满足条件1,并且T(n) = θ( n^㏒ьa);
    • f(n)大,满足条件3,并且T(n)=θ(f(n));
    • 如果相等同阶(或不能直接说比 n^㏒ьa大或小,通常是因为f(n)带了n的对数[考虑对数函数值大概可以明白]),这时候即与 n^㏒ьa * lg^k n 比较,确定k的值,且 T(n) = n^㏒ьa * lg^k+1 n
  • 主定理的证明 (递归树):
    算法导论二-递归_第3张图片
    通过递归树就可以比较清晰看出来了:
    1,树的高h: 可以看到,n 每层都除以 b,直到 n 为1,设除了h次,那么即 n / b^h = 1 ,即 树高 h = logь n
    2,叶子节点个数 leaves:可以看到,f(n) 每个节点每一层都分了 a 个子节点,直到最后一层(即h层,也是叶节点层),那么结合1可得叶节点数为: leaves = a ^ h = a ^ logь n,通过对数换底公式,即为 leaves = n ^ logь a。这个数就是我们要与 f(n)比较的数(看3)。
    3,那么,总代价为每一层加起来,即: T(n) =θ( f(n) + af(n/b) + a²f(n/b²) +… leaves ) = θ( f(n) + af(n/b) + a²f(n/b²) +… n ^ logь a),加项共h个,根据 θ 规则(忽略低阶)可得:
    • f(n) 比 leaves 小,那么,得到条件1,T(n) =θ(leaves)=θ(n ^ logь a)即可。
    • f(n) 比 leaves 大,那么,得到条件3,T(n) = θ(f(n)) 即可。
    • f(n) 与 leaves 同阶,即,f(n) = a * f (n/b) = a² * f(n/b²) = n ^ logь a 。那么,T(n) 可变换为: T(n) = θ( leaves * h ) = θ( f(n) * h ) = n ^ logь a * logь n ,而根据条件2 f(n) = θ( n^㏒ьa * lg^k n ),那么,T(n) = θ( n^㏒ьa * lg^k n * h ) = θ( n^㏒ьa * lg^k n * logь n )。根据对数的性质,对数底变化不大的情况下,值也变化不大,即,log ьa ≈ lg n 。所以,最终 T(n) = θ( n^㏒ьa * lg^k+1 n )

笔记参考:
https://blog.csdn.net/qing0706/article/details/50061011

你可能感兴趣的:(算法)