你知道如何使用C语言实现递归吗?

news2024/11/28 12:38:01

本篇博客会讲解如何使用C语言实现递归,以及2个注意事项。
在这里插入图片描述

递归是什么

递归,简单来说,就是自己调用自己。C语言中,可以使用函数来实现递归,也就是让一个函数自己调用自己。举一个简单的例子:

请你求斐波那契数量的第n项。所谓斐波那契数列,即前2项是1,从第3项开始,每一项都是前2项的和。也就是:1 1 2 3 5 8 13 21 34 55…

分析一下:假设有一个函数int Fib(int n);,当n <= 2时,函数返回1,否则返回Fib(n-1) + Fib(n-2),这就是自己调用自己的最直观、最简单的例子了。

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

如何实现递归

实现递归,需要有“大事化小小事化了”的思路。举个例子:请使用递归打印一个整数的每一位。假设这个函数是void Print(int n);,当n为1234时,会打印1 2 3 4

打印n是一个“大事”,我们可以把它拆分成“小事”。显然,最后一位是最容易打印的,也就是说,1234中的4是最容易打印的,直接1234%10即可,那问题就转换成了先打印123的每一位,再打印4。而123=1234/10

经过我们的分析,打印n其实就2步:

  1. 打印n/10的每一位。
  2. 打印n%10。

如果你这么想,那你还忽略了一点:如果是一位数,比如3,就不需要第一步了,直接进行第二步。换句话说,只有2位数以上才需要第一步。代码实现如下:

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

当我们调用Print(1234)时,输出结果如下:
在这里插入图片描述

递归的调用逻辑

递归是自己调用自己的。我们还是用“打印一个整数的每一位”为例。假设Print(1234);,会发生什么呢?

首先会调用一次Print函数,Print函数再调用Print函数:
在这里插入图片描述
Print函数再调用Print函数:
在这里插入图片描述
Print函数再调用Print函数:
在这里插入图片描述
总算不用继续调用了。此时打印1,返回到上一层:
在这里插入图片描述
打印2,返回上一层:
在这里插入图片描述
打印3,返回上一层:
在这里插入图片描述
最后打印4,返回。

在这里插入图片描述
以上就是整体调用的逻辑。红色的线表示继续调用新的Print函数,即“递推”;紫色的线代表返回到上一层,即“回归”。“递推”和“回归”合称“递归”。

递归的注意事项

函数调用是需要开辟栈帧的,如果无限制的调用下去,栈空间会被耗干,就出现了“栈溢出”现象。为了防止这种情况,递归时需要注意以下2点:

  1. 需要一个限制条件,当不满足这个限制条件时,递归不再继续。
  2. 不断接近这个限制条件。

还是“打印一个整数的每一位”这个例子。可以发现,当满足n>=10时,才会递归调用Print(n/10),这就是递归的限制条件。如果没有这个条件,就会无限递归下去,出现“栈溢出”的错误。

由于每次递归调用都是Print(n/10)n/10之后会接近n>=10这个条件,直到n变成一位数,不满足这个限制条件,递归结束。

注意,以上的2个注意事项只是递归的“必要条件”,而不是“充要条件”。也就是说,满足这2个注意事项,你写的递归函数不一定对,但不满足这2个注意事项的话,你写的递归函数一定是错误的。

递归的优缺点

优点:

  1. 递归可以用少量的代码实现大量重复的计算,代码较为简洁。
  2. 有一些场景非常适合使用递归实现,比如数据结构中的树形结构,基本上都要使用递归来实现各种功能。

缺点:

  1. 当递归的深度太深的时候,会出现“栈溢出”的错误。
  2. 某些场景下,递归的重复计算太多,会导致时间复杂度也偏高。

这里强调一下最后一点,即“递归会增加时间复杂度”。以“求斐波那契数列的第n项”为例,也就是本篇博客开头举的例子,大家可以在自己电脑上测一下,当n是50多的时候,算的会非常慢。这是因为,递归调用时,会有大量重复的计算,整体是一个类似二叉树的结构,时间复杂度为O(2N)。比如计算Fib(50):

  1. Fib(50)会调用Fib(49)和Fib(48)。
  2. Fib(49)调用Fib(48)和Fib(47),Fib(48)调用Fib(47)和Fib(46)。
  3. Fib(48)调用Fib(47)和Fib(46),Fib(47)调用Fib(46)和Fib(45),Fib(47)调用Fib(46)和Fib(45),Fib(46)调用Fib(45)和Fib(44)……

