C语言—函数递归
一、递归概念
递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。下面举一个例子:
上述就是⼀个简单的递归程序,只不过上⾯的递归只是为了演⽰递归的基本形式,不是为了解决问题,代码最终也会陷⼊死递归,导致栈溢出(Stack overflow)。
递归的思想:把⼀个⼤型复杂问题层层转化为⼀个与原问题相似,但规模较⼩的⼦问题来求解;直到⼦问题不能再被拆分,递归就结束了。所以递归的思考⽅式就是把⼤事化⼩的过程。递归中的递就是递推的意思,归就是回归的意思。
二、递归的限制条件
递归在书写的时候,有2个必要条件:
• 递归存在限制条件,当满⾜这个限制条件的时候,递归便不再继续。
• 每次递归调⽤之后越来越接近这个限制条件。
三、递归举例
(3.1)求n的阶乘
计算n的阶乘(不考虑溢出),n的阶乘就是1~n的数字累积相乘。
(3.1.1)分析和代码实现
首先我们要知道n的阶乘的公式:n! = n ∗ (n − 1)!
例如:
这样的思路就是把⼀个较⼤的问题,转换为⼀个与原问题相似,但规模较⼩的问题来求解的。通过上图继续分析:(假设求4的阶乘)
当n<=1时,n的阶乘是1,其余n的阶乘都是可以通过上述公式进行拆分计算。
因此,n的阶乘的递归公式如下:
那我们就可以写出函数Fact求n的阶乘,假设Fact(n)就是求n的阶乘,那么Fact(n-1)就是求n-1的阶乘,函数如下:
测试:
(3.1.2)画图推演
(3.2)顺序打印一个整数的每一位
输⼊⼀个整数m,按照顺序打印整数的每⼀位。例如:
(3.2.1)分析和代码实现
如果n是⼀位数,n的每⼀位就是n自己。
n是超过1位数的话,就得拆分每⼀位。例如:1234%10就能得到4,然后1234/10得到123,这就相当于去掉了4然后继续对123%10,就得到了3,再除10去掉3,以此类推。不断的 %10 和 \10 操作,直到1234的每⼀位都得到;但是这⾥有个问题就是得到的数字顺序是倒着的。我们发现⼀个数字的最低位是最容易得到的,通过%10就能得到,那我们假设写⼀个函数Print来打印n的每⼀位,如下表⽰:
直到被打印的数字变成⼀位数的时候,就不需要再拆分,递归结束。代码如下:
测试:
在这个解题的过程中,我们就是使⽤了⼤事化⼩的思路(以1234为例)把Print(1234)打印1234每⼀位,拆解为⾸先Print(123)打印123的每⼀位,再打印得到4,Print(123)打印123每⼀位,拆解为⾸先Print(12)打印12的每⼀位,再打印得到的3,直到Print打印的是⼀位数,直接打印就⾏。
(3.2.2)画图推演
以1234每⼀位的打印来推演⼀下。
四、递归和迭代
在C语⾔中每⼀次函数调⽤,都要需要为本次函数调⽤在栈区申请⼀块内存空间来保存函数调⽤期间的各种局部变量的值,这块空间被称为运⾏时堆栈,或者函数栈帧。函数不返回,函数对应的栈帧空间就⼀直占⽤,所以如果函数调⽤中存在递归调⽤的话,每⼀次递归函数调⽤都会开辟属于⾃⼰的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间。所以如果采⽤函数递归的⽅式完成代码,递归层次太深,就会浪费太多的栈帧空间引起栈溢出(stack overflow)的问题。
所以如果不想使⽤递归就得想其他的办法,通常就是迭代的⽅式(通常就是循环的⽅式)。
⽐如:计算n的阶乘。
事实上,我们看到的许多问题是以递归的形式进⾏解释的,这只是因为它⽐⾮递归的形式更加清晰,但是这些问题的迭代实现往往⽐递归实现效率更⾼。
当⼀个问题⾮常复杂,难以使⽤迭代的⽅式实现时,此时递归实现的简洁性便可以补偿它所带来的运⾏时开销。
例如:求第n个斐波那契数
注:斐波那契数列第一项和第二项都是1,后面每一项等于前两项相加。
假设我们写了一个Fib函数求第n个斐波那契数列,那么根据斐波那契数列的性质可以得到以下公式:
看到这公式,我们很容易就能写出递归形式的代码:
测试:
当我们n输⼊为50的时候,需要很⻓时间才能算出结果,这个计算所花费的时间,是我们很难接受的,这也说明递归的写法是⾮常低效的,那是为什么呢?其实递归程序会不断的展开,在展开的过程中,我们很容易就能发现,在递归的过程中会有重复计算,⽽且递归层次越深,冗余计算就会越多。如图:
我们可以写代码统计一下第三个斐波那契数被计算的次数。
这⾥我们看到了,在计算第40个斐波那契数的时候,使⽤递归⽅式,第3个斐波那契数就被重复计算了39088169次,这些计算是⾮常冗余的。所以斐波那契数的计算,使⽤递归是⾮常不明智的,我们就得想迭代的⽅式解决。我们知道斐波那契数的前2个数都1,然后前2个数相加就是第3个数,那么我们从前往后,从⼩到⼤计算就⾏了。代码如下:
解释:我们可以把a看成是第一个斐波那契数,b看成是第二个斐波那契数,c是要求的第n个斐波那契数,因为前两个斐波那契数没有必要求,所以求第三个及之后的斐波那契数需要累加n-2次,所以循环条件是n>2且每次n--。令a = b,b = c,是为了每次进入循环时,a,b分别为第n个斐波那契数的前2项和前1项。
五、拓展问题
青蛙跳台阶
题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。如图所示:
思路:由题可知,当n等于1时,只有一种跳法,当n等于2时,有两种跳法。假设我们写一个climbStairs函数用来求青蛙跳上一个n级台阶有多少种跳法,那么当n大于等于3时,第一次跳有两种情况,如果第一次跳了一步,那么后面的台阶就有climbStairs(n-1)种方法,如果第一次跳了两步,那么后面的台阶就有climbStairs(n-2)种方法。由此我们可以得到公式:
代码为:
测试:
相关文章:

