函数递归的介绍

1.递归的定义

C语言中,递归就是函数自己调用自己

上面的代码就是 main 函数在函数主体内 自己调用自己

但是,上面的代码存在问题:main 函数反复地 自己调用自己 ,不受限制,停不下来。

最终形成死递归,导致栈溢出

1.0栈溢出

 每一次函数调用,都要从内存上的栈区为这次函数调用分配内存空间

栈区的大小是有限的,如果无限的调用函数就会导致栈区空间被使用完,

从而发生栈溢出的现象,导致程序运行停止

1.1递归的思想

将一个大问题细分为一个个子问题,直到子问题不可拆分为止就是递归的思想。

递归就是将大事化小的过程。

递,就是递推;归,就是回归。

1.2.递归的书写条件

(1)递归存在限制条件,当条件满足时,递归便不再继续

(2)每次递归调用之后,越来越接近这个限制条件

2.举例

2.1阶乘

我们知道,n! = n * (n-1) * (n-2) * (n-3) * ……* 2 * 1

又注意到,2! = 2 * 1!  ||   3! = 3 * 2! || 4! = 4 * 3!

所以 n! = n * (n -1)!

int Fact1(int n)
{if (n == 0)return 1;else return n * Fact1(n - 1);
}

当 n = 3 时

Fact1(3) = 3*Fact1(2) 

Fact1(2)  = 2*Fact1(1) 

Fact1(1) = 1*Fact1(0) 

Fact1(0)  = 1

先是递推,每次函数调用之后,接近 n 等于 0 这个限制条件

然后回归

Fact1(0)  = 1

Fact1(1) = 1*Fact1(0) = 1

Fact1(2)  = 2*Fact1(1)  = 2

Fact1(3) = 3*Fact1(2)  = 6

2.2顺序打印整数的每一位

运用递归时,我们要相信我们所创建的函数能够完成相应的任务

例如,顺序打印 123 中的每一位

void Print1(int n)
{if (n > 9)Print1(n / 10);printf("%d ", n % 10);
}

 

在上面的代码实现中:

Print(123)中 123 > 9 所以 先调用函数Print(123/10)打印 12 再打印3

Print(123 / 10)中 12 > 9 所以 先调用函数Print(12/10)打印 1 再打印2,

Print(12 / 10)中 1  < 9 开始 打印 1,函数Print(12 / 10)调用完毕

然后返回函数Print(123 / 10)打印 2, 再返回函数Print(123)打印3

Print(123)  -> Print(123 / 10) -> Print(12 / 10)

这是递推, 将 大问题转化位 小问题, 只打印个位数

Print(12 / 10)  - > Print(123 / 10)  -> Print(123)

这是回归 ,因为只有函数调用任务实现后,才会继续后面的操作

2.3斐波那契数列

1,1,2,3,5,8,13,21,34........

第一二个数为1,其余的数等于前两个数相加,就是斐波那契数列的规律

代码实现:

int Fib(int n)
{if (n < 3)return 1;else return Fib(n - 1) + Fib(n - 2);
}

例如 n = 4

Fib(4) = Fib(3) + Fib(2)

Fib(3) = Fib(2) + Fib(1)

Fib(2) = 1

这是递推,然后回归

Fib(3) = 1 +Fib(1)

Fib(1) = 1

所以Fib(3) = 1+ 1 = 2

继续回归

Fib(4) = 2 + Fib(2)

Fib(2) = 1

Fib(4) =  2 +1 = 3

注意:只用当前一个Fib函数调用完毕后才会调用后面的Fib函数

 

3.递归与迭代

上述例子用递归的思想实现时,代码较为简洁

但不可避免的是,如果递归的层次太深,栈溢出的现象就不可避免

所谓层次太深,就是说许多函数被调用后,未被销毁,依然占据着栈区的部分内存

最终导致栈区空间被使用完,出现栈溢出的现象

 

 

虽然存在限制条件 n > 10000 但是 3988次调用之后,程序就自动停止了 ,

因为递归层次太深,出现了栈溢出的现象

注意到,Fib函数虽然被调用了很多次,但是却没有出现栈溢出的现象

这是因为Fib(40)最深只会调用40次,然后就会被销毁,再继续后面的调用 

..........................................................................................................................................

注意到,Fib(40)重复调用的Fib函数太多,运行效率非常低

此时就可以采用迭代的方法实现斐波那契数列。

循环是一种迭代,迭代不仅仅是循环