这要是一直调用下去,耗时将以“指数爆炸”的形式增长,程序的时间复杂度太高,效率太低。

所以,递归并不适用于所有情况,一定要在不太影响效率的前提下使用。

总结

  1. 递归就是自己调用自己,实现思路是大事化小小事化了。
  2. 递归是“递推”和“回归”的合称,会先向深处递推,再回归。
  3. 递归需要注意,必须在满足某个限制条件时才继续递归,且每次递归要更加接近这个限制条件。
  4. 递归深度太深,会导致栈溢出。
  5. 递归有可能增加时间复杂度,导致程序效率太低。只有在不过多影响效率的前提下,才推荐使用递归。

感谢大家的阅读!

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

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

相关文章

微服务---分布式事务Seata(XA,AT,TCC,SAGA模式基本使用)

分布式事务 1.分布式事务问题 1.1.本地事务 本地事务&#xff0c;也就是传统的单机事务。在传统数据库事务中&#xff0c;必须要满足四个原则&#xff1a; 1.2.分布式事务 分布式事务&#xff0c;就是指不是在单个服务或单个数据库架构下&#xff0c;产生的事务&#xff0c…

开发中不可轻视的接口文档

接口文档是描述如何与软件系统中的特定接口进行交互的文档&#xff0c;通常包含接口的名称、描述、请求和响应的格式、参数、返回值、错误码、调用示例等信息。它是开发人员在设计和开发软件系统时必不可少的参考资料。 日常工作中&#xff0c;运用接口文档最多的是前后端的同…

提高效率:使用这些工具,让你开发和学习更简单

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; 目录 零、ChatGPT一、代码1.代码备忘清单2.菜鸟教程3.代码转图片4.代码在线运行5.LaTeX 公式编辑器6.GitCode、GitHub 等代码仓库平台 二、绘图1.Canva 可画2.Echarts Js画图3.算法可视化4.函数绘图5.遇到 Alt 截不…

236:vue+openlayers输入经纬度坐标,校验并在地图上标记点,enter提交

第236个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers中输入坐标点,在地图上显示点图形。这里面校验了输入的经纬度坐标,同时使用了@keyup.enter.native来做提交处理。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文章目录 示例效果…

第七章SpingMVC

1.MVC模式 视图&#xff08;View&#xff09;-对应组件&#xff1a;JSP或者HTML文件 控制器&#xff08;Controller&#xff09;-对应组件&#xff1a;Servlet 模型&#xff08;Model&#xff09; -对应组件&#xff1a;JavaBean 2.MVC模式具体说明 JSP&#xff1a;负责生成动态…

python resnet实例,残差网络医学分类,基于resnet医学图像分类任务;医学图像处理实战

一&#xff0c;数据集介绍&#xff1a; 数据预处理&#xff1a; 把数据处理成相同大小&#xff1a; 数据集&#xff1a; PathMNIST:结直肠癌组织学切片&#xff1b;ChestMNIST&#xff1a;胸部CT数据集&#xff0c;来源于NIH-ChestXray14 dataset&#xff1b;DermaMNIST&#…

【刷题之路Ⅱ】LeetCode 138. 复制带随机指针的链表

【刷题之路Ⅱ】LeetCode 138. 复制带随机指针的链表 一、题目描述二、解题难点分析方法——插入拷贝节点2、将拷贝节点插入到原节点的后面3、复制原节点的random到拷贝节点中4、将拷贝节点尾插到新链表中并恢复原链表的结构 一、题目描述 原题连接&#xff1a; 138. 复制带随机…

考研拓展:汇编基础

一.说明 本篇博客是基于考研之计算机组成原理中的程序机器级代码表示进行学习的&#xff0c;并不是从汇编语言这一门单独的课程来学习的&#xff0c;涉及的汇编语言知识多是帮助你学习考研之计算机组成原理中对应的考点。 二.相关寄存器 1.相关寄存器 X86处理器中有8个32位…

