在上一章中我们讨论了如何分析循环语句。在现实中,有很多算法是递归的,当我们分析这些算法的时候我们要找到他们的的递归关系。例如归并排序,为了排序一个数组,我们把它平均分为两份然后再重复平分的步骤。最后我们合并这些结果。归并排序的时间复杂度可以写作T(n) = 2T(n/2) + cn。当然还有很多其他的类似算法如二分查找,汉诺塔等等。

有三种办法可以分析递归函数。

1.置换法 substitution method: (叫假设法比较合适)

我们可以先假设一下算法的时间复杂度,然后用数学归纳法来验证这个假设是不是正确的。

例如我们有一个这样的递归的函数 T(n) = 2T(n/) + n

我们假设他的答案是 T(n) = O(nLogn). 现在我们用数学归纳法来验证我们的猜想

我们需要证明 存在某个常数C T(n) <= cnLogn. 
我们可以假设当某个小于n的值是 这个式子是成立的 T(n) = 2T(n/) + n
<= c (n/2Log(n/)) + n
= cnLogn - cnLog2 + n
= cnLogn - cn + n
<= cnLogn

2.递归树的方法Recurrence Tree Method

我们可以画一个递归树并计算每一层的运行时间,最后我们把所有的时间加到一起。我们从给出的递归时开始一直往下画知道我们可以找到某种pattern。这种pattern一般都是等比数列或者等差数列

For example consider the recurrence relation
T(n) = T(n/) + T(n/) + cn2 cn2
/ \
T(n/) T(n/) If we further break down the expression T(n/) and T(n/),
we get following recursion tree. cn2
/ \
c(n2)/ c(n2)/
/ \ / \
T(n/) T(n/) T(n/) T(n/)
Breaking down further gives us following
cn2
/ \
c(n2)/ c(n2)/
/ \ / \
c(n2)/ c(n2)/ c(n2)/ c(n2)/
/ \ / \ / \ / \ To know the value of T(n), we need to calculate sum of tree
nodes level by level. If we sum the above tree level by level,
we get the following series
T(n) = c(n^ + (n^)/ + (n^)/) + ....
The above series is geometrical progression with ratio /. To get an upper bound, we can sum the infinite series.
We get the sum as (n2)/( - /) which is O(n2)

3.主定理 master method

主定理是一种可以直接得到结果的方法。但是主定理只能用于下面这种形式的递归式

T(n) = aT(n/b) + f(n) where a >=  and b > 

有三种情况

1. If f(n) = Θ(nc) where c < Logba then T(n) = Θ(nlogba)

2. If f(n) = Θ(nc) where c = Logba then T(n) = Θ(ncLog n)

3.If f(n) = Θ(nc) where c > Logbthen T(n) = Θ(f(n))

一些标准算法用主定理来计算时间复杂度的例子:

merge sort 归并排序 : T(n) = 2T(n/2) + Θ(n). 是第二个case c=1 Logba = 1 所以时间复杂度是 Θ(n Logn)

binary search 二分查找: T(n) = T(n/2) + Θ(1).是第二个case c=0 logba = 0 时间复杂度是Θ(Logn)

