用递归树求解递归算法时间复杂度

文章内容、图片均来自极客时间。
递归代码复杂度分析起来比较麻烦。一般来说有两种分析方法:递推公式和递归树。

1 递推公式法

归并排序的递推公式是:

merge_sort(p…r) = merge(merge_sort(p…q), merge_sort(q+1…r))
终止条件:
p >= r 不用再继续分解

我们假设对n个元素排序的时间是T(n),那分解成两个子数组排序的时间是T(n2)T(\dfrac{n}{2})T(2n)。merge函数合并两个子数组的时间复杂度是O(n)。所以归并排序时间复杂度计算公式就是:
 T(n)=2∗T(n2)+n,n>2T(n)=2*T(\dfrac{n}{2})+n,n>2T(n)=2T(2n)+n,n>2
 T(1)=c;
 
 继续计算T(n)

T(n)=2*T(n/2)+n=2*(2*T(n/4)+n/2)+n=4*T(n/4)+2n=4*(2*T(n/8)+n/4)+2n=8*T(n/8)+3n=8*(2*T(n/16)+n/8)+3n=16*T(n/16)+4n...=2^k*T(n/2^k)+k*n

n/2k=1n/2^k=1n/2k=1的时候,k=log2nk=log_2nk=log2n,代入上面的式子:T(n)=c∗n+nlog2nT(n)=c*n+nlog_2nT(n)=cn+nlog2n,用大O表示法,T(n)=O(nlogn)。

2 递归树法

递归的思想就是将大问题分解为小问题来求解。然后再将小问题分解成小小问题。这样一层层分解直到问题不能再分解。如果我们把这一层层的分解过程画成图,其实就是一棵树。我们把它叫做递归树。
参看下图,括号中的数字表示问题的规模。

在这里插入图片描述

归并排序比较耗时的操作是合并,也就是将两个小数组合并成一个大数组。其他操作的代价很低,可以记为常数L。
从图中看出每一层的耗时是相同的,都为n。现在我们只要知道这棵树的高度h,就可以得到总的时间复杂度O(h*n)。
从图中能看到这是一颗满二叉树。满二叉树的高度大约是log2nlog_2nlog2n。所以归并排序的时间复杂度就是O(nlogn)。

3 递归树分析法实战

3.1 快排时间复杂度

快排的递推公式:quick_sort(p…q) = quick_sort(p,i-1)+ quick_sort(i+1,q)
退出条件:p>=q
快排最好的情况是每次都能将数组一分为二。这时候用递推公式T(n)=2T(n/2)+n,就能得到时间复杂度O(nlogn)。
但是不可能每次都是理想情况。我们假设平均情况下每次分区,两个分区的比例是1:k。当k=9的时候,公式变为这样:
T(n)=T(9n10)+T(n10)+nT(n)=T(\dfrac{9n}{10})+T(\dfrac{n}{10})+nT(n)=T(109n)+T(10n)+n
这个公式的值不太好求。用递归树是不是更简单呢?
在这里插入图片描述

我们看到每一层因为有选择交换操作,且最多n次。所以每一层的操作代价是相同的:n。
递归树的路径长度却是不一样的。快排结束的条件是待排序的区间大小为1,也就是说叶子节点的数据规模是1。从节点n到叶子节点1,递归树中的最长路径是每次乘以110\dfrac{1}{10}101,最短路径是每次乘以910\dfrac{9}{10}109。通过计算,我们可以得到,从根节点到叶子节点的最短路径是 log10nlog_{10}nlog10n,最长路径是log(109)nlog_(\dfrac{10}{9})nlog(910)n。所以总操作代价在n∗log10nn*log_{10}nnlog10nn∗log(109)nn*log_(\dfrac{10}{9})nnlog(910)n之间。大O表示法不关注对数的底数,所以平均时间复杂度O(n*logn)。

将k=99,999…替换之后结论相同。

3.2 斐波那契数列

上面的两个例子每层的操作数相同,都是n。这次需要具体分析每层的操作数。
菲波那切数列的实现代码:

int f(int n) {if (n == 1) return 1;if (n == 2) return 2;return f(n-1) + f(n-2);
}

把递归代码画成递归树如下。
在这里插入图片描述
f(n)分解为f(n-1)和f(n-2),每次-1,或者-2。叶子节点的数据规模是1或者2。那最长路径大概就是n,最短路径大概是n2\dfrac{n}{2}2n

