秋招复习之迭代与递归

目录

前言

递归

1.  调用栈

2.  尾递归

3.  递归树

总结


前言

复习中ing,递归我总是迷迷糊糊的,这里有点醍醐灌顶。迭代是自下而上,从最基础的步骤开始,然后不断重复或累加这些步骤,直到任务完成。递归是自上而下,找到终止条件,然后向上“归”。

之前也刷过类似题:力扣刷题篇之递归-CSDN博客

参考2.2   迭代与递归 - Hello 算法 (hello-algo.com)


递归

「递归 recursion」是一种算法策略,通过函数调用自身来解决问题。它主要包含两个阶段。

  1. :程序不断深入地调用自身,通常传入更小或更简化的参数,直到达到“终止条件”。
  2. :触发“终止条件”后,程序从最深层的递归函数开始逐层返回,汇聚每一层的结果。

而从实现的角度看,递归代码主要包含三个要素。

  1. 终止条件:用于决定什么时候由“递”转“归”。
  2. 递归调用:对应“递”,函数调用自身,通常输入更小或更简化的参数。
  3. 返回结果:对应“归”,将当前递归层级的结果返回至上一层。

观察以下代码,我们只需调用函数 recur(n) ,就可以完成 1+2+⋯+n 的计算:

/* 递归 */
int recur(int n) {// 终止条件if (n == 1)return 1;// 递:递归调用int res = recur(n - 1);// 归:返回结果return n + res;
}

 该函数的递归过程:

虽然从计算角度看,迭代与递归可以得到相同的结果,但它们代表了两种完全不同的思考和解决问题的范式

  • 迭代:“自下而上”地解决问题。从最基础的步骤开始,然后不断重复或累加这些步骤,直到任务完成。
  • 递归:“自上而下”地解决问题。将原问题分解为更小的子问题,这些子问题和原问题具有相同的形式。接下来将子问题继续分解为更小的子问题,直到基本情况时停止(基本情况的解是已知的)。

以上述求和函数为例,设问题f(n)=1+2+3+...+n

  • 迭代:在循环中模拟求和过程,从 1 遍历到 n ,每轮执行求和操作,即可求得 f(n)。
  • 递归:将问题分解为子问题 f(n)=n+f(n-1),不断(递归地)分解下去,直至基本情况 f(1)=1 时终止。

1.  调用栈

递归函数每次调用自身时,系统都会为新开启的函数分配内存,以存储局部变量、调用地址和其他信息等。这将导致两方面的结果。

  • 函数的上下文数据都存储在称为“栈帧空间”的内存区域中,直至函数返回后才会被释放。因此,递归通常比迭代更加耗费内存空间
  • 递归调用函数会产生额外的开销。因此递归通常比循环的时间效率更低

如图 2-4 所示,在触发终止条件前,同时存在n个未返回的递归函数,递归深度为 n

在实际中,编程语言允许的递归深度通常是有限的,过深的递归可能导致栈溢出错误。

2.  尾递归

有趣的是,如果函数在返回前的最后一步才进行递归调用,则该函数可以被编译器或解释器优化,使其在空间效率上与迭代相当。这种情况被称为「尾递归 tail recursion」。

  • 普通递归:当函数返回到上一层级的函数后,需要继续执行代码,因此系统需要保存上一层调用的上下文。
  • 尾递归:递归调用是函数返回前的最后一个操作,这意味着函数返回到上一层级后,无须继续执行其他操作,因此系统无须保存上一层函数的上下文。

以计算 1+2+⋯+n 为例,我们可以将结果变量 res 设为函数参数,从而实现尾递归:

/* 尾递归 */
int tailRecur(int n, int res) {// 终止条件if (n == 0)return res;// 尾递归调用return tailRecur(n - 1, res + n);
}

尾递归的执行过程如图所示。对比普通递归和尾递归,两者的求和操作的执行点是不同的。

  • 普通递归:求和操作是在“归”的过程中执行的,每层返回后都要再执行一次求和操作。
  • 尾递归:求和操作是在“递”的过程中执行的,“归”的过程只需层层返回。

请注意,许多编译器或解释器并不支持尾递归优化。例如,Python 默认不支持尾递归优化,因此即使函数是尾递归形式,仍然可能会遇到栈溢出问题。

3.  递归树

当处理与“分治”相关的算法问题时,递归往往比迭代的思路更加直观、代码更加易读。以“斐波那契数列”为例。

Question

给定一个斐波那契数列 0,1,1,2,3,5,8,13,… ,求该数列的第 � 个数字。

设斐波那契数列的第 n个数字为 f(n) ,易得两个结论。

  • 数列的前两个数字为 f(1)=0 和 f(2)=1 。
  • 数列中的每个数字是前两个数字的和,即 f(n)=f(n−1)+f(n−2) 。

按照递推关系进行递归调用,将前两个数字作为终止条件,便可写出递归代码。调用 fib(n) 即可得到斐波那契数列的第 n 个数字:

/* 斐波那契数列:递归 */
int fib(int n) {// 终止条件 f(1) = 0, f(2) = 1if (n == 1 || n == 2)return n - 1;// 递归调用 f(n) = f(n-1) + f(n-2)int res = fib(n - 1) + fib(n - 2);// 返回结果 f(n)return res;
}

