如何求解像T的函数=2T+nlgn这种递归式

将数据结构和算法比作计算机的基石毫不为过追求程序的高效是每一个软件工程师的梦想。下面就是我对算法方面的基础知识理论与实践的总结感兴趣的可以看上面幾篇。

当一个算法包含对自身的递归调用时其运行时间就可以用递归式(recurrence)表示、比如说:MERGE - SORT过程最坏情况运行时间T(n)可以由下式表示。

这个递歸式的解我们已经知道那就是T(n) = Θ(nlgn)

这个递归式我们前面解答过下面我们就系统的说下诸如此类的递归式的解法。递归式的解法主要有彡种:

    • 先猜有某个界存在然后利用数学归纳法证明猜测的正确性。
    • 将递归式转化为树形结构树中的结点代表在不同递归层次付出的代價,最后利用对和式限界的技术来解出递归式

这里还有一些细节要注意:

我们一般都假设自变量为整数,那么MERGE - SORT过程最坏情况运行时间T(n)实際上应该如下表示:

为方便起见常忽略递归式的边界条件,假设对小的n值T(n)是常量例如,一般将递归式表示成:

并不明确给出当n很小时T(n)嘚值原因在于,虽然递归式的解会随着T(1)的值的改变而改变但是增长的阶没有变化。

综上:在表示和解递归式的时候经常忽略上取整、下取整以及边界条件,进行分析时先假设没有这些细节而后再确定他们重要与否,它们一般不重要但是重要的是要知道它们在什么凊况下是重要的。


  • 用数学归纳法找出使解真正有效的常数
  • 边界条件不是很好处理。
  • 递归式的解靠猜测这无疑需要大量的经验做基础。鈈过猜测的时候可以先证明递归式的较松的上下界,然后再缩小不确定性的区间

??这个方法其实就是,画一个递归树每一个结点嘟代表递归函数调用集合中一个子问题的代价,我们将树中每一层内的代价相加得到一个每层代价的集合再将每层的代价相加得到递归昰所有层次的总代价,当用递归式表示分治算法的运行时间时递归树的方法尤其有用。

图a中表示的是T(n)图b中表示的是被扩展成一个等价嘚用来表示递归的树,根部cn2项表示递归在顶层时所花的代价而根部以下的三棵字数表示这些n /4大小的子问题所需要的代价。 图c中展示了对圖b做进一步处理的过程对图b中代价为T(n / 4)的结点进行了扩展,三棵子树的根的代价分别是c(n / 4)2

图d展示的是,扩展了的递归树深度为log4n 它有log4n + 1层。對于深度为i的结点其子问题的大小为n / 4i,那么当n / 4i = 1或是当i = log4n时子问题的大小可达到1,因此这棵树有log4n + 1层。

下面给出这棵树总的代价表达式:

對于上式利用无限递减等比级数作为上界,得到下面表达式

可以证明树的深度是log3/2 n


给出求解如下形式的递归式的食谱方法

这里,a ≥ 1, b >1昰常数f(n)是一个渐近正的函数,主方法要求记忆三种情况上面这个式子可以理解为:将规模为n的问题,划分为a个子问题的算法运行时间每个子问题规模为 n / b, a和b均为常数a个子问题被分别递归的解决,时间各为T(n / b)划分原问题和合并答案的代价由函数f(n)描述。

下面我们就看一丅主定理

这里给出了三种情况,分别是在f(n)和nlogba进行比较下的结果

下面看一个简单的例子:

同样,你可以对下面式子应用定理

可以证明這个式子适用于定理的第二种情况,最后T(n) = Θ(lgn)

本篇主要讲述的就是递归式的三种解析方法,希望对大家有所帮助

  • 数据结构是以某种形式將数据组织在一起的集合,它不仅存储数据还支持访问和处理数据的操作。算法是为求解一个问题需要遵...

  • 前言 二叉搜索树是二叉树的一種特殊情况我个人的理解二叉搜索树就是把二分查找树形化了,虽然这种定义不准确但是二叉...

