分析递归式 Solving Recurrences------GeeksforGeeks 翻译
在上一章中我们讨论了如何分析循环语句。在现实中,有很多算法是递归的,当我们分析这些算法的时候我们要找到他们的的递归关系。例如归并排序,为了排序一个数组,我们把它平均分为两份然后再重复平分的步骤。最后我们合并这些结果。归并排序的时间复杂度可以写作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 > Logba then 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 翻译的更多相关文章
- 【Python算法】递归与递归式
该树结构显示了从1(根节点)到n(n个叶节点)的整个倍增过程.节点下的标签表示从n减半到1的过程. 当我们处理递归的时候,这些级数代表了问题实例的数量以及对一系列递归调用来说处理的相关工作量. 当我们 ...
- C++扬帆远航——18(项目五2,递归式)
/* * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:qiushi.cpp * 作者:常轩 * 微信公众号:World ...
- 算法——快速排序迭代式和递归式的Java实现
快速排序迭代式和递归式的Java实现 快速排序基于分治法的思想,在待排序表中任选一值作为中枢值 pivot,一趟快排将所有大于该值的元素置于一边,小于该值的元素置于另一边,这样一个元素在排序中的最终位 ...
- 平摊分析 Amortized Analysis ------geeksforgeeks翻译
当偶尔一切操作很花的时间很慢,而大多数操作的时间都很快的时候,平摊分析的方法就很很好用了.在平摊分析中,我们分析一串操作并且可以得到最坏情况下的平均时间复杂度.例如hash table, disjoi ...
- 算法最坏,平均和最佳情况(Worst, Average and Best Cases)-------geeksforgeeks 翻译
最坏,平均和最佳运行时间(Worst, Average and Best Cases) 在上一篇文章中,我们讨论到了渐进分析可以解决分析算法的问题,那么在这一篇中,我们用线性搜索来举例说明一下如何用渐 ...
- Makefile内置变量,递归式变量,直接展开式变量,条件赋值,追加赋值
将shell命令的输出赋值给变量: VALUE = $(shell 命令) Makefile中给变量赋值: = 是递归展开式变量 value1 = 5 value2 = $(value1) ...
- C# 递归式快速排序算法
static void Main(string[] args) { Console.WriteLine("************快速排序*****************"); ...
- 空间复杂度是什么?What does ‘Space Complexity’ mean? ------geeksforgeeks 翻译
这一章比较短! 空间复杂度(space complexity)和辅助空间(auxiliary space)经常混用,下面是正确的辅助空间和空间复杂度的定义 辅助空间:算法需要用到的额外或者暂时的存储空 ...
- Windows C++ 非递归式(stack)深度优先遍历目录
#include <Windows.h> #include <cstdio> #include <cstring> #include <string> ...
随机推荐
- java之StringBuilder类详解
StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...
- B/S和C/S的区别(转)
一.什么是CS和BS结构? 1.C/S又称Client/Server或客户/服务器模式.服务器通常采用高性能的PC.工作站或小型机,并采用大型数据库系统,如Oracle.Sybase.Informix ...
- PHP imagecopyresampled 参数图示
- RAID选项
RAID:Redundant Array Independent Disk(独立磁盘构成的具有冗余能力的阵列) 最常见的为RAID类型为:0,1,5和10:3和6很少见,但在某些环境中仍然有用. RA ...
- ASP.NET Web API默认支持的媒体类型(SupportedMediaTypes)
JsonMediaTypeFormatter XmlMediaTypeFormatter ( application/xml text/xml) FormUrlEncodedMediaTypeFor ...
- ElasticSearch文档-简单介绍
ElasticSearch是一个基于Lucene构建的开源,分布式,RESTful搜索引擎.设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便.支持通过HTTP使用JSON进行数据索引 ...
- swift学习笔记之-错误处理
//错误处理 import UIKit /*错误处理(Error Handling):响应错误以及从错误中恢复的过程 在 Swift 中,错误用符合ErrorType协议的类型的值来表示.这个空协议表 ...
- 关于在EXCEL中输入01-01-01被转换为2001/1/1怎么解决
当向EXCEL写入类似'01-01-01'或'01-01'这样的数据时,打开EXCEL时会发现数据变成了2001/1/1和1月1日. 这是由于EXCEL自动转换功能,我们得要在输入前多加一个’号. 而 ...
- 使用Python给要素添加序号
在ArcGIS的属性表中,由于编辑修改的原因,默认的FID或OID并不连续,经常需要给要素添加连读的序号,可使用Python代码完成. rec=-1 def autoIncrement(): glob ...
- 【读书笔记】iOS-复制的种类
一,你可以使用不同的方法复制对象.大多数对象都引用(即指向)其它对象. 二,浅层复制,不复制引用对象,新复制的对象只指向现有的引用对象.NSArray类的copy方法是浅层复制.当复制一个NSArra ...