C语言--递归

在这里插入图片描述

曾经有一个段子:上大学时,我们的c语言老师说:学c时,如果有50%的同学死在了循环上面,那么就有90%的同学死在了递归上面。接下来,就来看看递归是怎么个事?

一.递归的介绍

递归是指一个函数直接或间接调用自身的过程。在编程中,递归通常用于解决可以被分解为相似子问题的任务。

  1. 基本原理:递归函数通过反复调用自身来解决问题,每次调用都会解决一个规模较小的子问题,直到达到递归的终止条件。

  2. 递归函数的结构

    • 基本情况(终止条件):递归函数需要定义一个或多个基本情况,这些情况下递归调用不再发生,避免无限循环。
    • 递归情况:在递归情况下,函数调用自身来解决同一问题的子问题。
  3. 递归与循环:递归和迭代循环(for、while循环)都可以实现相同的算法,但递归通常更简洁,易于理解,有时更符合问题的自然表达方式。

  4. 递归的应用:递归广泛用于数据结构==(如树、图等)的遍历和搜索==,例如深度优先搜索(DFS)和快速排序算法。

  5. 性能考虑递归可能会消耗大量的栈空间,因为每次函数调用都会在栈上分配一个新的栈帧。这在处理大规模问题时需要注意,可以通过优化算法或者尾递归优化来减少内存消耗。

  6. 递归的优缺点

    • 优点:简洁、清晰表达某些问题的解决方式。
    • 缺点:可能会因为调用层次过深导致栈溢出,性能上可能不如迭代循环。

二.什么是栈帧

栈帧(Stack Frame),也称为活动记录(Activation Record)或者帧(Frame),是在函数调用过程中在程序运行时栈上的一个特定区域,用于存储与当前函数调用相关的信息和数据。每当一个函数被调用时,系统就会为该函数在栈上分配一个新的栈帧,用于管理函数的局部变量、参数、返回地址以及其他执行上下文信息。

栈帧通常包括以下主要部分:

  1. 局部变量:函数内部声明的局部变量会被存储在栈帧中。这些变量的生命周期与函数的调用周期相关联,在函数调用结束时,这些变量的存储空间也会自动释放。

  2. 参数:调用函数时传递的参数值被存储在栈帧中,供函数体内部使用。

  3. 返回地址:函数调用完成后,程序需要返回到调用该函数的下一条指令的地址。返回地址存储在栈帧中,使得程序可以正确地返回到调用点继续执行。

  4. 其他管理信息:栈帧还可能包括调试信息、异常处理信息等,这些信息有助于程序的正确执行和调试。

栈帧的创建和销毁遵循后进先出(LIFO)原则,即最后进入栈的栈帧最先被释放。这种机制保证了函数调用的嵌套顺序正确,同时也控制了函数调用过程中的内存管理。

理解和正确使用栈帧是编写函数式程序的关键,尤其是在处理递归函数或者多层函数调用时,对栈帧的合理利用可以提高程序的效率和可靠性。

举例说明

有 5 个学生坐在一起, 问第 5 个学生多少岁?他说比第 4 个学生大 2岁,问第 4 个学生岁数,他说比第 3 个学生大 2 岁,问第 3 个学生,又说比第 2个学生大 2 岁,问第 2 个学生,说比第 1 个学生大 2 岁,最后问第 1 个学生,他说是 10 岁,请问第 5 个学生多大。
该问题如果使用非递归,代码如下:

//非递归求年龄
int Age1(int n)
{
	int tmp = 10; //第一个人年龄
	for(int i=1;i<n;i++)
	{
		tmp += 2;//后面的人比前一个多 2 岁
	}
		return tmp;
}

那么递归该如何处理呢?我们先分析一下:
如果 Age 函数是用来求年龄的,那么
Age(1)表示第一个人的年龄;
Age(2)表示第二个人的年龄;

Age(n-1)表示第 n-1 个人的年龄;
Age(n)表示第 n 个人的年龄。
上面的这些能理解,下面的程序就好理解了

//递归求年龄
int Age(int n)
{
	int tmp;//保存年龄
	if (n == 1)
		tmp = 10;
	else
		tmp = Age(n - 1) + 2;//当前第 n 个比第 n-1 个年龄多 2
	return tmp;
}

