C语言之递归函数、例题详解以及注意事项


目录

前言

一、递归的概念

二、递归例题详解

例1:斐波那契数列

例2:求次方

例3:求各位数之和

例4:阶乘

例5:顺序打印

三、递归的注意事项

总结


前言

        本文将和大家分享一些递归函数的相关知识,技巧与一些经验,希望对大家有所帮助,递归函数作为一种简洁的解题方法和特别的思维方式,非常值得我们去学习,而这种解题思路不太好想,最重要的还是多加练习,文中将举例一些我做过的递归题目来详细介绍递归,希望对大家有所帮助


一、递归的概念

在C语言中,递归简单来说就是函数自己调用自己,但是函数一味的自己调用自己就可能造成死递归,死递归就会导致栈溢出

如:

Stack overflow 即栈溢出

递归应当避免死递归

递归的中心思想:把一个大型复杂问题层层转化为一个与原问题相似,但规模较小的子问题来求解;直到子问题不能再被拆分,递归就结束了。所以递归的思考方式就是把大事化小的过程

递归递归,递推的意思,回归的意思。

因此,函数递归除了满足函数自己调用自己外,还有两个必要的条件:

  • 递归存在限制条件,当满足这个限制条件的时候,递归便不再继续
  • 每次递归调用之后越来越接近这个限制条件

以下将通过例题深入体会这两个限制条件


二、递归例题详解

例1:斐波那契数列

题目:使用递归实现求第n个斐波那契数列

题目分析:

  • 斐波那契数列:1  1  2  3  5  8  13  21  ...
  • 规律:即从第3位开始,该位数等于前两位数之和

递归分析:

  1. 为了实现递归,我们先找到一个临界条件,也就是递推的终点,回归的起点,该递归函数需要的参数只有n,即第n个斐波那契数列值,我们将函数命名为 Fib(n)
  2. 斐波那契数列只有从第三位开始才有前两项之和等于该项的规律,也就是当n>2时。当n<=2时,函数只需要返回1,
  3. 因此,我们可以设置n<=2为这个临界条件,每次调用该函数时都接近这个条件
  4. 例如,当n=5时,如下图分析:
  5. 下面我们就实现这个代码并验证这个结果:

这就是使用递归实现求斐波那契数列的代码,我们可以对比观察一下不使用递归实现求斐波那契数列的代码:

(注:该方法为,c为前两项之和,a,b分别为前2项和前1项,每次计算完c,就将b赋值给a,c赋值给b,实现逐步向后计算斐波那契数列)

对比发现:递归函数代码量非常少,却能实现一样的效果


例2:求次方

题目:编写一个函数实现n的k次方,使用递归实现。

分析:

  1. 众所周知,实现n的k次方,使用库函数pow即可实现,但现在需要使用递归实现,实现n的k次方,即n*n*n*...  递归函数的参数为n和k,我们将该函数命名为my_pow
  2. 同样,实现递归我们首先需要寻找限制条件,也就是递推与回归的临界条件,条件一般从参数上找,该函数有两个参数,我们先找到最底层的条件,也就是满足该条件时函数一定或应该返回什么。
  3. 不难想到,当k=1时,函数只需要返回n就行,当k不等于1时,我们需要再次调用该函数并接近这个临界条件,所以我们可以写成n*my_pow(n,k-1)
  4. 代码实现如下:
  5. 我们通过画图来理解:
  6. 当k不等于1时,计算n*my_pow(n, k-1),直到k=1,再逐渐返回计算值,这就是整个递归过程


例3:求各位数之和

题目:写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

例如:调用DigitSum(1729),则应该返回1 + 7 + 2 + 9,它的和是19

输入:1729,输出:19

分析:

  1. 该递归函数只有一个参数n,我们需要求每一位上的数之和,就需要得到每一位的数。不难想到,得到一个数的个位数只需要除10取余数就行,也就是%10,而得到十位数只需要先除以10就能消去个位数,再将得到的数%10就能得到十位数
  2. 我们再来确认限制条件,不难先想到最小的值,也就是n只有一位数时,即n<10时,这时候函数只需要返回n就行。当n为多位数时,我们需要先计算尾数,然后再调用该函数计算剩余的每一位数之和,而调用该函数时的参数需消除尾数,直到n仅剩一位数时递推结束
  3. 代码实现如下:
  4. 画图理解:
  5. 每一次递推将结果拆分为尾数+调用函数,直到n<10依次将结果返回


例4:阶乘

题目:递归实现求n的阶乘(不考虑溢出的问题)

