爱上C语言:函数递归,青蛙跳台阶图文详解
🚀 作者:阿辉不一般
🚀 你说呢:生活本来沉闷,但跑起来就有风
🚀 专栏:爱上C语言
🚀作图工具:draw.io(免费开源的作图网站)
如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主,如有不足还请指点,博主及时改正,感谢大家支持!!!
文章目录
- 🚀前言
- 🚀什么是函数递归?
- 🚀函数递归的必要条件
- 🚀 用递归求n的阶乘
- 🚀青蛙跳台阶问题(斐波那契数列)
- 🚀什么是栈溢出?
🚀前言
大家好啊😉!今天阿辉将为大家介绍C语言中的函数的递归,✍包括什么是函数递归,函数递归的必要条件,青蛙跳台阶问题(斐波那契数列)以及栈溢出问题,内容干货满满😋,接下来就跟着阿辉一起学习吧👊
🚀什么是函数递归?
函数递归:简单来说就是函数自己调自己。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明
中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与
原问题相似的规模较小的问题来求解递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了
程序、的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递
归需要、有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当
边界条件满足时,递归返回。
🚀函数递归的必要条件
- 递归存在限制条件,当满足限制条件时函数便不再不在递归下去了
- 每一次递归后都会逐渐接近这个限制条件
这两个条件是必要的,否则将陷入死递归
我们来看个例子👇
#include<stdio.h>int main()
{printf("hallo c !\n");main();return 0;
}
上面这段代码你在VS上调试的话就会报错
栈溢出是什么?别急后面会讲,我们接着看👊
🚀 用递归求n的阶乘
5! = 5*4*3*2*1 4! = 4*3*2*1
3! = 3*2*1 2! = 2*1
1! = 1 0! = 1
我们看出求 5!可以变成求 5*4!
而4! = 4*3! 3! = 3*2! 2! = 2*1!
以此类推由上图我们把青蛙跳台阶抽象成下面这个模型👇
把n的阶乘记作Fac(n)
由上图我们可以写出n的阶乘的函数递归代码
int Fac(int n)
{if (n < 2)return 1;elsereturn n * Fac(n - 1);
}
int main()
{int n = 0;scanf("%d", &n);int a = Fac(n);printf("%d\n", a);return 0;
}
🚀青蛙跳台阶问题(斐波那契数列)
一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法
上图我们可知,青蛙跳n次台阶的跳法可以分成:青蛙跳(n - 1)次台阶的跳法加上青蛙跳(n - 2)次台阶的跳法
而青蛙跳(n - 1)次台阶的跳法又可以分成:青蛙跳(n - 2)次台阶的跳法加上青蛙跳(n - 3)次台阶的跳法
…
以此类推由上图我们把青蛙跳台阶抽象成下面这个模型👇
把青蛙跳n次台阶的次数记作Fib(n)
上图其实也就是斐波那契数列得到的方法,只不过斐波那契数列前两个数都是1
由上图我们可以写出青蛙跳台阶的函数递归代码
#include<stdio.h>
int Fib(int n)
{if (n < 3)return n;elsereturn Fib(n - 1) + Fib(n - 2);
}
int main()
{int n = 0;scanf("%d", &n);int a = Fib(n);printf("%d\n", a);return 0;
}
虽然递归能以很少的代码量解决复杂的问题,但是如果递归程度太深,递归次数太多将导致效率低下,甚至栈溢出
上述n的阶乘以及青蛙跳台阶都可以用迭代的方式去写,效率更高,利用的栈内存更小
迭代版本n的阶乘以及青蛙跳台阶奉上👊
n的阶乘:
int Fac(int n)
{int i = 0;int ret = 1;for (i = 1; i <= n; i++){ret *= i;}return ret;
}
int main()
{int n = 0;scanf("%d", &n);int a = Fac(n);printf("%d\n", a);return 0;
}
青蛙跳台阶:
int Fib(int n)
{int a = 1;int b = 2;int c = 0;if (n < 3)return n;while (n - 2){c = a + b;a = b;b = c;n--;}return c;
}
int main()
{int n = 0; scanf("%d", &n);int a = Fib(n);printf("%d\n", a);return 0;
}
🚀什么是栈溢出?
栈,又称堆栈,是一种具有一定规则的数据结构,它按照先进后出的原则存储数据,先存的元素放在栈底,后存的元素在栈顶。
栈区存放函数参数以及局部变量等。内存由编译器分配和释放。
那么栈溢出又是什么呢?
栈溢出是指向向栈中写入了超出限定长度的数据,溢出的数据会覆盖栈中其它数据,从而影响程序的运行
而递归每调一次函数都会向栈区申请一块内存空间,如果死递归或者递归层次太深都会导致栈溢出。
SO递归虽好,可不要贪杯啊
到这里,阿辉今天对于C语言函数递归的分享就结束了,希望这篇博客能让大家有所收获, 如果觉得阿辉写得不错的话,记得给个赞呗,你们的支持是我创作的最大动力🌹
相关文章:

