【C语言】函数的递归

目录

一、什么是递归

二、递归的思想

三、递归的限制条件

四、递归中的栈溢出

五、递归举例

(1)例1:n的阶乘

(2)例子2:顺序打印一个数的每一位

六、递归和迭代

七、拓展题目

(1)青蛙跳台阶问题

(2)汉诺塔问题


一、什么是递归

        递归就是函数自己调用自己。下面举一个简单的递归例子(并不能解决问题,用法也不正确,只是让大家感受一下递归是什么样的):

        在打印了很多次后终止了运行,但预期是一直死循环打印下去,为什么会这样?调试看看:

        用F11进行调试,不进入第6行的main();,最后弹出了一个错误,如上图,Stack overflow(栈溢出),出现这个问题的原因在第四节讲。

二、递归的思想

        将一个复杂的问题分解为相似的子问题,子问题再分解为更小的相似子问题,直到子问题不能再分解就结束分解。递归的递,表示递推,就是分解的过程;递归的归,表示回归,结束分解后再一个个返回子问题计算的结果,从小问题的解决到最后整个复杂问题的解决。

三、递归的限制条件

        递归必须有以下两个条件:

  • 递归必须有限制条件,这是递归中递推过程结束的条件。
  • 每一次递归,要离限制条件更近。

四、递归中的栈溢出

        在C语言中每次调用函数,都会向栈区申请一块内存空间,用于存放函数调用期间的各种信息(包括调用函数里局部变量的值等),这块空间被称为 运行时堆栈函数栈帧

        每一次递归都会为调用的函数申请一块栈帧空间,只有函数返回后,才会释放对应的栈帧空间。如果递归太深而不返回,就会导致内存不够,发生栈溢出的问题。

        这也是为什么递归必须要有限制条件的原因。

五、递归举例

(1)例1:n的阶乘

        题目:计算n的阶乘(不考虑溢出,数太大了会发生溢出),n的阶乘就是1~n的数字累积相乘。

        分析:

        Fact(n)是求解n阶乘的递归函数,Fact(n - 1)是求解n - 1阶乘的递归函数,也是求解n阶乘的相似子问题。n等于0时,0的阶乘为1,是该递归函数的限制条件

        代码及运行结果:

        递归过程图(红色是递推过程,蓝色是回归过程,绿色是返回的结果):

(2)例子2:顺序打印一个数的每一位

        题目:输入一个整数m,按照顺序打印m的每一位数。

        如:输入1234,打印1 2 3 4。

        分析:对于数字n,使用n%10可以得到最后一位数。

        9 > m ≥ 0时打印m,就是该递归的限制条件;Fact(m/10)就是相似子问题。这道题中的递归没有返回值,而是把返回值改为了打印数字。因为当m为个位数时,也可以用m%10表示,所有在代码中可以把两个条件下的打印部分统一在一起。

        代码及运行结果:

六、递归和迭代

        递归非常好用,可以把一个复杂的问题,以很简单的代码解决,但是它也有缺陷,在第四节讲的递归太深会造成很大的运行开销(无论是时间还是空间)。所以当一个问题用递归的方法很好解决,但是对于运行时的开销有很大的缺陷,递归的好用已经弥补不了这个缺陷时,就需要用迭代的方法(通常是循环的方式)解决了。

        递归运行开销大这个缺陷,在斐波那契数列这道题中显著体现。

        题目:求第n个斐波那契数。第一、二个数是1,后面的数都是它前两数的和。如:1,1,2,3,5......

        ① 递归的方法:

        分析:

        这道题可以用很简单的递归方法解决。

        代码及运行结果:

        当n较小时,比如10,很快计算出了结果。

        当n较大时,比如50,计算特别慢,等了很久都没有结果出来。大家可以试试。

        讨论一下运行慢的原因:

        简略画一下计算第50个斐波那契数的递归过程图:

        从上面的图可以看到有很多重复(同色)的计算,这个图只是画了一点,全部延伸下去直到遇到1和2才结束递推,可想而知要计算很多很多很多很多次。

        用小点的n = 40做例子,看看计算了多少次Fact(3):

        可以看到仅仅对于比较小的数40,它的Fact(3)就计算了这么多次!

        所以这道题我们不能使用递归的方法,它的运行开销实在太大。改用循环的方法:

        计算n=50,结果立马就运行出来了。注:把a、b、c换成long long类型是因为计算结果太大了,定义为int类型会溢出,看不到正确结果。仔细思考一下,这个计算时间只要50-2=48次循环而已。对比一下,用递归法算n=40,光计算Fact(3)都计算了39088169次。

七、拓展题目