在这里插入图片描述
上图中的红色表示函数的调用过程,在这个过程中每个函数都还没有执行完成,那么每个函数占用的内存空间都不能释放,函数的调用都需要占用一定的栈空间(一个栈帧),而栈的空间是非常小的(在动态内存章节讲过栈 1M),当递归次数非常多时有可能出现栈空间不足

在这里插入图片描述

// 递归求年龄
int Age(int n)
{
	int tmp;//保存年龄
	if (n == 1)
		tmp = 10;
	else
		tmp = Age(n - 1) + 2;//当前第 n 个比第 n-1 个多 2
	return tmp;
	//return n == 1 ? 10 : Age(n - 1) + 2;//等同上面的代码
}
 //递归调用次数太多, 程序崩溃
int main()
{
	printf("%d\n", Age1(5000));//可以.利用循环求解
	//printf("%d\n",Age(5000));//崩溃,栈溢出,递归次数太多,超过栈容量
	return 0;
}

在这里插入图片描述

例2.求阶乘

利用递归求阶乘 n!
算法分析:可以利用下面公式求阶乘

在这里插入图片描述

long long Fac(int n)
{
	if (n == 0 || n == 1)
		return 1;
	return n * Fac(n - 1);
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

护佑未来!引领儿童安全新时代的AI大模型

引领儿童安全新时代的AI大模型 一. 前言1.1 AI在儿童安全方面的潜在作用1.2 实时监控与预警1.3 个性化安全教育与引导1.4 家长监护与安全意识提升 二. AI大模型的优势2.1. 保护儿童隐私和安全的重要性2.2. AI大模型如何应用于儿童安全领域2.1 儿童内容过滤2.2.1 儿童行为监测 2…

算法力扣刷题记录 四十四【222.完全二叉树的节点个数】

前言 二叉树篇继续。 记录 四十四【222.完全二叉树的节点个数】 一、题目阅读 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没填满外&#xff0c;其余每层节点数都…

Java时间复杂度介绍以及枚举

时间复杂度 从小到大&#xff1a; O(1) 常数阶。复杂度为O(1)与问题规模无关 线性阶 O&#xff08;n&#xff09;比如一个for循环中代码执行n遍 n阶 对数阶 int n9; int i1; while(i<n) { i*2; } 2^x>n时候退出。次数xlog2^n 时间复杂度为O(logN) 根号阶 int…

09 函数基础

目录 一、定义一个函数 二、调用函数 三、函数的参数 1.形参和实参 2. 参数的分类 3.参数默认值 4.参数类型说明 5.不定长参数 四、函数的返回值 1.定义 2.关键字return 五、变量的作用域 六、匿名函数 七、实参高阶函数 1.定义 2.常见实参高阶函数 max、min、so…

数据结构回顾(Java)

1.数组 线性表 定义的方式 int[] anew int[10] 为什么查询快&#xff1f; 1.可以借助O(1)时间复杂度访问某一元素&#xff0c; 2.地址连续&#xff0c;逻辑连续 3.数组长度一旦确定就不可以被修改 当需要扩容的时候需要将老数组的内容复制过来 在Java中数组是一个对象 Ar…

SpringBoot开发的AI导航站技术架构剖析 —— 技术如何选型 - 第520篇

历史文章&#xff08;文章累计520&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《…

C#与PLC通信——如何设置电脑IP地址

前言&#xff1a; 我们与PLC通过以太网通信时&#xff0c;首先要做的就是先设置好电脑的IP&#xff0c;这样才能实现上位机电脑与PLC之间的通信&#xff0c;并且电脑的ip地址和PLC的Ip地址要同处于一个网段&#xff0c;比如电脑的Ip地址为192.168.1.1&#xff0c;那么PLC的Ip地…

【Android面试八股文】请描述一下 android 的系统架构?

Android 是一个基于 Linux 的开源软件堆栈,针对多种不同设备类型打造。下图显示了 Android 平台的主要组件。 早期的Android架构如下图所示 官方网站最新的Android平台架构图,如下所示: Linux 内核 Android 平台的基础是 Linux 内核。例如,Android 运行时 (ART) 依赖…

css-grid布局(栅格布局)

css新世界-auto-fit grid 一个比flex更强大的布局,适合做整体布局 grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); auto-fit的话有strech效果gap 不仅可以用于grid 也可用flex. 在grid-template-areas表示这个位置空着grid area 的 [a b]命名可重复命名 表示的…