C语言—函数递归
一、递归概念 递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。下面举一个例子: 上述就是⼀个简单的递归程序,只不过上⾯的递归只是为了演⽰递归的基本形式,不是为了解决问题,代码最终…...

结构开发笔记(四):solidworks软件(三):绘制36x36方块摄像头示意体
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/141187797 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...

【机器学习】Caltech-101的基本概念和使用方法以及Caltech-101和ImageNet的联系和区别
引言 Caltech-101数据集是一个广泛用于对象识别任务的数据库,它包含了大约9,000张图像,这些图像来自101个不同的对象类别。每个类别包含的图像数量大约在40到800张之间,大多数类别大约有50张图像。图像的分辨率大致为300200像素 文章目录 引言…...

mysql Ubuntu安装与远程连接配置
一、安装(Ubuntu22环境安装mysql8) 这里使用Xshell链接Ubuntu和mysql windows进行操作,特别提醒:安装之前建议对Ubuntu快照处理备份,避免安装中出错导致Ubuntu崩溃。 查看是否安装的有可以用指令:ps -ef|…...

c语言中比较特殊的输入格式
目录 一.%[ ] 格式说明符 1.基本用法 (1)读取字母字符: (2)读取数字字符: (3)读取所有字符直到遇到空格: (4)读取直到换行符: 2.使用范围和组合: 3.^ 取反操作 4.注意事项 (1). 字符范围的正确表示 (2). 避免字符集中的特殊字符冲突 (3).避免空字符集 (4). 输入长…...

远程命令行控制SSH
第一次接触SSH是ROS小车作为服务端,通过ubuntu电脑客户端访问。因为机器人接键盘和屏幕操作起来不方便,所以使用SSH进行连接,方便对小车的操作。 1.服务端安装 打开终端查看ssh是否安装 sudo service ssh status 如果未安装 sudo apt upd…...

钢铁百科:A572Gr60和SA572Gr60材质分析、A572Gr60和SA572Gr60简介
A572Gr60和SA572Gr60是两种常用的结构钢板,它们在材质、执行标准、化学成分、力学性能、交货状态、应用范围和常用规格方面有所不同。 材质: A572Gr60:属于美国材料与试验协会(ASTM)标准下的A572系列高性能结构钢&…...

