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;elsetmp = Age(n - 1) + 2;//当前第 n 个比第 n-1 个年龄多 2return tmp;
}

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

在这里插入图片描述

// 递归求年龄
int Age(int n)
{int tmp;//保存年龄if (n == 1)tmp = 10;elsetmp = Age(n - 1) + 2;//当前第 n 个比第 n-1 个多 2return 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);
}

在这里插入图片描述

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

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

相关文章

跨平台WPF音乐商店应用程序

目录 一 简介 二 设计思路 三 源码 一 简介 支持在线检索音乐&#xff0c;支持实时浏览当前收藏的音乐及音乐数据的持久化。 二 设计思路 采用MVVM架构&#xff0c;前后端分离&#xff0c;子界面弹出始终位于主界面的中心。 三 源码 视窗引导启动源码&#xff1a; namesp…

MySQL(8)事务

目录 1.事务; 1.事务: 1.1 如果CURD不加限制会这么样子? 可能造成数据同时被修改, 数据修改的结果是未知的.(可以想一下之前的抢票线程问题) 1.2 事务概念: 事务就是一组DML语句组成&#xff0c;这些语句在逻辑上存在相关性&#xff0c;这一组DML语句要么全部成功&#xff0…

基于python旅游景点满意度分析设计与实现

1.1研究背景与意义 1.1.1研究背景 随着旅游业的快速发展&#xff0c;满意度分析成为评估旅游景点质量和提升游客体验的重要手段。海口市作为中国的旅游城市之一&#xff0c;其旅游景点吸引了大量游客。然而&#xff0c;如何科学评估和提升海口市旅游景点的满意度&#xff0c;…

【概率论三】参数估计:点估计(矩估计、极大似然法)、区间估计

文章目录 一. 点估计1. 矩估计法2. 极大似然法2.1. 似然函数2.2. 极大似然估计法 3. 评价估计量的标准3.1. 无偏性3.2. 有效性3.3. 一致性 二. 区间估计1. 区间估计的概念2. 正态总体参数的区间估计 参数估计讲什么 由样本来确定未知参数参数估计分为点估计与区间估计 一. 点估…

算法:二叉树相关

目录 题目一&#xff1a;单值二叉树 题目二&#xff1a;二叉树的最大深度 题目三&#xff1a;相同的树 题目四&#xff1a;对称二叉树 题目五&#xff1a;另一棵树的子树 题目六&#xff1a;二叉树的前序遍历 题目七&#xff1a;二叉树遍历 题目八&#xff1a;根据二叉…

linux搭建mysql主从复制(一主一从)

目录 0、环境部署 1、主服务器配置 1.1 修改mysql配置文件 1.2 重启mysql 1.3 为从服务器授权 1.4 查看二进制日志坐标 2、从服务器配置 2.1 修改mysql配置文件 2.2 重启mysql 2.3 配置主从同步 2.4 开启主从复制 3、验证主从复制 3.1 主服务器上创建test…

4款良心软件,免费又实用,内存满了都舍不得卸载

以下几款高质量软件&#xff0c;若是不曾体验&#xff0c;实在是遗憾可惜。 PDF Guru 这是一款开源免费的PDF编辑软件&#xff0c;打开之后功能一目了然。 可以拆分、合并PDF&#xff0c;也可以给PDF添加水印和密码&#xff0c;同时也可以去除别人PDF里的水印或密码&#xff0…

HouseCrafter:平面草稿至3D室内场景的革新之旅

在室内设计、房地产展示和影视布景设计等领域,将平面草稿图快速转换为立体的3D场景一直是一个迫切的需求。HouseCrafter,一个创新的AI室内设计方案,正致力于解决这一挑战。本文将探索HouseCrafter如何将这一过程自动化并提升至新的高度。 一、定位:AI室内设计的革新者 Ho…

【iOS】类对象的结构分析

目录 对象的分类object_getClass和class方法isa流程和继承链分析isa流程实例验证类的继承链实例验证 类的结构cache_t结构bits分析实例验证属性properties方法methods协议protocolsro类方法 类结构流程图解 对象的分类 OC中的对象主要可以分为3种&#xff1a;实例对象&#xf…

TDesign组件库日常应用的一些注意事项

【前言】Element&#xff08;饿了么开源组件库&#xff09;在国内使用的普及率和覆盖率高于TDesign-vue&#xff08;腾讯开源组件库&#xff09;&#xff0c;这也导致日常开发遇到组件使用上的疑惑时&#xff0c;网上几乎搜索不到其文章解决方案&#xff0c;只能深挖官方文档或…

C++右值引用和移动语义

目录 概念&#xff1a; 左值引用和右值引用 概念&#xff1a; 注意&#xff1a; 左值引用的意义 作函数参数 函数引用返回 右值引用的意义 诞生背景 移动构造 移动赋值 其他应用 万能引用和完美转发 默认的移动构造和移动赋值 概念&#xff1a; 左值&#xff1a;顾…

VulnHub:CK00

靶场搭建 靶机下载地址&#xff1a;CK: 00 ~ VulnHub 下载后&#xff0c;在vmware中打开靶机。 修改网络配置为NAT 处理器修改为2 启动靶机 靶机ip扫描不到的解决办法 靶机开机时一直按shift或者esc直到进入GRUB界面。 按e进入编辑模式&#xff0c;找到ro&#xff0c;修…

思路|如何利用oneNote钓鱼?

本文仅用于技术研究学习&#xff0c;请遵守相关法律&#xff0c;禁止使用本文所提及的相关技术开展非法攻击行为&#xff0c;由于传播、利用本文所提供的信息而造成任何不良后果及损失&#xff0c;与本账号及作者无关。 本文来源无问社区&#xff0c;更多实战内容&#xff0c;…

[python]pycharm设置清华源

国内镜像源有以下几个&#xff0c;因为都是国内的&#xff0c;基本速度差不了太多。 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣&…

爬虫案例(读书网)(下)

上篇链接&#xff1a; CSDN-读书网https://mp.csdn.net/mp_blog/creation/editor/139306808 可以看见基本的全部信息&#xff1a;如(author、bookname、link.....) 写下代码如下&#xff1a; import requests from bs4 import BeautifulSoup from lxml import etreeheaders{…

scottplot5 中 使用signalXY图,如何更新数据?

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

Apache POI 使用Java处理Excel数据 进阶

1.POI入门教程链接 http://t.csdnimg.cn/Axn4Phttp://t.csdnimg.cn/Axn4P建议&#xff1a;从入门看起会更好理解POI对Excel数据的使用和处理 记得引入依赖&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactI…

JVM高频面试点

文章目录 JVM内存模型程序计数器Java虚拟机栈本地方法栈Java堆方法区运行时常量池 Java对象对象的创建如何为对象分配内存 对象的内存布局对象头实例数据对齐填充 对象的访问定位 垃圾收集器找到垃圾引用计数法可达性分析&#xff08;根搜索法&#xff09; 引用概念的扩充回收方…

【Socket套接字编程】(实现TCP和UDP的通信)

&#x1f387;&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳&#xff0c;欢迎大佬指点&#xff01; 人生格言: 当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友…

创建通用JS公共模块并发布至npm

title: 创建通用JS公共模块并发布至npm tags: UMD rollup verdaccio npm categories: 模块化 概要内容 创建&#xff1a;JS公共模块 打包&#xff1a;使用rollup 打包公共模块 发布&#xff1a;js公共模块至verdaccio平台 发布&#xff1a;js公共模块至npm平台 如何创建JS公共模…