(1)青蛙跳台阶问题

        题目:一只青蛙一次可以跳1个或者2个台阶,请计算它跳n个台阶有几种跳法。

        分析:

        如果跳n个台阶,最后一跳要么是已经跳了n-1个台阶,最后一次跳一个台阶;要么是已经跳了n-2个台阶,最后一次跳两个台阶。Fact(n)表示跳n阶的跳法种数,可以拆分成 “最后跳一个台阶:跳n-1阶的跳法种数Fact(n-1)” 加上 “最后跳两个台阶:跳n-2阶的跳法种数Fact(n-2)”。对于限制条件(因为n=3的时候要算Fact(1)和Fact(2),所以限制条件为n=1和n=2两种情况):跳一个台阶时,只有一种跳法;跳两个台阶时,有两种跳法(跳两次一阶,或者跳一次两阶)。

        代码及运行结果:

(2)汉诺塔问题

        题目:如下图,有ABC三个杆,A杆上有n个盘子,请计算把A杆上的n个盘子全部移到C杆上,需要移动多少次盘子。

        移动规则:

  • 一次只能移一个盘子。
  • 大盘子不能放在小盘子上。
  • 可以以B杆作为中介柱子。

        分析:

        首先,若只有一个盘子,需要移动1次(A>C);若只有两个盘子,需要移动3次(小:A>B,大:A>C,小:B>C)。而n(n>1)个盘子,则可以类比移动两个盘子,看作上面有n-1个盘子和下面有一个盘子。因为最底下那个盘子最大,所以上面n-1个盘子中,随便哪个盘子都可以在它的上面。因此,上面的n-1个盘子移动时,可以把最底下的那个盘子忽略掉。【上面n-1整体:A>B,移动Fact(n-1)次;最大:A>C,移动1次;上面n-1整体:B>C,移动Fact(n-1)次】,加起来就是1+2*Fact(n-1)次。

        为什么不把下面的n-1个作为整体,最小的看作另一个整体呢?如果把最小的看作一部分,下面的n-1个看作一部分,n-1个盘子移动时,就不能忽略掉最小的那个,【最小:A>B,移动1次;n-1整体:A>C,移动Fact(n-1)次;最小:B>C,移动一次】这个想法也就是错误的。因此,不能用Fact(n) = 2 + Fact(n-1)做递归。

        代码及运行结果:

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

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

相关文章

Chainlit一个快速构建成式AI应用的Python框架,无缝集成与多平台部署

概述 Chainlit 是一个开源 Python 包,用于构建和部署生成式 AI 应用的开源框架。它提供了一种简单的方法来创建交互式的用户界面,这些界面可以与 LLM(大型语言模型)驱动的应用程序进行通信。Chainlit 旨在帮助开发者快速构建基于…

如何知道一个字段在selenium中是否可编辑?

这篇文章将检查我们如何使用Java检查selenium webdriver中的字段是否可编辑。 我们如何知道我们是否可以编辑字段?“readonly”属性控制字段的可编辑性。如果元素上存在“readonly”属性,则无法编辑或操作该元素或字段。 因此,如果我们找到一…

强大的开源网络攻击面分析工具:Hetty

Hetty:深入网络的每一个角落,Hetty让安全漏洞无处遁形。- 精选真开源,释放新价值。 概览 Hetty作为一个专为网络攻击面分析而设计的开源HTTP/1.1客户端,其设计初衷是为了帮助安全研究人员和渗透测试人员深入挖掘潜在的网络漏洞。…

[网鼎杯 2020 朱雀组]Nmap(详细解读版)

这道题考察nmap的一些用法,以及escapeshellarg和escapeshellcmd两个函数的绕过,可以看这里PHP escapeshellarg()escapeshellcmd() 之殇 (seebug.org) 两种解题方法: 第一种通过nmap的-iL参数读取扫描一个文件到指定文件中第二种是利用nmap的参数写入we…

NTC测温

前言 假设已知ad-温度转换表ad_table[100]; 数组元素ad_table[0] ~ ad_table[99] 对应温度0 ~ 99℃;已知MCU检测到NTC两端电压ad值位temp_ad,请写出将temp_ad转换成温度值的程序代码,要求温度值精确到0.1℃ 代码 为了将AD值转换为精确到0.1℃的温度值…

AMQP-核心概念-5

本文参考以下链接摘录翻译: https://www.rabbitmq.com/tutorials/amqp-concepts 消息确认(Message Acknowledgements) 消费者应用,就是接收和处理消息的应用。它们偶尔会处理个别消息失败,断开与服务器之间的连接或许…

数据库基础--概念模型