爱上C语言:函数递归,青蛙跳台阶图文详解
🚀 作者:阿辉不一般 🚀 你说呢:生活本来沉闷,但跑起来就有风 🚀 专栏:爱上C语言 🚀作图工具:draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话,还请…...

Pycharm 对容器中的 Python 程序断点远程调试
pycharm如何连接远程服务器的docker容器有两种方法: 第一种:pycharm通过ssh连接已在运行中的docker容器 第二种:pycharm连接docker镜像,pycharm运行代码再自动创建容器 本文是第一种方法的教程,第二种请点击以上的链接…...

自动驾驶行业观察之2023上海车展-----车企发展趋势(3)
合资\外资发展 宝马:i7、iX1新车亮相,未来将持续发力电动化、数字化(座舱) 宝马在本次车展重点展示了电动化产品,新发车型为i7 M70L、iX1、及i vision Dee概念车等车型。 • 展示重点:电动化数字化&#…...
day55【动态规划子序列】392.判断子序列 115.不同的子序列
文章目录 392.判断子序列115.不同的子序列 392.判断子序列 题目链接:力扣链接 讲解链接:代码随想录讲解链接 题意:给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不…...
c语言中磁盘文件的分类
#include <stdio.h> /*磁盘文件的分类: * 一个文件通常是磁盘上一段命名的存储区计算机的存储在物理上是二进制的, * 所以物理上所有的磁盘文件本质上都是一样的:以字节为单位进行顺序存储 * 从用户或者操作系统使用的角度(…...
Unity适配微信
使用的是微信开发的插件 GitHub - wechat-miniprogram/minigame-unity-webgl-transform 路径相关: Unity:Application.streamingAssetsPath --> 配置的cdn路径StreamingAssets...
虚拟机本地磁盘在线扩容
背景 虚拟机本地盘对于host物理机来说就是一个LVM卷,虚拟化(libvirt+kvm_qemu)已经支持虚拟机磁盘在线调整,配合物理机lvm管理工具可实现云场景下虚拟机磁盘在线扩容功能。环境检查 (1)虚拟机本地盘信息 <disk type=block device=disk><driver...

ACTIVE_MQ学习
ActiveMq学习①___入门概述https://blog.csdn.net/qq_45905724/article/details/131796502 ActiveMq学习②__安装与控制台https://blog.csdn.net/qq_45905724/article/details/133893214 ActiveMq学习③___Java编码实现ActiveMQ通讯https://blog.csdn.net/qq_45905724/articl…...

【C++初阶】类和对象(上)
【C初阶】类和对象(上) 1.面向对象与面向过程的初步认识2.类的引入3. 类的定义4.类的访问限定符及封装4.1访问限定符4.2封装 5.类的作用域6.类的实例化6.类的对象的大小计算7.类的this指针7.1this指针的引入7.2this指针的一些特性 📃博客主页…...

新版onenet平台安全鉴权的确定与使用
根据onenet官方更新的文档:平台提供开放的API接口,用户可以通过HTTP/HTTPS调用,进行设备管理,数据查询,设备命令交互等操作,在API的基础上,根据自己的个性化需求搭建上层应用。 为提高API访问安…...

容器核心技术-Namespace
一、容器 基于Linux 内核的 Cgroup, Namespace,以及Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术,由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。 1.1 容器主要特性…...
linux写文件如何保证落盘?
3.1.1. sync sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。通常称为 update的系统守护进程会周期性地(一般每隔30秒)调用sync函数。这就保证了定期冲洗内核的块缓冲区。命令 sync也…...