【三十天精通Vue 3】第二十天 Vue 3的性能优化详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录 引言一、Vue3 性能优化的概念1.1 为什么需要性能优化1.2 性能优化…

基于dsp+fpga+AD+ENDAC的半导体运动台高速数据采集电路仿真设计(四)

整个调试验证与仿真分析分三个步骤&#xff1a;第一步是进行 PCB 检查及电气特性测试&#xff0c;主 要用来验证硬件设计是否正常工作&#xff1b;第二步进行各子模块功能测试&#xff0c;包括高速光纤串行 通信的稳定性与可靠性测试&#xff0c; A/D 及 D/A 转换特性测…

26从零开始学Java之如何对数组进行排序与二分查找?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 在上一篇文章中&#xff0c;壹哥给大家讲解了数组的扩容、缩容及拷贝方式。接下来在今天的文章中&…

深眸科技|深度学习、3D视觉融入机器视觉系统,实现生产数智化

随着“中国制造2025”战略加速落实&#xff0c;制造业生产线正在加紧向智能化、自动化和数字化转型之路迈进。而人工智能技术的兴起以及边缘算力持续提升的同时&#xff0c;机器视觉及其相关技术也在飞速发展&#xff0c;并不断渗透进工业领域&#xff0c;拓展应用场景的同时&a…

Apache Druid中Kafka配置远程代码执行漏洞(MPS-2023-6623)

漏洞描述 Apache Druid 是一个高性能的数据分析引擎。 Kafka Connect模块曾出现JNDI注入漏洞(CVE-2023-25194)&#xff0c;近期安全研究人员发现Apache Druid由于支持从 Kafka 加载数据的实现满足其利用条件&#xff0c;攻击者可通过修改 Kafka 连接配置属性进行 JNDI 注入攻…

软件架构中间件技术

中间件的定义 其实中间件是属于构件的一种。是一种独立的系统软件或服务程序&#xff0c;可以帮助分布式应用软件在不同技术之间共享资源。 我们把它定性为一类系统软件&#xff0c;比如我们常说的消息中间件&#xff0c;数据库中间件等等都是中间件的一种体现。一般情况都是…

减少 try catch ,可以这样干

软件开发过程中&#xff0c;不可避免的是需要处理各种异常&#xff0c;就我自己来说&#xff0c;至少有一半以上的时间都是在处理各种异常情况&#xff0c;所以代码中就会出现大量的try {...} catch {...} finally {...}代码块&#xff0c;不仅有大量的冗余代码&#xff0c;而且…

d3.js学习笔记①创建html文档

本人之前从未学过HTML、CSS、JavaScript&#xff0c;然而我导是做前端的&#xff0c;要求我必须在三周内掌握d3.js&#xff0c;我只能从0学起并以此记录自己的学习过程。 首先对这三种语言有一个初步的认识&#xff1a;HTML是用于搭建网页框架&#xff0c;CSS是美化网页的&…

软件设计师考试——计算机网络、系统安全分析和设计部分

计算机网路 七层模型 OSI/RM七层模型 网络技术标准与协议 TCP协议 DHCP协议 DNS协议 计算机网络的分类——拓扑结构 按分布范围&#xff1a; 局域网城域网广域网因特网 按拓扑结构&#xff1a; 总线型星型环型 网络规划与设计 逻辑网络设计 物理网络设计 分层设计 IP地址…

VirboxLM-免服务版授权码,快速实现一机一码

一、产品介绍 ​ 授权码是由深盾科技开发的一款软件保护及授权管理产品 ​&#xff0c;一方面要保护软件代码不被逆向&#xff0c;另一方面要控制软件的授权使用。软件用户只需要输入授权码&#xff08;由数字和字母组成的一串字符&#xff09;&#xff0c;激活授权码后即可使…

这年头,谁还在「贩卖」生活方式?

【潮汐商业评论/原创】 “我已经很久没有追寻过品牌购物了”Anna如是说。 如今的Anna对商品的选择往往会考虑性价比以及简洁的外观&#xff0c;去品牌化、简单已经成为其新的生活方式。 日本作者三浦展在《第四消费时代》一书中提到&#xff0c;在第三消费社会&#xff0c;新…

Java版本企业工程项目管理系统平台源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…