分析:

  1. 阶乘:如5! = 5*4*3*2*1,阶乘的概念我们应该很清楚,通过5的阶乘我们可以发现 5! = 5* 4!,所以求5!我们可以转换求5*4!,以此类推下去...,除此之外我们需要知道0! = 1
  2. 因此我们可以将0作为限制条件,当n等于0时,函数返回1即可。当n>0时,函数返回n*(n-1)!即可,直到n等于0,递推结束,我们将函数命名为Factorial
  3. 代码实现如下:
  4. 我们画图分析:
  5. n不等于0时,不断地使n*(n-1),直到n等于0即可逐步返回


例5:顺序打印

题目:递归的方式实现打印整数的每一位数

例如:输入:4321

           输出:4 3 2 1

如果前面四道题全部能理清楚,那么这道题就不在话下了,只需要递归满足两个条件,一:限制条件,二:每次调用越来越接近这个条件即可。大家可以自己试着画图分析并且完成这道题

代码实现:


三、递归的注意事项

  • 关于递归和迭代的选取

        当我们学会递归后是不是发现递归的代码非常简单,并且递归和迭代相似,像一种套娃式的循环,那我们是不是遇到类似的问题就都使用递归呢?

        答案是否定的,递归虽好,却也有着局限

递归的局限性:如果计算数值过大,递归中就会存在大量重复计算,导致计算效率降低

例如我们的第一道例题:求斐波那契数列

假如我们使用递归求第50个斐波那锲数列,我们会发现计算机半天计算不出来

而我们使用迭代的方式发现,虽然计算结果是错的,但计算效率非常高,(结果错误是因为int类型存储大小的限制)

为什么递归半天计算不出结果,我们通过画图来解释:

我们可以发现,单就一个Fib(46)就计算了4次,而且越往下,重复计算就越多

我们可以打印看看求Fib(40),Fib(3)被计算了多少次:

Fib(3)居然被计算了三千多万次,这样大量的重复计算会导致代码效率非常低下

因此对于求斐波那契数列,用迭代的方式效率会高很多

总之,递归虽好,但也不是万能的,要根据实际问题选择是使用递归还是迭代


总结

        以上就是关于递归函数的一些知识,希望对大家有所帮助,感谢支持。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

栈和队列OJ刷题

制作不易&#xff0c;三连支持一下呗&#xff01;&#xff01;&#xff01; 文章目录 一.有效的括号二.用队列实现栈三.用栈实现队列四.设计循环队列 前言 上两篇博客介绍了栈和队列的结构与实现&#xff0c;这篇博客我们将用栈和队列的结构与思想来解决一些oj题目 一、有效的…

关于安装Tensorflow的一些操作及问题解决

关于conda和tensorflow&#xff1a; 由于在安装tensorflow遇到各种问题&#xff0c;遇坑则进&#xff0c;耗费了很多时间。由此想整理一些关于安装tensorflow的操作和方法。欢迎各位补充和指正&#xff01; 1.conda: 1&#xff09;conda list 查看安装了哪些包。 2&#xff…

【实验】根据docker部署nginx并且实现https

环境准备 systemctl stop firewalld setenforce 0 安装docker #安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2 #设置阿里云镜像 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #安装最新版…

LabVIEW鸡蛋品质智能分级系统

LabVIEW鸡蛋品质智能分级系统 随着现代农业技术的飞速发展&#xff0c;精确、高效的农产品质量控制已成为行业的重要需求。其中&#xff0c;鸡蛋作为日常膳食中不可或缺的重要组成部分&#xff0c;其品质直接关系到消费者的健康与满意度。本文设计并实现了一套基于LabVIEW的鸡…

进程控制【Linux】

文章目录 进程终止进程等待 创建一批子进程 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #define N 5void runChild() {int cnt 10;while (cnt ! 0){printf("i am a child : %d , ppid:%d\n", getpid(), getppid());sleep(1);c…

Cisco WLC 2504控制器重启后所有AP掉线故障-系统日期时间

1 故障描述 现场1台WLC 2504控制器掉电重启后&#xff0c;所有AP均无线上线&#xff0c; 正常时共有18个AP在线&#xff0c;而当前为0 AP在线数量为0 (Cisco Controller) >show ap sumNumber of APs.................................... 0Global AP User Name..........…

【AIGC】本地部署 ollama + open-webui

在之前的篇章《【AIGC】本地部署 ollama(gguf) 与项目整合》中我们已经使用 ollama 部署了一个基于预量化&#xff08;gguf&#xff09;的 Qwen1.5 模型&#xff0c;这个模型除了提供研发使用外&#xff0c;我还想提供给公司内部使用&#xff0c;因此还需要一个 ui 交互界面。 …

麦克纳姆轮 Mecanum 小车运动学模型和动力学分析

目录 一、简介 二、运动学模型分析 1. 逆运动学方程 2. 正运动学方程 三、动力学模型 四、广泛运动学模型 一、简介 参考文献https://www.geometrie.tugraz.at/gfrerrer/publications/MecanumWheel.pdf 移动机器人的运动学模型是为了解决小车的正向运动学和逆向运动学问…