2023 electron最新最简版打包、自动升级详解
这里我将讲解一下从0搭建一个electron最简版架子,以及如何实现打包自动化更新 之前我有写过两篇文章关于electron框架概述以及 常用api的使用,感兴趣的同学可以看看 Electron桌面应用开发 Electron桌面应用开发2 搭建electron 官方文档:ht…...

ConcurrentHashMap是如何实现线程安全的
目录 原理: 初始化数据结构时的线程安全 put 操作时的线程安全 原理: 多段锁cassynchronize 初始化数据结构时的线程安全 在 JDK 1.8 中,初始化 ConcurrentHashMap 的时候这个 Node[] 数组是还未初始化的,会等到第一次 put() 方…...
MYSQL:索引与锁表范围简述
一、聚簇索引原则 当有主键索引时,选择主键索引;如果没有主键索引,选择第一个的unique索引;如果都没有就选择隐藏生成的ROW_ID。 二、加锁原则 来自知乎MySQL探秘(七):InnoDB行锁算法 - 知乎 (zhihu.com) 在不通过索引条件查询时…...

15 款 PDF 编辑器帮助轻松编辑、合并PDF文档
PDF 编辑器在当今的数字环境中至关重要,因为 PDF 已成为共享和存储信息的首选格式。只需几分钟,可靠的 PDF 编辑器即可让用户能够根据其特定需求修改、定制和定制文档。在本文中,我们全面汇编了 15 款最佳免费 PDF 编辑器,让您可以…...

PS Raw中文增效工具Camera Raw 16
Camera Raw 16 for mac(PS Raw增效工具)的功能特色包括强大的图像调整工具。例如,它提供白平衡、曝光、对比度、饱和度等调整选项,帮助用户优化图像的色彩和细节。此外,Camera Raw 16的界面简洁易用,用户可…...
Flink源码解析二之执行计划⽣成
JobManager Leader 选举 首先flink会依据配置获取RecoveryMode,RecoveryMode一共两两种:STANDALONE和ZOOKEEPER。 如果用户配置的是STANDALONE,会直接去配置中获取JobManager的地址如果用户配置的是ZOOKEEPER,flink会首先尝试连接zookeeper,利用zookeeper的leadder选举服务发现…...
MySQL遍历所有表所有字段查找字符数据
MySQL遍历所有表所有字段查找字符数据 工作中有一些数据查找,但是在那个库那个表那个字段中并不明确,特别是敏感字符查找,如果数据量并不大,我们可以采用遍历整个库、表中字符来查找相关数据来解决该问题。 我们可以写一个存储过…...
Java中的异常处理机制是怎样的?
Java中的异常处理机制主要包括以下几个部分: 异常类(Exception Class):Java中的异常类继承自java.lang.Throwable,主要分为两大类:Error和Exception。Error表示程序无法处理的严重问题,如系统崩…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...
ThreadLocal 源码
ThreadLocal 源码 此类提供线程局部变量。这些变量不同于它们的普通对应物,因为每个访问一个线程局部变量的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是类中的私有静态字段,这些类希望将…...

归并排序:分治思想的高效排序
目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...

ArcGIS Pro+ArcGIS给你的地图加上北回归线!
今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等,设置经线、纬线都以10间隔显示。 2、需要插入背会归线…...

【java面试】微服务篇
【java面试】微服务篇 一、总体框架二、Springcloud(一)Springcloud五大组件(二)服务注册和发现1、Eureka2、Nacos (三)负载均衡1、Ribbon负载均衡流程2、Ribbon负载均衡策略3、自定义负载均衡策略4、总结 …...

leetcode_69.x的平方根
题目如下 : 看到题 ,我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历,我们是整数的平方根,所以我们分两…...
【Java】Ajax 技术详解
文章目录 1. Filter 过滤器1.1 Filter 概述1.2 Filter 快速入门开发步骤:1.3 Filter 执行流程1.4 Filter 拦截路径配置1.5 过滤器链2. Listener 监听器2.1 Listener 概述2.2 ServletContextListener3. Ajax 技术3.1 Ajax 概述3.2 Ajax 快速入门服务端实现:客户端实现:4. Axi…...