int Fact2(int n)
{int a = 1;//前两个数int b = 1;//前一个数int c = 1;//当前的数//当n 小于等于 2时
//直接返回c 为 1
//当n 大于 2时
//1 + 1 = 2  1+ 2 = 3 2+ 3 = 5
//第n个数需要迭代n-2次for (int i = 0; i < n - 2; ++i){c = a + b;a = b;b = c;}return c;}

运行一下就知道,迭代实现斐波那契数列比递归更快!

但是解决实际问题时

递归比较好想,如果能保证不会出现栈溢出等问题就可优先考虑使用递归

其次是迭代

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

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

相关文章

【PCIe 总线及设备入门学习专栏 6.1 -- PCIe MCTP】

文章目录 1 什么是 MCTP?2 MCTP 消息在 PCIe 中的传输特点3 PCIe MCTP 的局限性(1) 出站(Outbound)MCTP 消息分解的限制(2) 入站(Inbound)MCTP 消息组装的限制4 MCTP 消息的实际使用流程发送端处理流程接收端处理流程5 实际使用场景例 1:管理命令传输例 2:监控数据报告例…

Text2Sql:开启自然语言与数据库交互新时代(30/30)

一、Text2Sql 简介 在当今数字化时代&#xff0c;数据处理和分析的需求日益增长。对于众多非技术专业人员而言&#xff0c;数据库操作的复杂性常常成为他们获取所需信息的障碍。而 Text2Sql 技术的出现&#xff0c;为这一问题提供了有效的解决方案。 Text2Sql&#xff0c;即文…

OneFlow的简单介绍

OneFlow 是北京一流科技有限公司旗下的采用全新架构设计的开源工业级通用深度学习框架。以下是关于 OneFlow 的详细介绍&#xff1a; 本篇文章的目录 特点 功能 应用场景 发展历程 特点 简洁易用的接口&#xff1a;为深度学习相关的算法工程师提供一套简洁易用的用户接口…

【机器学习实战入门项目】MNIST数字分类机器学习项目

Python 深度学习项目&#xff1a;手写数字识别 为了使机器更加智能&#xff0c;开发者们正在深入研究机器学习和深度学习技术。人类通过不断练习和重复来学习执行某项任务&#xff0c;从而记住如何完成这些任务。然后&#xff0c;大脑中的神经元会自动触发&#xff0c;他们能够…

[创业之路-255]:《华为数字化转型之道》-1-主要章节、核心内容、核心思想

目录 前言&#xff1a;数字化转型对于企业而言&#xff0c;是一种全方位的变革 一、主要章节 1、认知篇&#xff08;第1~2章&#xff09;- Why 2、方法篇&#xff08;第3~5章&#xff09;- How 3、实践篇&#xff08;第6~10章&#xff09;- 实践 4、平台篇&#xff08;第…

快速入门:如何注册并使用GPT

文章目录 ProtonMail邮箱步骤 1&#xff1a;访问Proton官网步骤 2&#xff1a;创建ProtonMail账户步骤 3&#xff1a;选择注册免费账户步骤 4&#xff1a;填写邮箱地址和手机号&#xff08;可选&#xff09;步骤 5&#xff1a;邮箱验证&#xff08;必须进行验证&#xff09;步骤…

C# 给定欧氏平面中的一组线可以形成的三角形的数量

给定欧氏平面中的一组线可以形成的三角形的数量(Number of Triangles that can be formed given a set of lines in Euclidean Plane) 给定欧氏平面上的 n 条不同直线的集合 L {l 1 , l 2 , ………, l n }。第i 条直线由形式为 a i x b i y c i的方程给出。求出可以使用集合…

从CRUD到高级功能:EF Core在.NET Core中全面应用(三)

目录 IQueryable使用 原生SQL使用 实体状态跟踪 全局查询筛选器 并发控制使用 IQueryable使用 在EFCore中IQueryable是一个接口用于表示可查询的集合&#xff0c;它继承自IEnumerable但具有一些关键的区别&#xff0c;使得它在处理数据库查询时非常有用&#xff0c;普通集…

淘宝关键词页面爬取绘图进行数据分析

对爬虫、逆向感兴趣的同学可以查看文章&#xff0c;一对一小班V教学&#xff1a;https://blog.csdn.net/weixin_35770067/article/details/142514698 关键词页面爬取代码 from DrissionPage import WebPage, ChromiumOptions from DataRecorder import Recorder import time …

【C++提高篇】—— C++泛型编程之模板基本语法和使用的详解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、模板的概念二、函数模板2.1 函数模板的使用2.2 函数模板注意事项2.3 普通函数与函数模板的区别2.4 普通函数与函数模板的调用规则2.5 模板的局限性 三、类模…

用JAVA写算法之输入输出篇

本系列适合原来用C语言或其他语言写算法&#xff0c;但是因为找工作或比赛的原因改用JAVA语言写算法的同学。当然也同样适合初学算法&#xff0c;想用JAVA来写算法题的同学。 常规方法&#xff1a;使用Scanner类和System.out 这种方法适用于leetcode&#xff0c;以及一些面试手…

uniapp中h5的微应用解决办法

考虑过用wujie&#xff0c;参考官网Vue组件封装 | 无界的教程&#xff0c;虽然没报错&#xff0c;但是子应用的vue节点根本没挂载上&#xff0c;不知道什么原因&#xff0c;如下图所示 后面采用iframe方式将子应用导入进来&#xff1a; 父应用&#xff1a; <template>&…

数据分析及应用:经营分析中的综合指标解析与应用

目录 1. 市场份额(Market Share) 2. 客户获取成本(Customer Acquisition Cost, CAC) 3. 客户生命周期价值(Customer Lifetime Value, CLV) 4. 客户留存率(Customer Retention Rate, CRR) 5. 净推荐值(Net Promoter Score, NPS) 6. 转化率(Conversion Rate) …

【大数据】Flink + Kafka 实现通用流式数据处理详解

目录 一、前言 二、流式数据处理场景介绍 2.1 流式数据处理概述 2.1.1 流式数据处理场景介绍 2.2 流式数据处理技术栈 2.2.1 数据采集 2.2.2 数据处理 2.2.3 数据存储 2.2.4 数据展示 2.3 流式数据处理场景面临的问题和挑战 三、通用的流式数据处理场景解决方案 3.1…

【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活

&#x1f4ac; 欢迎讨论&#xff1a;如对文章内容有疑问或见解&#xff0c;欢迎在评论区留言&#xff0c;我需要您的帮助&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;如果这篇文章对您有所帮助&#xff0c;请不吝点赞、收藏或分享&#xff0c;谢谢您的支持&#x…

JAVA-Exploit编写(7)--http-request库文件上传使用续篇

目录 1.http-request简介 2. 依赖导入 3.靶场实战 3.1 简单使用 3.2 增加判断机制 3.3 文件上传成功后的利用 3.4 正则匹配上传文件的返回的路径 1.http-request简介 http-request 是一个库 里面提供很多方法&#xff0c;使得很容易就可以构造http请求,相比于之前使用的…

抖音小程序一键获取手机号

前端代码组件 <button v-if"!isFromOrderList"class"get-phone-btn" open-type"getPhoneNumber"getphonenumber"onGetPhoneNumber">一键获取</button>// 获取手机号回调onGetPhoneNumber(e) {var that this tt.login({f…

NavVis手持激光扫描帮助舍弗勒快速打造“数字孪生”工厂-沪敖3D

在全球拥有近100家工厂的舍弗勒&#xff0c;从2016年开启数字化运营进程&#xff0c;而当前制造、库存、劳动力和物流的数字化&#xff0c;已无法支持其进一步简化工作流程&#xff0c;亟需数字化物理制造环境&#xff0c;打造“数字孪生”工厂。 NavVis为其提供NavVis VLX 3…

2024年博客之星主题创作|Android 开发:前沿技术、跨领域融合与就业技能展望

目录 引言 一、推动 Android 应用创新的核心力量 1.1 人工智能与机器学习的崛起 1.2 增强现实&#xff08;AR&#xff09;与虚拟现实&#xff08;VR&#xff09;的应用扩展 1.3 5G技术的推动 1.4 跨平台开发技术的成熟 1.4.1 React Native 1.4.2 Flutter 1.4.3 Taro …

云原生周刊:K8s 生产环境架构设计及成本分析

开源项目推荐 KubeZoneNet KubeZoneNet 旨在帮助监控和优化 Kubernetes 集群中的跨可用区&#xff08;Cross-Zone&#xff09;网络流量。这个项目提供了一种简便的方式来跟踪和分析 Kubernetes 集群中跨不同可用区的通信&#xff0c;帮助用户优化集群的网络架构、提高资源利用…