springmvc下

第二类初始化操作 multipartResolver应用 localeResolver应用 themeResolver应用 handlerMapping应用 handlerAdapter应用 handlerExceptionReslver requestToViewNameTranslator应用 viewResolver应用 flashMapManager应用 dispatcherServlet逻辑处理 processRequest处理web请…

【Flask 系统教程 5】视图进阶

类视图 在 Flask 中&#xff0c;除了使用函数视图外&#xff0c;你还可以使用类视图来处理请求。类视图提供了一种更为结构化和面向对象的方式来编写视图函数&#xff0c;使得代码组织更清晰&#xff0c;并且提供了更多的灵活性和可扩展性。 创建类视图 要创建一个类视图&am…

Docker高频使用命令

一、Docker常用命令总结 1.镜像命令管理 指令描述ls列出镜像build构建镜像来自Dockerfilehoistory查看历史镜像inspect显示一个或多个镜像的详细信息pull从镜像仓库拉取镜像push推送一个镜像仓库rm移除一个或多个镜像prune一处未使用的镜像&#xff0c;没有被标记或被任何容器…

初始化Linux或者Mac下Docker运行环境

文章目录 1 Mac下安装Docker2 Linux下安装Docker2.1 确定Linux版本2.2 安装Docker2.3 配置加速镜像 3 Docker安装校验4 安装docker-compose4.1 直接下载二进制文件4.2 移动二进制文件到系统路径4.3 设置可执行权限4.4 验证安装 1 Mac下安装Docker mac 安装 docker 还是比较方便…

哥白尼高程Copernicus DEM下载(CSDN_20240505)

哥白尼数字高程模型(Copernicus DEM, COP-DEM)由欧洲航天局(European Space Agency, 简称ESA或欧空局)发布&#xff0c;全球范围免费提供30米和90米分辨率DEM。COP-DEM是数字表面模型(DSM)&#xff0c;它表示地球表面(包括建筑物、基础设施和植被)的高程。COP-DEM是经过编辑的D…

c++set和map

目录 一、set的使用 1、set对象的创建 2、multiset 二、map的使用 1、map对象的创建 2、map的operator[] 序列式容器&#xff1a;vector、list、deque....单纯的存储数据&#xff0c;数据和数据之间没有关联 关联式容器&#xff1a;map、set.....不仅仅是存储数据&#x…

2000-2020年县域创业活跃度数据

2000-2020年县域创业活跃度数据 1、时间&#xff1a;2000-2020年 2、指标&#xff1a;地区名称、年份、行政区划代码、经度、纬度、所属城市、所属省份、年末总人口万人、户籍人口数万人、当年企业注册数目、县域创业活跃度1、县域创业活跃度2、县域创业活跃3 3、来源&#…

python数据可视化:显示两个变量间的关系散点图scatterplot()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 python数据可视化&#xff1a; 显示两个变量间的关系 散点图 scatterplot() [太阳]选择题 请问关于以下代码表述错误的选项是&#xff1f; import seaborn as sns import matplotlib.pyplot …

VISO流程图之子流程的使用

子流程的作用 整个流程图的框图多而且大&#xff0c;进行分块&#xff1b;让流程图简洁对于重复使用的流程&#xff0c;可以归结为一个子流程图&#xff0c;方便使用&#xff0c;避免大量的重复性工作&#xff1b; 新建子流程 方法1&#xff1a; 随便布局 框选3 和4 &#…

SQL:NOT IN与NOT EXISTS不等价

在对SQL语句进行性能优化时&#xff0c;经常用到一个技巧是将IN改写成EXISTS&#xff0c;这是等价改写&#xff0c;并没有什么问题。问题在于&#xff0c;将NOT IN改写成NOT EXISTS时&#xff0c;结果未必一样。 目录 一、举例验证二、三值逻辑简述三、附录&#xff1a;用到的S…

3.3Java全栈开发前端+后端(全栈工程师进阶之路)-前端框架VUE3框架-企业级应用-Vue组合式API

为什么要使用Composition API 一个Options API实例 在前面的课程中&#xff0c;我们都是采用 Options API&#xff08;基于选项的 API &#xff09; 来写一个组件的。下面是一个实例&#xff1a; <template> Count is: {{ count }}, doubleCount is: {{ doubleCount…

深入理解网络原理3----TCP核心特性介绍(上)【面试高频考点】

文章目录 前言TCP协议段格式一、确认应答【保证可靠性传输的机制】二、超时重传【保证可靠性传输的机制】三、连接管理机制【保证可靠性传输的机制】3.1建立连接&#xff08;TCP三次握手&#xff09;---经典面试题3.2断开连接&#xff08;四次挥手&#xff09;3.3TCP状态转换 四…
最新文章