分析递归式 Solving Recurrences------GeeksforGeeks 翻译的更多相关文章

  1. 【Python算法】递归与递归式

    该树结构显示了从1(根节点)到n(n个叶节点)的整个倍增过程.节点下的标签表示从n减半到1的过程. 当我们处理递归的时候,这些级数代表了问题实例的数量以及对一系列递归调用来说处理的相关工作量. 当我们 ...

  2. C++扬帆远航——18(项目五2,递归式)

    /* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:qiushi.cpp * 作者:常轩 * 微信公众号:World ...

  3. 算法——快速排序迭代式和递归式的Java实现

    快速排序迭代式和递归式的Java实现 快速排序基于分治法的思想,在待排序表中任选一值作为中枢值 pivot,一趟快排将所有大于该值的元素置于一边,小于该值的元素置于另一边,这样一个元素在排序中的最终位 ...

  4. 平摊分析 Amortized Analysis ------geeksforgeeks翻译

    当偶尔一切操作很花的时间很慢,而大多数操作的时间都很快的时候,平摊分析的方法就很很好用了.在平摊分析中,我们分析一串操作并且可以得到最坏情况下的平均时间复杂度.例如hash table, disjoi ...

  5. 算法最坏,平均和最佳情况(Worst, Average and Best Cases)-------geeksforgeeks 翻译

    最坏,平均和最佳运行时间(Worst, Average and Best Cases) 在上一篇文章中,我们讨论到了渐进分析可以解决分析算法的问题,那么在这一篇中,我们用线性搜索来举例说明一下如何用渐 ...

  6. Makefile内置变量,递归式变量,直接展开式变量,条件赋值,追加赋值

    将shell命令的输出赋值给变量: VALUE = $(shell   命令) Makefile中给变量赋值: =     是递归展开式变量 value1 = 5 value2 = $(value1) ...

  7. C# 递归式快速排序算法

    static void Main(string[] args) { Console.WriteLine("************快速排序*****************"); ...

  8. 空间复杂度是什么?What does ‘Space Complexity’ mean? ------geeksforgeeks 翻译

    这一章比较短! 空间复杂度(space complexity)和辅助空间(auxiliary space)经常混用,下面是正确的辅助空间和空间复杂度的定义 辅助空间:算法需要用到的额外或者暂时的存储空 ...

  9. Windows C++ 非递归式(stack)深度优先遍历目录

    #include <Windows.h> #include <cstdio> #include <cstring> #include <string> ...

随机推荐

  1. IOC容器中bean的生命周期

    一.Bean的生命周期 Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务. Spring IOC容器对Bean的生命周期进行管理的过程如下: (1).通 ...

  2. 使用jQuery库改造ajax

    html页 ---------------------------------------------------------------------------------------------- ...

  3. H5前端面试题及答案(1)

    前几天去面试了一家公司,整下改公司的面试题. 1.新的 HTML5 文档类型和字符集是? HTML5 文档类型很简单: <!doctype html> HTML5 使用 UTF-8 编码示 ...

  4. 关于SharePoint 的Client object model该何时load和execut query的一点自己的看法

    很多人在用client object model的时候,不知道何时或者该不该load,今天看到一个观点描述这个问题,觉得很有道理,和大家分享.那就是写client object model就像写sql ...

  5. SPServices.SPDisplayRelatedInfo

    Function $().SPServices.SPDisplayRelatedInfo Certification Functionality SPDisplayRelatedInfo is a f ...

  6. 每日vim插件--vim中的文本对象及相关插件

    最近在个人博客上 http://foocoder.com  每天都会介绍一个vim插件,想起来园子也好久没更新了,也来更新一篇. 今天按读者留言的要求,介绍下文本对象.同时还会介绍我在用的几个文本相关 ...

  7. 安卓问题集-Installation error: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED

    错误出现原因: 1.没有 AndroidManifest.xml file文件(出现几率较小) 2. 是你在外面修改了包名而在 AndroidManifest.xml file.文件中没有同步过去导致 ...

  8. UWP开发-HTTP详解

    HTTP作为一个基础功能,有必要介绍下在UWP下的使用方法. 一.Get请求: 一般我们用到的是GetAsync方法 public static async Task Gets(Uri uri) { ...

  9. App开发流程之源代码Git管理

    base项目已经可以编译运行了,只不过没有实际功能而已.继续完善base项目前,我们需要考虑一下代码管理的事情了. 不管是一个人开发还是一个团队开发,对源代码进行版本管理是必须的,任何人对代码的的任何 ...

  10. iOS开发之网络编程--使用NSURLConnection实现大文件下载

    主要思路(实现下载数据分段写入缓存中) 1.使用NSURLConnectionDataDelegate以及代理方法.2.在成功获取响应的代理方法中,获得沙盒全路径,并在该路径下创建空文件和文件句柄.3 ...