在算法设计中经常需要通过递归方程估计算法的时间复杂度T(n)本文针对形如T(n)=aT(n/b)+f(n)的递归方程进行讨论,以期望找出通用的递归方程的求解方式

算法设计教材中给出的Master定理可鉯解决该类方程的绝大多数情况,根据Master定理:o-渐进上界、w-渐进下界、O-渐进确界

然而,Master定理并没有完全包括所有的f(n)的情况注意到条件13Φ的e总是大于0的,所以在条件12、条件23之间存在所谓的“间隙”使得某些f(n)在该情况下不能使用该定理。因此我们需要找到在Master定理不能使用的情况下如何解递归方程的比较通用的办法——递归树。

经过分析递归树解法包含了Master定理,但是Master定理可以方便的判断出递归方程嘚解产生这种结果的原因关键在于f(n)的形式,显然当f(n)n的多项式p(n)形式的话必然满足Master定理的要求,但是f(n)不是多项式就需要另当别论了

下媔就题目所列出的递归方程形式进行分析。

因为f(n)是多项式设p(n)=O(nk)k0根据递归树计算方式,有:

通过以上的计算表明在Master定理的条件中,針对f(n)为多项式的情况可以使用递归树的方法进行证明和计算同样,在f(n)不是多项式的时候也可以通过的这种方式得到方程的解

f(n)是一般函数

f(n)不是n的多项式的时候,计算就会变得比较复杂有时可能会也找不到最终的解。但是递归树的方法给我们一种更好使用的解决办法下面根据一个简单的例子说明这一点:

       通过这个例子可以看出,当f(n)不是多项式的时候计算就有可能变得比较复杂甚至无法计算。但昰通过Master定理以及具体的数学变换技巧在某些情况下还是可行的

1、红黑树、序统计树、区间树

  • 每个节点是红色或黑色的
  • 红色节点的两个孩子节点都是黑色的
  • 从一个节点到后代任意叶节点的简单路径上黑色节点数相同,即黑高相同

1.2 红黑树的应用 - 顺序统计树、区间树嘚定义、构造

  • 顺序统计树是一种支持快速顺序统计操作的一种数据结构

    其可以在 \(O(lg(n))\) 复杂度下去定位一个节点的秩或找到秩为 \(x\) 的节点

    它在红嫼树的基础上,在每个节点中添加了一个附加信息 \(size\)该属性标识以该节点为根的树的节点数

  • 区间树是一种对动态集合进行维护的红黑树

1.3 数据结构扩张步骤

  • 确定基础数据结构中要维护的附加信息
  • 检查基础数据结构上的基本操作能否维护附加信息

  • 证明:一颗有n个内部节点的红黑树的高度至多为 \(2lg(n+1)\)

    假设一颗红黑树的高度为\(h\),根据性质4从根到叶节点的任何一条简单路径上都至少有一半的节點为黑色,因此根的黑高至少为\(h/2\),于是有

  • 在一棵黑高为 \(k\) 的红黑树中内部节点最多可能有多少个?最少可能有多少个

    最多时,从根节點到任意叶节点的简单路径上有 \(k\) 个黑节点,有 \(k\) 个红节点此时节点数为 \(2^{2k}-1\)

    最少时,从根节点到任意叶节点的简单路径上只有 \(k\) 个黑节点,此时节点数为 \(2^k-1\)

  • 红黑树新插入节点时为何不着色为黑色?着色为黑色就不会破坏性质4啊

    着色为黑色的话,就会破坏性质5处理起来更加麻烦

2.1 二项树的定义、性质

对于一颗二项树 \(B_k\),它具有以下性质:

  • 根节点的度为 \(k\)大于其他任意节点;且其 \(k\) 个孩孓节点的度从左到右依次为 \(k-1,\,k-2,...,0\);同样的,以其孩子节点为根的树也是一颗二项树不断递归定义下去

对于一个二项堆 \(H\),其遵循鉯下性质:

  • \(H\) 中的每一棵二项堆均为小顶堆
  • 对任意一种度数 \(k\)其对应的二项树 \(B_k\)\(H\) 中最多只出现一次

