函数递归的介绍

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.rhkb.cn/news/4939.html

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

相关文章

小白爬虫——selenium入门超详细教程

目录 一、selenium简介 二、环境安装 2.1、安装Selenium 2.2、浏览器驱动安装 三、基本操作 3.1、对页面进行操作 3.1.1、初始化webdriver 3.1.2、打开网页 3.1.3、页面操作 3.1.4、页面数据提取 3.1.5、关闭页面 ?3.1.6、综合小案例 3.2、对页面元素进行操作 3…

JDK长期支持版本(LTS)

https://blogs.oracle.com/java/post/the-arrival-of-java-23 jdk长期支持版本&#xff08;LTS&#xff09;&#xff1a;JDK 8、11、17、21&#xff1a;

三格电子——MODBUS TCP 转 CANOpen 协议网关

一、产品概述 1.1 产品用途 SG-TCP-COE-210 网关可以实现将 CANOpen 接口设备连接到 MODBUS TCP 网络中。用户不需要了解具体的 CANOpen 和 Modbus TCP 协议即可实现将 CANOpen 设备挂载到 MODBUS TCP 接口的 PLC 上&#xff0c;并和 CANOpen 设备进行 数据交互。 1.2 产品…

在离线无管理员权限的情况下为Linux配置oh-my-zsh(zsh+oh my zsh+powerlevel10k)

0. 前言 最近接触到一台离线环境下的Linux&#xff08;CentOS7&#xff09;&#xff0c;自带的终端实在过于丑陋&#xff08;tcsh&#xff09;&#xff0c;但是搜半天改zsh的教程要么要网、要么要管理员权限&#xff0c;奋而自己折腾半天记录于此以作备忘。 所需环境 一台能…

C 语言雏启:擘画代码乾坤,谛观编程奥宇之初瞰

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。* 这一课主要是让大家初步了解C语言&#xff0c;了解我们的开发环境&#xff0c;main函数&#xff0c;库…

Java - WebSocket

一、WebSocket 1.1、WebSocket概念 WebSocket是一种协议&#xff0c;用于在Web应用程序和服务器之间建立实时、双向的通信连接。它通过一个单一的TCP连接提供了持久化连接&#xff0c;这使得Web应用程序可以更加实时地传递数据。WebSocket协议最初由W3C开发&#xff0c;并于2…

C语言内存之旅:从静态到动态的跨越

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 本文目录 引言正文一 动态内存管理的必要性二 动态…

气膜料仓:工业仓储的高效与安全新选择—轻空间

在工业仓储领域&#xff0c;如何实现高效、安全、环保的存储方式成为企业关注的重点。气膜料仓以其独特的无梁无柱设计和智能化功能&#xff0c;为工业仓储带来了全新的解决方案。 空间利用率高&#xff1a;无障碍的大容量仓储 气膜料仓内部无梁无柱&#xff0c;形成了完全开…

Windows FileZila Server共享电脑文件夹 映射21端口外网连接

我有这样一个使用场景&#xff0c;在外部网络环境下&#xff0c;通过手机便捷地读取存储在电脑上的视频文件。比如在外出旅行、出差&#xff0c;身边没有携带电脑&#xff0c;仅依靠手机设备&#xff0c;就能随时获取电脑里存储的各类视频&#xff0c;无论是学习资料视频、工作…

CentOS部署FastDFS+Nginx并实现远程访问本地服务器中文件

文章目录 前言1. 本地搭建FastDFS文件系统 1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址…

2023年江西省职业院校技能大赛网络系统管理赛项(Linux部分样题)

一、Linux项目任务描述 你作为一个Linux的技术工程师,被指派去构建一个公司的内部网络,要为员工提供便捷、安全稳定内外网络服务。你必须在规定的时间内完成要求的任务,并进行充分的测试,确保设备和应用正常运行。任务所有规划都基于Linux操作系统,请根据网络拓扑、基本配…

【Spring】定义的Bean缺少隐式依赖

问题描述 初学 Spring 时&#xff0c;我们往往不能快速转化思维。例如&#xff0c;在程序开发过程中&#xff0c;有时候&#xff0c;一方面我们把一个类定义成 Bean&#xff0c;同时又觉得这个 Bean 的定义除了加了一些 Spring 注解外&#xff0c;并没有什么不同。所以在后续使…

使用Chrome和Selenium实现对Superset等私域网站的截图

最近遇到了一个问题&#xff0c;因为一些原因&#xff0c;我搭建的一个 Superset 的 Report 功能由于节假日期间不好控制邮件的发送&#xff0c;所以急需一个方案来替换掉 Superset 的 Report 功能 首先我们需要 Chrome 浏览器和 Chrome Driver&#xff0c;这是执行数据抓取的…

vulnhub靶场【IA系列】之Tornado

前言 靶机&#xff1a;IA-Tornado&#xff0c;IP地址为192.168.10.11 攻击&#xff1a;kali&#xff0c;IP地址为192.168.10.2 都采用虚拟机&#xff0c;网卡为桥接模式 本文所用靶场、kali镜像以及相关工具&#xff0c;我放置在网盘中&#xff0c;可以复制后面链接查看 htt…

不用编程即可实现多台PLC的MQTT协议JSON文件发布与订阅的智能网关的配置说明

IGT-SER系列智能网关支持各种PLC的以太网和串口协议&#xff0c;以及Modbus、OPC通讯&#xff0c;通过网关所带的参数配置工具软件&#xff0c;不用编程&#xff0c;即可打包和解析JSON格式的设备数据&#xff0c;通过MQTT、HTTP等协议发布和订阅。相关案例 IGT-SER系列智能网关…

为什么相关性不是因果关系?人工智能中的因果推理探秘

目录 一、背景 &#xff08;一&#xff09;聚焦当下人工智能 &#xff08;二&#xff09;基于关联框架的人工智能 &#xff08;三&#xff09;基于因果框架的人工智能 二、因果推理的基本理论 &#xff08;一&#xff09;因果推理基本范式&#xff1a;因果模型&#xff0…

ARCGIS国土超级工具集1.3更新说明

ARCGIS国土超级工具集V1.3版本&#xff0c;功能已增加至49 个。在V1.2的基础上修复了若干使用时发现的BUG&#xff0c;完善了部分已有的功能&#xff0c;新增了“面要素狭长面检测分割”等功能&#xff0c;新工具使用说明如下&#xff1a; 一、勘测定界工具栏更新土地分类面积表…

阿里云 Serverless 助力盟主直播:高并发下的稳定性和成本优化

在直播场景中&#xff0c;阿里云 Serverless 应用引擎 SAE 提供的无缝弹性伸缩与极速部署能力&#xff0c;确保直播间高并发时的流畅体验&#xff0c;降低了我们的运营成本&#xff0c;简化了运维流程。结合阿里云云原生数据库 PolarDB 的 Serverless 能力&#xff0c;实现了数…

网络编程 | UDP组播通信

1、什么是组播 在上一篇博客中&#xff0c;对UDP的广播通信进行了由浅入深的总结梳理&#xff0c;本文继续对UDP的知识体系进行探讨&#xff0c;旨在将UDP的组播通信由浅入深的讲解清楚。 组播是介于单播与广播之间&#xff0c;在一个局域网内&#xff0c;将某些主机添加到组中…

日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件

日历热力图&#xff0c;月度数据可视化图表&#xff0c;vue组件 先看效果&#x1f447; 在线体验https://www.guetzjb.cn/calanderViewGraph/ 日历图简单划分为近一年时间&#xff0c;开始时间是 上一年的今天&#xff0c;例如2024/01/01 —— 2025/01/01&#xff0c;跨度刚…