一次sql请求,返回分页数据和总条数
日常搬砖,总少不了需要获取分页数据和总行数。 一直以来的实践是编码两次sql请求,分别拉分页数据和totalCount。 最近我在思考: 常规实践为什么不是 在一次sql请求中中执行多次sql查询或多次更新,显而易见的优势: ① 能…...
2.5 pyautogui 实现微信自动回复
第四节:实战微信自动回复 课程目标 学习如何通过pyautogui完成微信自动回复 课程内容 编码实现 import pyautogui as pg import time from pyautogui import ImageNotFoundException import pyperclip from cnocr import CnOcr import random ocr CnOcr() msg…...

观存储历史,论数据未来
数据存储 这几天我反复观看了腾讯云社区的《中国数据库前世今生》纪录片,每次的感受都大相径庭。以下是我在这段时间里对纪录片的两个不同感想,希望感兴趣的小伙伴们也能去观看一番。 一个是关于国产数据库的发展趋势的探讨:https://blog.c…...
linux:对目录的操作
一、对目录操作 1,打开目标目录 2.读取目录,, 3.关闭目录 目录 当文件看,只不过操作函数和操作文件函数不一样。 *1.opendir DIR *opendir(const char *name); 功能:打开一个目录获得一个目录流指针 参数:name:目录名 返回值…...

详解Redis 高可用的方式 Redis Cluster
Redis 高可用方式 Redis 提供了多种高可用性方案,主要包括以下几种方式: 主从复制(Replication) 主从复制是最基本的高可用性方案,通过将数据从一个主节点复制到多个从节点来实现数据的冗余和读写分离。主节点负责所…...
$clog2(1)=0
项目场景: 写ip 时, 使用参数化的方式实现2w1r 时,出现计算读返回index 时,减下溢! 问题描述 verilog中会使用parameter 参数化,例如使用dpth 和$clog2(dpth)addr 。 常见的写法没有什么问题。 module …...

开发学习日记1
用这个系列博客记录下学习开发的一些小收获 git的使用: 说来惭愧,学到了大二,git的使用还是一团糟,记录一下如何使用git进行团队合作开发 当要加入其他人的项目时首先你要创建自己的分支(克隆一下其他分支ÿ…...

孙宇晨领航波场TRON:引领数字资产迈向崭新纪元
在风起云涌的数字资产领域,孙宇晨这个名字始终与创新、突破和引领紧密相连。作为波场TRON的创始人,他不仅是一位远见卓识的领导者,更是推动数字资产迈向新纪元的坚实力量。 自波场TRON诞生以来,孙宇晨便以其敏锐的洞察力…...
python运维(twenty-four day)
一、python基础 1、环境python2、python3 [rootpython ~]# yum list installed | grep python #检查是否有python包 [rootpython ~]# yum list installed | grep epel #检查是否有epel包 [rootpython ~]# yum -y install epel-release [rootpython ~]# yum -y instal…...
Eureka原理实践
1. 简介 1.1. 概述 Eureka是Netflix开源的一个服务注册与发现框架,它在微服务架构中扮演着至关重要的角色。 Eureka由两个核心组件组成: Eureka Server(服务注册中心):负责存储、管理和提供服务实例信息,如服务名、IP地址、端口号等。Eureka Server通常采用集群部署以保…...
Ant-Design-Vue快速上手指南+排坑
1. 简介 1.1. 概述 Ant-Design-Vue是由阿里巴巴开源的一个基于Vue.js框架的企业级UI设计语言。它旨在帮助开发者构建设计优雅、体验流畅的企业级应用。Ant-Design-Vue提供了一系列高质量的Vue组件,包括表单、表格、布局、导航、图标等,可以帮助开发者快速搭建应用程序界面。…...

mysql5.7安装
1.创建一个software文件 2.先下载mysql的repo源 wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm 3安装源包 rpm -ivh mysql-community-release-el7-5.noarch.rpm 可能会报错 改成命令 rpm -ivh mysql-community-release-el7-5.noarch.rpm --nodeps…...

UE开发中的设计模式(三) —— 对象池模式
在FPS游戏中,射击会生成子弹,在命中敌人后子弹会被销毁,那么会导致子弹对象频繁地创建和销毁,会造成运行效率降低且会产生内存碎片问题,而对象池模式可以很好地解决这个问题。 文章目录 问题提出概述问题解决总结 问题…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...