每次分解之后的合并操作只是一次加法,算一个时间1。第一层是f(n-1)+f(n-2),1次运算;第二层是f(n-2)+f(n-3),f(n-3)+f(n-4)是两次运算…依次类推,第k层的总耗时是2k−12^{k-1}2k1。算法总耗时是每层耗时相加。

如果路径长度都为n,那么总耗时是:2n−12^n-12n1
1+2+22+...+2n−1=2n−11+2+2^2+...+2^{n-1}=2^n-11+2+22+...+2n1=2n1

如果路径长度都为n2\dfrac{n}{2}2n,那么总耗时是2n2−12^{\dfrac{n}{2}}-122n1
1+2+22+...+2n2−1=2n2−11+2+2^2+...+2^{\dfrac{n}{2}-1}=2^{\dfrac{n}{2}}-11+2+22+...+22n1=22n1

所以算法的时间复杂度在2n2−12^{\dfrac{n}{2}}-122n12n−12^n-12n1之间。这样的计算不够精确,只是一个范围。但是我们知道了该算法的时间复杂度是指数级的。复杂度非常高。

心得:时间复杂度是可以估算的,不用非常准确。只要数量级保证正确即可。

3.3 全排列的时间复杂度

1 递归公式是

假设数组里的内容是1,2,3.....n
f(n)={最后一位是1,f(n-1)}+{最后一位是2,f(n-1)}+...+{最后一位是n,f(n-1)}

接着画出递归树。
在这里插入图片描述

2 对于问题f(n),在得到子问题f(n-1)的结果之后需要把结果相加,有n次相加,所以第一层的操作数是n。
对于问题f(n-1),首先会有n个f(n-1)的问题需要求解。每个f(n-1),在得到子问题f(n-2)的结果之后需要把结果相加,有n-1次相加操作,所以第二层的操作数是n*(n-1)。
以此类推,到最后一层的子问题是f(1),会有n*(n-1)(n-2)2个f(1)。f(1)可以直接返回,操作数是1。所以最后一层的操作数是:n∗(n−1)∗(n−2)∗...∗2∗1=n!n*(n-1)*(n-2)*...*2*1=n!n(n1)(n2)...21=n!
3 因为叶子问题为f(1),问题每次-1分解,所以有n层。
4 前面每一层的操作数都小于n!,所以时间复杂度在n∗n!n*n!nn!n!n!n!之间。
5 算法时间复杂度大于O(n!),小于O(n
n!)。复杂度非常高。

4 递归树法分析得步骤

1 找到递归公式画递归树
2 计算每一层在得到子问题的解以后,还要进行哪些操作才能得到本问题的答案,计算这些操作的操作数。
3 考虑树的最长路径和最短路径。
4 分别按照最长路径和最短路径计算所有层的操作数的和。
5 得出时间复杂度范围,推测时间复杂度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424593.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring学习(8):log4j.properties 详解与配置步骤

一、入门实例 1.新建一个JAva工程,导入包log4j-1.2.17.jar,整个工程最终目录如下 2、src同级创建并设置log4j.properties ### 设置### log4j.rootLogger debug,stdout,D,E### 输出信息到控制抬 ### log4j.appender.stdout org.apache.log4j.ConsoleAp…

[hackinglab][CTF][注入关][2020] hackinglab 注入关 writeup

服务器挂了 咕咕咕 参考链接:https://blog.csdn.net/weixin_41924764/article/details/107095963?utm_mediumdistribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_sourcedistribute.pc_relevant_t0.none-task-bl…

数据结构六——堆

