Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【算法】答应我,今天一定要掌握什么是函数递归!!!

【算法】答应我,今天一定要掌握什么是函数递归!!!

作者头像
蒙奇D索隆
发布于 2024-12-25 02:38:48
发布于 2024-12-25 02:38:48
10100
代码可运行
举报
运行总次数:0
代码可运行

函数递归

【算法】答应我,今天一定要掌握什么是函数递归!!!_C语言
【算法】答应我,今天一定要掌握什么是函数递归!!!_C语言

导读

大家好,很高兴又和大家见面啦!!!

在上一篇内容中,我们谈论了一下我所认为的算法,以及我们学习算法应该抱有的心态。在今天的内容中,我们将开始介绍咱们需要掌握的第一个算法——递归。

递归,相信大家在学完【C语言】和【数据结构】这两个内容后,应该也是非常熟悉的。

  • 在【C语言】中,我们介绍函数时就介绍了什么是递归:
  • 程序调用自身的编程技巧称为递归
  • 在【数据结构】中,我们在学习二叉树、快速排序、归并排序时,我们就是通过递归实现的对应的功能

如果有一直看我博客的朋友应该知道,我在C站最开始发布的几篇文章——扫雷汉诺塔青蛙跳台阶……其中的一些功能就是使用的递归完成的。

既然我们已经这么熟悉递归了,我们为什么还要来把这单独作为一个章节来进行说明呢?

这个问题的答案可以总结为以下几点:

  • 在上一篇内容中我们就有说过,我所认为的广义的算法就是指的我们在解决问题时所编写的代码。因此算法我们就可以理解为是编程,而编程就是算法;
  • 对于大部分人所说的算法,都是指的狭义的算法,如我们今天要谈论的递归,以及后面会陆续介绍的动态规划、分治……其实这些编程方法在我们之前的学习中,就已经不知不觉的融入了我们的编程中,只不过我们并不知道它的名字罢了;
  • 递归作为【算法】专栏中第一个介绍的算法,是希望通过递归来帮助大家减少算法与编程的割裂感,并且减轻大家在学习算法过程中可能出现的焦虑情绪;
  • 通过熟悉的递归算法,我们能够更加清晰的认识到我们将要学习的这些解决问题的编程方法离我们究竟有多近。

那接下来我们就来直接进入今天的主题——递归。

一、递归

1.1 什么是递归?

虽然大家都已经很熟悉递归了,但是为了防止有朋友还不怎么知道什么是递归,下面我们就来以一个最简单的递归来说明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//最简单的递归
int main() {
	int ret = main();
	printf("ret = %d\n", ret);
	return 0;
}

在上例中我们编写了一个main函数,并在main函数的函数体中调用了自己,像上例程序这种自己调用自己的编程方式就是我们所说的递归。

大家可以猜一下这个程序的输出结果是什么?

【算法】答应我,今天一定要掌握什么是函数递归!!!_栈溢出_02
【算法】答应我,今天一定要掌握什么是函数递归!!!_栈溢出_02

从输出窗口中可以看到,此时啥也没有输出,并且系统报了警告——函数运行时,堆栈溢出。

1.2 递归的本质

为了帮助大家更好的看清递归的本质,下面我们可以创建一个全局的计数变量,然后通过计数变量的值来进行观测,如下所示:

【算法】答应我,今天一定要掌握什么是函数递归!!!_算法_03
【算法】答应我,今天一定要掌握什么是函数递归!!!_算法_03

可以看到,在整个程序运行的过程中,main函数被调用了4584次,从这个输出结果我们可以得到以下信息:

  • 递归就是重复的执行函数体中的代码
  • 递归不能够无限制的重复,它会在运行到一定程度时终止

还没有接触过递归的朋友可能会有疑惑,这个递归怎么和循环这么像呢?它和循环又和有何联系呢?

1.3 递归与迭代

我们直接说结论——递归和迭代都是重复同一种操作的编程方式。这里的迭代就是指的循环。不过递归与迭代不同的是,递归不存在死递归,总是会有一个终止的方式,但是迭代却会出现死循环。为什么会这样呢?

有学过函数栈帧的创建与销毁的朋友应该是能够理解的,没学过的也没关系,我们今天简单的介绍一下,大家留有一个印象即可:

  • 递归是不断的在栈区为函数开辟新的空间,在每一次开辟的空间中执行相同的操作;
  • 迭代是在对应的开辟好的函数栈帧内执行相同的操作;
  • 计算机的内存并不是无限制的,它的大小是有限的,当我们通过递归不断的向栈区申请空间时,迟早会把栈区的空间申请完,之后继续申请就会导致堆栈溢出的情况;
  • 在迭代中,当我们如上例所示,只进行全局变量的自增与结果打印的话,并不会消耗额外的内存空间,因此程序不会出现内存不够的情况;