RHCA II之路---EX442-6

RHCA II之路---EX442-6 1. 题目2. 解题3. 确认 1. 题目 2. 解题 sysctl -a|grep shmall echo kernel.shmall 367001 >> /etc/sysctl.conf sysctl -p3. 确认 去人这里max total shared memory的值使我们之前设定的即可.这里的值单位是kb所以只需要2个1024就可以了 ipc…

如何快速区分电子原件极性

表贴式电阻电容无极性 1表贴式.二极管 如图所示:有横杠的表示负极&#xff08;竖杠标示&#xff09;&#xff0c;注意一定要查阅数据手册在引脚信息栏一般会有 铝电解电容 手册一般会对正负极有说明 钽电容有极性 发光二极管 芯片 一般规律&#xff1a;1.看丝印朝向正对丝印的…

监控易V7.6.6.15升级详解7,日志分析更高效

随着企业IT系统的日益复杂&#xff0c;日志管理成为了保障系统稳定运行、快速定位问题的重要工具。为了满足广大用户对日志管理功能的更高需求&#xff0c;监控易系统近日完成了重要版本升级&#xff0c;对日志管理功能进行了全面优化和新增。 一、Syslog日志与SnmpTrap日志统…

uniapp踩坑之项目:uni-table垂直居中和水平居中

uni-table 中的水平居中uni-td align"center" //html 水平居中<uni-table ref"table" :loading"loading" border stripe emptyText"暂无更多数据"><uni-tr><uni-th :width"tdWidth/6" align"center&quo…

7-Zip解压缩软件

7-Zip是一款完全免费而且开源的压缩软件&#xff0c;相比其他软件有更高的压缩比而且相对于WinRAR不会消耗大量资源 下载地址&#xff1a;7-Zip解压缩软件安装包_压缩软件安装包资源-CSDN文库

【Python3】自动化测试_用Playwright操作浏览器

创建浏览器实例 # 启动浏览器实例 myBrowser myPlaywright.chromium.launch(headlessFalse) # myBrowser myPlaywright.firefox.launch(headlessFalse) # myBrowser myPlaywright.webkit.launch(headlessFalse) args < List [ str ] >传递给浏览器实例的附加参数。 c…

仓颉语言 -- 函数

1、定义函数 仓颉使用关键字 func 来表示函数定义的开始&#xff0c;func 之后依次是函数名、参数列表、可选的函数返回值类型、函数体。其中&#xff0c;函数名可以是任意的合法标识符&#xff0c;参数列表定义在一对圆括号内&#xff08;多个参数间使用逗号分隔&#xff09;…

PyTorch论文

2019-12 PyTorch: An Imperative Style, High-Performance Deep Learning Library 设计迎合4大趋势&#xff1a; 1. array-based (Tensor) 2. GPU加速 3. 自动求导 (Auto Differentiation) 4. 拥抱Python生态 4大设计原则&#xff1a; 1. 使用算法和数据开发者熟悉的Python做编…

【Python学习笔记】:Python爬取音频

【Python学习笔记】&#xff1a;Python爬取音频 背景前摇&#xff08;省流可以不看&#xff09;&#xff1a; 人工智能公司实习&#xff0c;好奇技术老师训练语音模型的过程&#xff0c;遂请教&#xff0c;得知训练数据集来源于爬取某网页的音频。 很久以前看B站同济子豪兄的《…

开源AI生成连续一致性儿童故事书; GraphRAG结合本地版Ollama;AI辅助老年人用餐;开源无代码AI工作流VectorVein

✨ 1: SEED-Story SEED-Story 是一种能生成包含一致性图像的多模态长篇故事的机器学习模型&#xff0c;配套数据集已开放。 SEED-Story 是一种多模态长故事生成模型&#xff0c;具备生成包含丰富且连贯的叙事文本和一致性高的人物和风格图像的能力。此模型基于 SEED-X 构建。…

找到完美的横道图工具:2024年选择指南

国内外主流的10款项目进度横道图软件对比&#xff1a;PingCode、Worktile、灵动计划&#xff08;Wolai&#xff09;、飞书项目、Tapd、麦客CRM、Asana、Trello、Smartsheet、Basecamp。 在管理项目时&#xff0c;确保所有进度和任务都按计划进行是每个项目经理面临的一大挑战。…