文章目录 概念模型回顾概念结构设计基本概念概念模型中的几个基本概念联系——实体集之间的对应关系讨论:怎样寻找信息世界中的实体和联系?实体和联系的举例概念模型的设计概念模型的设计方法与步骤概念结构设计步骤合并E-R图时的冲突解决方法练习&#…

二叉树习题leetcode 572. 另一棵树的子树

题目链接:572. 另一棵树的子树 二叉树遍历综合问题 题意 给定两棵树,判断第二棵树是否为第一颗树的子树。 思路 用到了100. 相同的树 的思路,把给定的二叉树,每个节点都和subRoot都做一次相同的树的比较,只要正确&…

Llama + Dify,在你的电脑搭建一套AI工作流

theme: smartblue 点赞 关注 收藏 学会了 本文简介 最近字节在推Coze,你可以在这个平台制作知识库、制作工作流,生成一个具有特定领域知识的智能体。 那么,有没有可能在本地也部署一套这个东西呢?这样敏感数据就不会泄露了&…

使用两台虚拟机分别部署前端和后端项目

使用两台虚拟机分别部署前端和后端项目 1 部署方案2 准备两台虚拟机,并配置网络环境3 部署后端项目3.1 打包服务3.2 上传jar包到服务器3.3 集成Systemd3.3.1 移动端服务集成Systemd3.3.2 后台管理系统集成Systemd 4 配置域名映射5 部署前端项目5.1 移动端5.1.1 打包…

Kettle下载安装

环境说明 虚拟机:Win7;MySql8.0 主机:Win11;JDK1.8;Kettle 9.4(Pentaho Data Integration 9.4)(下载方式见文末) 安装说明 【1】解压后运行Spoon.bat 【2】将jar包 复…

DjangoRF-6-项目模块projects模型

首先,这是个新模块,在apps下创建projects 1.1、django-admin startapp projects 1.2进行注册 ‘apps.projects.apps.ProjectsConfig’ 进行接口编写的过程中,落入数据库的字段相同的有很多我们要在utils文件下进行闯进模型鸡肋 from django…

【黑科技】:Laravel 项目性能提升 20 倍

令人激动的黑科技:Laravel 项目性能提升 20 倍 这个项目能够在无需修改任何代码且无需第三方扩展的前提下,将你的 Laravel 项目性能提高 20 倍。它仅依赖于 PHP 原生的 pcntl、posix、fiber 和 sockets。 项目灵感 起因是看到官方发布的 PHP 8.1 更新…

【教学类-70-01】20240728一个茶壶两个茶杯(果茶)

‘ 背景需求: 用通义万相下载简笔画茶壶、茶杯 茶杯,简单笔画,卡通,黑白,未着色,幼儿插图,线条画,没有背景,没有颜色,黑白漫画线条艺术:,空背景…

【全国大学生电子设计竞赛】2022年B题

🥰🥰全国大学生电子设计大赛学习资料专栏已开启,限时免费,速速收藏~

Hakuin:一款自动化SQL盲注(BSQLI)安全检测工具

关于Hakuin Hakuin是一款功能强大的SQL盲注漏洞安全检测工具,该工具专门针对BSQLi设计,可以帮助广大研究人员优化BSQLi测试用例,并以自动化的形式完成针对目标Web应用程序的漏洞扫描与检测任务。 该工具允许用户以轻松高效的形式对目标Web应…

基于Python的宿舍管理系统/基于Spring Boot的学生宿舍管理系统/计算机专业/课设

摘要 宿舍管理系统是一种基于计算机技术的管理工具,旨在提高学生宿舍管理的效率、准确性和安全性。随着高校规模的不断扩大和学生数量的增加,宿舍管理工作变得愈发复杂,传统的手工管理已经无法满足需求。因此,开发宿舍管理系统已…

Greenplum的诞生与成长过程

Greenplum 成立与早期发展 Greenplum的诞生于早起发展 Greenplum于2003年在美国硅谷成立,在2006年发布了基于PostgreSQL(8.x)的MPP数据库产品,作为与公司同名的MPP数据库,专为分析和管理海量数据集而设计,支持复杂的数据分析和商…

大语言模型系列-Transformer:深入探索与未来展望

大家好,我是一名测试开发工程师,已经开源一套【自动化测试框架】和【测试管理平台】,欢迎大家联系我,一起【分享测试知识,交流测试技术】 Transformer模型自其问世以来,便迅速在自然语言处理领域崭露头角&a…

synchronized锁解析+synchronized锁的膨胀过程

目录 synchronized锁(具体详解) synchronized锁具体的三种形式: synchronized锁的实现原理是什么? 类锁和对象锁(面试重点) 锁的升级与对比(synchronized锁的膨胀 面试重点) 偏…