所以不管是递归还是迭代,我们都必须防止出现栈溢出与死循环的情况发生。那具体该如何做呢?

1.4 递归的必要条件

对于递归而言,它有两个非常重要且不可忽视的条件:

  1. 递归需要有一个限制条件,即递归的结束条件
  2. 每一次递进时都需要接近该限制条件,即递进会走向结束

这里我们还是以最简单的递归为例,我们来给该递归加上对应的限制条件,以此来避免栈溢出的情况,如下所示:

【算法】答应我,今天一定要掌握什么是函数递归!!!_栈溢出_04
【算法】答应我,今天一定要掌握什么是函数递归!!!_栈溢出_04

可以看到,此时当我们在函数调用前加入一个结束条件后,此时的递归就能够很好的在满足条件时结束函数的继续调用。

迭代中防止死循环的措施

这里我也简单的提一下迭代中为了避免死循环的出现可以采取的措施:

  1. 和递归一样,在循环中设置结束条件,并且每一次循环,都会接近该条件
  2. 在循环体中设置转向语句如break、return、go to……

这里我就不再展开,我们今天重点需要关注的是递归的内容。

1.5 注意事项!!!

在递归中我们还需要注意,当我们在设置结束条件时,并不能无限制的设置,从前面的测试中我们可以看到,这里最简单的递归仅可以在内存中自我调用4584次,也就是说当我们调用了4584次main函数后,此时栈区的空间是已经被申请完了,不存在多余的空间来提供给下一次的main函数的调用。

因此在递归调用中,该结束条件的设置不能够太大,如直接设置1w、10w、100w……这些特别大的条件,也不能设置的太小,如直接设置-1w、-10w、-100w……这样的数字。因为在这种条件下,即使我们每一次的函数调用都是在接近结束条件,但是也会存在栈溢出的情况。

因此递归的调用不适合那些重复次数特别多的情况,所以当我们在处理那些结束条件特别大或者特别小的问题时,我们最好使用迭代的方式来实现。

结语

今天的内容到这里就全部结束了,在下一篇内容中我们将介绍《如何使用递归》,大家记得关注哦!如果大家喜欢博主的内容,可以点赞、收藏加评论支持一下博主,当然也可以将博主的内容转发给你身边需要的朋友。最后感谢各位朋友的支持,咱们下一篇再见!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【C语言】函数递归总结
上述就是一个简单的递归程序,只不过上面的递归只是为了演示递归的基本形式,不是为了解决问题,代码最终也会陷入死递归导致栈溢出(Stackoverflow)。
用户11290673
2024/09/25
1070
【C语言】函数递归总结
【C语言】函数递归(含扫雷进阶思路)
    递归是学习C语⾔函数绕不开的⼀个话题,那什么是递归呢?     递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。 写⼀个史上最简单的C语⾔递归代码:
