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.mzph.cn/web/6607.shtml

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

相关文章

EPAI手绘建模APP颜色、贴图、材质、样式

⑦ 颜色选择页面 1) 颜色环选色。 图 65 颜色选择器-颜色环 2) RGB选色。 图 66 颜色选择器-RGB 3) HSL选色。 图 67 颜色选择器-HSL 4) 国风颜色库选色。 图 68 颜色选择器-国风 5) CSS颜色库选色。 图 69 颜色选择器-CSS 6) 历史颜色&#xff1a;保存最近使用的多个颜色&…

vue快速入门(五十三)使用js进行路由跳转

注释很详细&#xff0c;直接上代码 上一篇 新增内容 几种常用的路由跳转方式演示 源码 App.vue <template><div id"app"><div class"nav"><!-- router-link 自带两个高亮样式类 router-link-exact-active和router-link-active区别&a…

3.SpringSecurity基本原理

SpringSecurity本质是一个过滤器链。十多个过滤器构成一个过滤器链。 这些过滤器在项目启动就会进行加载。每个过滤器执行放行操作才会执行下一个过滤器。 常见过滤器 FilterSecurityInterceptor 是一个方法级的权限过滤器&#xff0c;基本位于过滤器链的最底部。 Excepti…

Rust web简单实战

一、使用async搭建简单的web服务 1、修改cargo.toml文件添加依赖 [dependencies] futures "0.3" tokio { version "1", features ["full"] } [dependencies.async-std] version "1.6" features ["attributes"]2、搭…

HTML_CSS学习:CSS盒子模型

一、CSS中常用的长度单位 相关代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>CSS中常用的长度单位</title><style>html{font-size: 40px;}#d1{/*第一种长度单位&…

开源模型应用落地-LangChain高阶-Tools工具-集成agents(四)

一、前言 LangChain 的 tools 是一系列关键组件&#xff0c;它们提供了与外部世界进行交互的能力。通过适当的使用这些组件&#xff0c;可以简单实现如执行网络搜索以获取最新信息、调用特定的 API 来获取数据或执行特定的操作、与数据库进行交互以获取存储的信息等需求。 本章…

安装vscode基础配置,es6基础语法,

https://code.visualstudio.com/ es6 定义变量 const声明常量&#xff08;只读变量&#xff09; // 1、声明之后不允许改变 const PI “3.1415926” PI 3 // TypeError: Assignment to constant variable. // 2、一但声明必须初始化&#xff0c;否则会报错 const MY_AGE /…

01-MySQL 基础篇笔记

一、MySQL 概述 1.1 数据库相关概念 数据库&#xff1a;&#xff08;DB&#xff1a;DataBase&#xff09; 存储数据的仓库&#xff0c;数据是有组织的进行存储 数据库管理系统&#xff1a;&#xff08;DBMS&#xff1a;DataBase Management System&#xff09; 操作和管理数…

java spring 09 Bean的销毁过程

1.Bean销毁是发送在Spring容器关闭过程中的 AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(AppConfig.class);UserService userService (UserService) context.getBean("userService");userService.test();// 容器关闭cont…

手撕spring框架(5)

手撕spring框架(5) 相关系列 手撕spring框架&#xff08;1&#xff09; 手撕spring框架&#xff08;2&#xff09; 手撕spring框架&#xff08;3&#xff09; 手撕spring框架&#xff08;4&#xff09; 这是本专题最后一节了&#xff0c;主要是讲述自定义一个注解&#xff0c;实…

14_Scala面向对象编程_属性

属性 1.类中属性声明 // 1.给Scala声明属性&#xff1b;var name :String "zhangsan"val age :Int 302.系统默认赋值 scala由于初始化变量必须赋值&#xff0c;为了解决此问题可以采用下划线赋值&#xff0c;表示系统默认赋值 , –但是此方法局限于变量&…

太阳能光伏光热综合利用(PVT)

PVT系统介绍 传统太阳能系统是太阳光直接加热水&#xff0c;效率高&#xff0c;但是需要有防冻措施&#xff0c;且在太阳光不充足时需要增加电辅热&#xff0c;受天气影响大&#xff0c;且电加热能耗高。传统发电是将直流电转化为交流电&#xff0c;再提供给用户使用。此PVT技…

特斯拉全自动驾驶系统Tesla‘s Full-Self Driving (FSD)

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Overview Tesla’s FSD is a suite of features that includes Autopilot, Navigate on Autopilot, Auto Lane Change, Autopark, Summon, and Traffic Light and Stop Sig…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-12-蜂鸣器

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

力扣每日一题104:二叉树的最大深度

题目 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root [1,null,2…

C#中.net8WebApi加密解密

尤其在公网之中&#xff0c;数据的安全及其的重要&#xff0c;除过我们使用jwt之外&#xff0c;还可以对传送的数据进行加密&#xff0c;就算别人使用抓包工具&#xff0c;抓到数据&#xff0c;一时半会儿也解密不了数据&#xff0c;当然&#xff0c;加密也影响了效率&#xff…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-11.1,11.2-BSP文件目录组织

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

Redis-三主三从高可用集群搭建

正式搭建之前&#xff0c;注意事项&#xff08;坑&#xff09;提前放到最开始&#xff0c;也可以出问题回来看&#xff0c; &#xff08;1&#xff09;第二步中最好将配置文件中的logfile自定义一个目录&#xff0c;以便于在第五步中启动出错的时候迅速定位错误。 &#xff0…

2024五一赛数学建模A题B题C题完整思路+数据代码+参考论文

A题 钢板最优切割路径问题 &#xff08;完整资料在文末获取&#xff09; 1. 建立坐标系和表示方法&#xff1a; 在建模之前&#xff0c;我们需要将切割布局转换为数学表示。首先&#xff0c;我们可以将布局中的每个点表示为二维坐标系中的一个点。例如&#xff0c;B1可以表示…

计算机毕业设计Python+Spark知识图谱高考志愿推荐系统 高考数据分析 高考可视化 高考大数据 大数据毕业设计

毕业设计&#xff08;论文&#xff09;任务书 毕业设计&#xff08;论文&#xff09;题目&#xff1a; 基于大数据的高考志愿推荐系统 设计&#xff08;论文&#xff09;的主要内容与要求&#xff1a; 主要内容&#xff1a; 高…