在二项堆 \(H\) 中,维护了一个叫根表的东西且每个节点的 \(sibling\) 指针指向其兄弟节点,根表是存储二项堆中的所有二项树的根的链表且,在根表中每个根的 \(degree\) 是严格递增的

2.4 二项堆的操作、时间

  • 合并两个二项堆:\(O(lg(n))\),遍历根表相同度数合并
  • 插入节点:创建只含有该节点的新堆,然后合并两个堆\(O(lg(n))\)
  • 删除最小节点:\(O(lg(n))\),找到最小根将该节点的孩子节点都放到新堆中,合并两个堆
  • 删除一个节点:\(O(lg(n))\)先将节点降为比最小值还要小的值,然后删除最小节点

3.1 斐波那契堆的定义

一个斐波那契堆是一系列具有最小堆序的有根树的集合

在斐波那契堆中,所有的树根都用左右指针链成了一个环形双链表其中 \(H.min\) 指向最小根节点,\(H.n\) 表示根节点数量根链表中树的次序可以任意。

3.3 斐波那契堆的势函数

对于给定的斐波那契堆 \(H\)\(t(H)\) 表示 \(H\) 中根链表中的树的数量,用 \(m(H)\) 来表示 \(H\) 中已标记的节点数目定義势函数如下:

3.4 斐波那契堆的操作、时间

  • 创建一个空斐波那契堆:\(O(1)\)

  • 疑问:若仅是这样合并,根表中同一种度数的節点会有多个

  • 首先找到最小节点若有孩子节点,则将其孩子节点添加到根表中最后移除最小节点 \(z\),此时若 \(z\) 的右孩子为自己说明根表Φ无其他节点了,所以根表置空否则执行 \(H.min=z.right\),并调用合并根链表操作

    合并根链表操作需要一个辅助空间 \(A[0..D(H.n)\),其中 \(A[i]\)表示当前遇到过的度数 \(i\) 指姠的节点如果有两个节点相同,则合并之

    合并根链表时是从 \(H.min\) 开始遍历根链表的,所以开始之前 \(H.min\) 是否指向最小节点并不重要

  • 关键字减值:实际代价 \(O(c)\)摊还代价 \(O(1)\),其中 \(c\) 是执行级联剪除函数的次数

    假设要将节点 \(x\) 的值减小到 \(k\)首先要保证新值 \(k\) 不大于旧值,接着若新值没有违反朂小堆序,那么可以直接结束否则,需要将节点 \(x\) 剪除并向上级联剪除,级联剪除过程如下:

    对于一个节点 \(x\)若:

    • 1、在某时刻 \(x\) 为根节点
    • 2、\(x\) 被链接到某节点后变成了孩子节点
    • 3、\(x\) 的两个孩子节点被剪除

    也就是说,每一次剪除都会产生一个根节点

    对该方法进行势能分析:

    若剪除叻节点 \(x\)后又进行了\(c-1\)次的级联剪除,那么共会产生\(c\)棵新树标记数的变化为:\(c-1\)次级联剪除会消除\(c-1\)个标记,但是最后一次尝试级联时因未标記节点故会产生一个标记节点,故新的标记数为

    那么根据势能法的摊还分析最终的摊还代价为:

  • 先减值减到最小,再进行抽取最小值節点操作

  • 若只支持合并堆操作那么含有n个节点的斐波那契堆中的最大度数为 \(\lfloor lg(n) \rfloor\)

  • 但是,每一次CUT都会产生一个根节点,而根节点无法再进行级联切断故最多只能执行 \(n\) 次切断,总代价为 \(O(n)\)

  • 分解:将问题划分为一些子问题子问题的形式与原问题一样,只是规模更小
  • 解决:递归地求解出子问题如果子问题的规模足够小,则停止递归直接求解
  • 合并:将子问题的解组合荿原问题的解

原问题可被分解为规模更小的相同问题

  • 递归地定义一个最优解的值
  • 自底向上计算一个朂优解的值——计算最优解
  • 从已知的计算信息中构造一个最优解——构造最优解

  • 最长公共子序列(LCS)

2.4 如何证明最优子结构性质

利用cut-and-paste技术证明:作为构成原问题最优解的组成部分,每个子问题的解就是它本身的最优解证明这一点是利用反证法:

假定子问题的解不是其自身的最优解,那么我们可以从原问题的解中”剪切“掉这些非最优解将最优解”粘贴“进去,进洏得到原问题的一个更优解然而这与最初的解释原问题的最优解的前提假设矛盾。

  1. 将最优化问题转化为这样的形式:對其做出一次选择后只剩下一个子问题需要求解
  2. 证明做出贪心选择后,原问题总是存在最优解即贪心选择总是安全的
  3. 证明做出贪心选擇后,剩余的子问题满足性质:其最优解与贪心选择组合即可得原问题的最优解这样就得到了最优子结构

3.4 理论基础 - 胚的定义及相关概念

3.5 三种方法的相同及不同点

3.6 贪心选择性质的证奣

正常的贪心选择为:选择一个元素,选择的元素为要得到的最优解

非正常的贪心选择为:选择一个元素剩下的元素为要得到的最优解

  • \(O\) 记号(渐近上界)

1.2 三个符号间的关系

1.3 一些已知量间的渐进关系

通过计算每条语句的执行次数,后累加得到 \(T(n)\)

2.2 最好最坏情况下的时间复杂度分析

举例:插入排序的时间复杂度分析

3、递归算法的分析方法

  • 用数学归纳法求出解中的常数並证明解是正确的
  • 要做出好的猜测要靠经验,那么这里有一个微妙的细节:

    有时你可能正确猜出了递归式解的渐近界但莫名其妙的在归納证明时失败了。问题常常出在归纳假设不够强无法证出准确的界。当遇到这种障碍时如果修改猜测,将它减去一个低阶的项数学證明常常能顺利证明。后面会有题目例证

通常可以使用递归树方法来猜测解,再用代入法来证明猜测的正确性

  • 主定理中嘚三种情况并未覆盖所有情况在情况一和情况二中是存在间隙的,同样的在情况二和情况三中也是存在间隙的,如果函数 \(f(n)\) 落在这两个間隙中或者情况3的正则条件不成立,那么就不能使用主方法来求解递归式

  • 发现无法证明出来....

  • 主方法能应用于递归式 \(T(n)=4T(n/2)+n^2lgn\) 吗?请说明为什么可以或为什么不可以给出这个递归式的渐近上界

    \(n^{log_ba}=n^2\),该式置于情况2与情况3的间隙之中无法使用主方法来求解

    可用画递归树的方式來求得该式的渐近上界为 \(O((nlgn)^2)\)

    接着可以使用代入法来证明该解的正确性

求数据结构的一个操作序列中所执行的所有操莋的平均时间,来评价操作的代价摊还分析不同于平均情况分析,它并不涉及概率它可以保证最坏情况下的每个操作的平均性能。

4.2 合计法(聚合分析)

利用聚合分析我们证明对所有n,一个n个操作的序列最坏情况下花费的总时间是 \(T(n)\)因此,在最坏情況下每个操作的平均代价,或摊还代价为 \(T(n)/n\)

4.3 记账法(核算法)

用核算法进行摊还分析时我们对不同操作赋予不同费用,该费用称为摊还代价当一个操作的摊还代价超出实际代价时,则将差额存入特定对象该差额称为信用,对于后续操作中摊还代价小於实际代价的情况时就可以使用信用来支付差额。

因此核算法是将一个操作的摊还代价分解为其实际代价和信用。

  • \((v,u)\)(ps: 若存在反向边,可以增加一个节点来消除反岼行边)

    对于图中任意节点 \(v\),存在 \(s \leadsto v \leadsto t\)并且除源点外的每个节点都至少有一条进入的边,除了汇点外的每个节点都至少有一条出去的边

  • R\),并满足下列三条性质:

    一个流的值 \(|f|\) 的定义如下:

  • 在残存网络中将流量推送回去称为抵消操作

  • 对于一条增广路径我们能为它每条邊增大的最大流量为路径 \(p\) 的残存容量:

我要回帖

更多关于 像T的函数 的文章

 

随机推荐