TANGLONG
2024/10/15
1550
【C语言】函数递归(含扫雷进阶思路)
关于我、重生到500年前凭借C语言改变世界科技vlog.8——函数递归
在 vlog.2 的 printf 函数的返回值举例中,我们使用多次递归的方式实现了同一个函数的返回值调用,但这只是一个简易的递归,不算真正意义上的递归,那么什么是递归?
DARLING Zero two
2024/11/19
1060
关于我、重生到500年前凭借C语言改变世界科技vlog.8——函数递归
【C语言】递归详解
上述就是⼀个简单的递归程序,只不过上⾯的递归只是为了演示递归的基本形式,不是为了解决问题,代码最终也会陷⼊死递归,导致栈溢出。
zxctscl
2024/01/23
8680
【C语言】递归详解
【C语言系列】函数递归
递归其实是一种解决问题的方法,在C语言中,递归就是函数自己调用自己。 下面我们看最简单的递归代码:
四念处茫茫
2025/02/06
1660
【C语言系列】函数递归
c语言从入门到实战——函数递归
函数递归是指一个函数直接或间接地调用自身,以解决问题的一种方法。在C语言中,函数递归可以用来计算阶乘、斐波那契数列等数学问题。 函数递归是一种编程技术,其中函数直接或间接地调用自身来解决问题。它常用于处理可以分解为更小同类问题的复杂问题,如排序、搜索树等。递归的基本思想是将问题分解为更简单的子问题,然后组合子问题的解来得到原问题的解。然而,递归需要小心处理终止条件,否则可能导致无限循环。此外,递归可能消耗大量内存,因为它需要存储每个递归调用的状态。因此,在使用递归时,应仔细考虑其效率和适用性。
鲜于言悠
2024/03/20
2870
c语言从入门到实战——函数递归
C语言学习系列-->【函数的递归】
3、这个盒子里有盒子,而盒子里的盒子又有盒子。钥匙就在某个盒子中。为了找到钥匙,苦逼的你尝试了不同的方法:
南桥
2024/01/26
1300
C语言学习系列-->【函数的递归】
初识C语言·递归
递归,这两字的理解应该分开来理解,递推和回归,在C语言中,递归是函数自己调用自己,最后返回一个结果,比如写一段最简单的递归。
_lazy
2024/10/16
1790
初识C语言·递归
c语言函数递归与迭代详解(含青蛙跳台阶问题详解)
1.递归是什么? 递归是学习C语言函数绕不开的一个话题,那什么是递归呢? 递归其实是一种解决问题的方法,在C语言中,递归就是函数自己调用自己。 这里有一个极其简单的递归代码:
fhvyxyci
2024/09/24
1500
c语言函数递归与迭代详解(含青蛙跳台阶问题详解)
C语言:函数递归
递归的思想: 把⼀个⼤型复杂问题层层转化为⼀个与原问题相似,但规模较小的⼦问题来求解;直到⼦问题不能再被拆分,递归就结束了。所以递归的思考⽅式就是把⼤事化小的过程。
小陈在拼命
2024/02/17
2350
C语言:函数递归
计算机小白的成长历程——函数(4)
大家好,很高兴又和大家见面啦!经过前面几个篇章的学习,我相信大家对函数的基本知识点都已经掌握的差不多了,接下来我们将要开始探讨函数递归的相关内容了。
蒙奇D索隆
2023/10/13
1870
计算机小白的成长历程——函数(4)
C语言--函数递归与迭代
当n≤2时,第n个斐波那契数都是1,当n>2时,第n个斐波那契数就可以通过前两个数相加计算
Undoom
2024/09/23
1270
C语言函数递归_c语言递归举例
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说C语言函数递归_c语言递归举例,希望能够帮助大家进步!!!
Java架构师必看
2022/07/19
13.9K0
C语言函数递归_c语言递归举例
【C语言基础】:函数递归详解
函数递归指的是在函数内部调用自身的过程。 具体而言,递归函数通过将一个问题分解为更小的、类似的子问题来解决问题。
爱喝兽奶的熊孩子
2024/04/10
1.2K0
【C语言基础】:函数递归详解
函数的递归
1. 递归是什么? 递归是学习C语⾔函数绕不开的⼀个话题,那什么是递归呢? 递归其实是⼀种解决问题的方法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。 写⼀个史上最简单的C语⾔递归代码:
用户11290648
2024/09/25
1560
函数的递归
数据结构与算法 --- 递归(一)
「递归(Recursion)」 是一种解决问题的方法,它将问题分解为更小的子问题,并逐层解决这些子问题。递归算法的核心思想是:「一个函数可以直接或间接地调用自身」。通过这种自我调用,我们可以用简洁的代码来解决复杂问题。
Niuery Diary
2023/10/22
3990
数据结构与算法 --- 递归(一)
函数递归和迭代
函数每次调用都会在栈区申请一定空间 该空间为函数栈帧 函数被调用时申请空间 函数结束后该空间销毁
E绵绵
2024/04/08
1680
函数递归和迭代
【C语言篇】递归详细介绍(基础概念习题及汉诺塔等进阶问题)
递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。 写⼀个史上最简单的C语⾔递归代码:
半截诗
2024/10/09
1640
【C语言篇】递归详细介绍(基础概念习题及汉诺塔等进阶问题)
如何深入掌握C语言递归函数(详解)
递归的精髓在于通过不断地重复逼近一个最终的结果,它更多的是一种思想,用于解决某些问题
用户9645905
2022/11/30
8670
如何深入掌握C语言递归函数(详解)
【C语言】卍字通晓→函数+递归
🚀write in front🚀    🔎大家好,我是泽En,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 🏅2021年度博客之星物联网与嵌入式开发TOP5→周榜43→总榜3343🏅 🆔本文由 泽En 原创 CSDN首发🐒 如需转载还请通知⚠ 📝个人主页:打打酱油desu_泽En_CSDN博客🎓 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 📣系列专栏:【C】系列_打打酱油desu-CSDN博客📢 ✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩 ---- 目录
謓泽
2022/12/12
7990
【C语言】卍字通晓→函数+递归
推荐阅读
相关推荐
【C语言】函数递归总结
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验