观察以上代码,我们在函数内递归调用了两个函数,这意味着从一个调用产生了两个调用分支。如图所示,这样不断递归调用下去,最终将产生一棵层数为 n 的「递归树 recursion tree」。

从本质上看,递归体现了“将问题分解为更小子问题”的思维范式,这种分治策略至关重要。

  • 从算法角度看,搜索、排序、回溯、分治、动态规划等许多重要算法策略直接或间接地应用了这种思维方式。
  • 从数据结构角度看,递归天然适合处理链表、树和图的相关问题,因为它们非常适合用分治思想进行分析。

总结

总之,选择迭代还是递归取决于特定问题的性质。在编程实践中,权衡两者的优劣并根据情境选择合适的方法至关重要。 

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

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

相关文章

MAC电脑安装java开发工具

一、安装brew 1.1、官网地址 链接 1.2、更新地址 二、安装 java brew install openjdk11 三、安装gradle Gradle安装与配置教程 - 知乎 四、GIT 4.1、GIT安装 brew install git 4.2、rsa ssh-keygen -t rsa -C "jhestarbucks.com" 五、自动搭建一个springBoot…

均方差损失推导

一、损失函数(Cost function) 定义:用于衡量模型预测结果与真实结果之间差距的函数。(有的地方称之为代价函数,但是个人感觉损失函数这个名称更贴近实际用途) 理解:(以均方差损失函…

「许战海战略文库」火遍云南的单山蘸水,为什么打不开全国市场?

引言:许战海咨询增长战略事业部调味品专项研究组在广泛的市场调研中发现,国内外各大视频网站都在传播“蘸水”,“蘸水”在农贸市场里,超市中的品牌和销量上升趋势明显。单山蘸水亚需立足科学的产品战略,抓住时机走向全国。 蘸水是云南人(甚至能推广到西南…

抖音引流跳转到微信加好友?免费教你创建一个链接!

在抖音想要跳转到微信,现在常规的做法就是通过微信小程序的Url Scheme跳转到微信并打开小程序指定的页面,这个已经有非常成熟的方案。 为了降低大家的门槛,可以使用开源的【引流宝】快速创建一个链接,这个链接生成的二维码&#…

【必看】网站提示不安全?教你一步步解决!

网站提示不安全通常指的是浏览器在访问某个网址时显示“不安全”或类似警告,这主要有以下几个原因: 1,SSL证书问题: 不受信任的证书颁发机构:如果网站使用的SSL证书不是由受信任的证书颁发机构(CA&#xf…

三、C语言中的分支与循环—while循环 (5)

本章分支结构的学习内容如下: 三、C语言中的分支与循环—if语句 (1) 三、C语言中的分支与循环—关系操作符 (2) 三、C语言中的分支与循环—条件操作符 与逻辑操作符(3) 三、C语言中的分支与循环—switch语句(4)分支结构 完 本章循环结…

2023年,软件评测师证书的收获与成长

在2023年,我获得了一项重要的成就,那就是软件评测师证书。这是我在软件开发领域的一次重大突破,也是我个人成长的一个重要里程碑。这一过程中,我不仅提升了自己的专业技能,也锻炼了自己的意志力和毅力,更重…

解决npm,pnpm,yarn等安装electron超时等问题

我在安装electron的时候,出现了超时等等各种问题: (RequestError: connect ETIMEDOUT 20.205.243.166:443) npm yarn:Request Error: connect ETIMEDOUT 20.205.243.166:443 RequestError: socket hang up npm ER…

HTML制作圣诞树,小白都会使用的教程。

不管你学没学过编程&#xff0c;只要有电脑都可以完成。 可以选择自己喜欢的歌曲播放 视频中的圣诞树可以闪烁 源码复制即可使用 <!DOCTYPE html> <html lang"en" ><head><meta charset"UTF-8"><title>Musical Christmas Li…

Linux学习之系统编程1(关于读写系统函数)

写在前面&#xff1a; 我的Linux的学习之路非常坎坷。第一次学习Linux是在大一下的开学没多久&#xff0c;结果因为不会安装VMware就无疾而终了&#xff0c;可以说是没开始就失败了。第二次学习Linux是在大一下快放暑假&#xff08;那个时候刚刚过完考试周&#xff09;&#xf…

中国国际光伏展

中国国际光伏展是中国规模最大、最具影响力的光伏展览会之一。该展览会定期举办&#xff0c;旨在促进全球光伏产业的发展和交流。展览会汇集了来自全球各地的光伏企业、专家学者以及相关政府机构&#xff0c;展示光伏技术、产品和解决方案。 中国国际光伏展展出的内容包括光伏发…

YoloV5改进策略:AAAI 2024 最新的轴向注意力| 即插即用,改进首选|全网首发,包含数据集和代码,开箱即用!

摘要 https://arxiv.org/pdf/2312.08866.pdf 本文提出了一种名为Multi-scale Cross-axis Attention(MCA)的方法,用于解决医学图像分割中的多尺度信息和长距离依赖性问题。该方法基于高效轴向注意力,通过计算两个平行轴向注意力之间的双向交叉注意力,更好地捕获全局信息。…