文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。 1 堆定义 1.1 定义和结构 堆是一个完全二叉树(完全二叉树:除了叶子节点外每一层节点都是满的,最后一层的子节点都靠左排列&…

spring学习(9):idea的config配置

点开eventlog 点击之后 勾选 apply---ok

[hackinglab][CTF][上传关][2020] hackinglab 上传关 writeup

上传关 1 请上传一张jpg格式的图片 关键字: 步骤: 1.F12查看源码 2.输入网址 获得key http://lab1.xseclab.com/upload1_a4daf6890f1166fd88f386f098b182af/upload_file.php上传关 2 关键字:burp 知识点: 步骤:看源…

靠谱的Pycharm安装详细教程

如何在本机上下载和安装Pycharm,具体的教程如下: 1、首先去Pycharm官网,或者直接输入网址:http://www.jetbrains.com/pycharm/download/#sectionwindows,下载PyCharm安装包,根据自己电脑的操作系统进行选择…

第四十四期:Keep突然大裁员,回应称“属正常调整”!

10 月 24 日程序员节原本是程序员们最开心的一天,但 Keep 程序员却开心不起来,因为不少人突然面临失业危机。\ 作者:51CTO 10 月 24 日程序员节原本是程序员们最开心的一天,但 Keep 程序员却开心不起来,因为不少人突然…

第四十五期:万亿级日访问量下,Redis在微博的9年优化历程

Redis在微博内部分布在各个应用场景,比如像现在春晚必争的“红包飞”活动,还有像粉丝数、用户数、阅读数、转评赞、评论盖楼、广告推荐、负反馈、音乐榜单等等都有用到Redis。 作者:兰将州来源 一、Redis在微博的应用场景 Redis在微博内部…

数据结构七——图

文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。 1 基本概念 顶点、边 微信:A和B是好朋友,B也和A是好朋友,A和B之间有条边。 入度:每个顶点链接的边的个数每个人好朋友…

[CTF][Web][PHP][JavaScript]弱类型问题

弱类型问题 类型转换是无法避免的问题。例如需要将GET或者是POST的参数转换为int类型,或者是两个变量不匹配的时候,PHP会自动地进行变量转换。但是PHP是一个弱类型的语言,导致在进行类型转换的时候会存在很多意想不到的问题。 如果在用于密…

第四十六期:最近程序员频繁被抓,如何避免面向监狱编程?!

最近,有很多关于程序员被抓甚至被判刑的新闻在朋友圈疯传:"某程序员因为接了个外包,帮别人写了个软件,结果这个软件被用于赌博导致被抓。某公司利用爬虫抓取用户信息,最后被发现,导致该公司的程序员被…

算法五——字符串匹配(上)

文章内容、图片均来自极客时间。 如何借助哈希算法实现高效字符串匹配 1 概念和用途 字符串匹配:查找一个字符串A在字符串B中是否出现,这个过程就是字符串匹配。A称为模式串,B称为主串。主串的长度记为n,模式串长度记为m。n>…

算法五——字符串匹配(中)

文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。 1文本编辑器中的查找功能怎么实现 在word中有一个功能:查找某个字符串,将其替换为另一个字符串,就会用到这个功能。 需要新算法的…

第四十七期:漫画:什么是公有云、私有云和混合云?

为了方便大家理解,我们尽量用通俗的语言和举例子的方式讲解,并且文中还配备了漫画供大家参考学习。 作者:漫话编程 为了方便大家理解,我们尽量用通俗的语言和举例子的方式讲解,并且文中还配备了漫画供大家参考学习。 …

第四十八期:你太菜了,竟然不知道Code Review?

我一直认为Code Review(代码审查)是软件开发中的优秀实践之一,可以有效提高整体代码质量,及时发现代码中可能存在的问题。 作者:宝玉 我一直认为Code Review(代码审查)是软件开发中的优秀实践之一,可以有效提高整体代码质量&…

算法五——字符串匹配(下)KMP

文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。 KMP,是三个作者(D.E.Knuth,J.H.Morris和V.R.Pratt)的简称。   KMP算法和BM一样,也是一个字符串匹配算法。…

第四十九期:大牛总结的MySQL锁优化,写得太好了!

随着 IT 技术的飞速发展,各种技术层出不穷,让人眼花缭乱。尽管技术在不断更新换代,但是有些技术依旧被一代代 IT 人使用至今。 作者:崔皓 随着 IT 技术的飞速发展,各种技术层出不穷,让人眼花缭乱。尽管技…

数据结构八-Trie树

文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。 1 Trie树的使用场景 搜索引擎中的搜索词建议。当你在搜索引擎中输入词,搜索引擎提示给你一个词的列表,帮助你快速输入想搜索的词。 这个功能…

[安全模型][Cambria Math][A][]敌手A-> 怎么打出来?

字母A 设置字体 “Cambria Math” -> 𝒜

第五十期:详解语音识别技术的发展

在我们的生活中交流起着重要的作用。人类从符号开始,然后发展到用语言交流,再后来出现了计算和通信技术。在某些情况下,机器不仅与人类交流,也与机器之间交流。计算机和通信技术创造了互联网世界,正如我们所知的物联网…