【C语言课堂】 函数递归

news2024/10/7 14:27:02

欢迎来到 Claffic 的博客 💞💞💞

前言:

时隔多日,来还欠大家的 C 语言学习啦,上期讲了函数,其实函数中应该包括函数递归的,这里单独拿出来讲解的原因是函数递归属于重难知识,值得拿出来单独讲讲。


目录

❤️1. 何为递归

🧡2. 递归的两个必要条件

💚3. 递归和迭代(循环) 

💜4. 一个练习


1. 何为递归

屏幕前的大佬们:

这个有趣的表情包就有点递归的意思:

可以看到抱腿系数不断攀升,抱腿下还有抱腿...(huyanluanyu)。

还有《盗梦空间》中的经典场面:

两面镜子相对,镜子里面的情景是相同的,无限循环的。典型的 “德罗斯特效应”。

这也与递归类似,逐渐深入,深入,深入... ...

通过上面两个引子,相信你已经大概了解递归是什么样子的,下面 递归的概念:

程序调用自身的编程技巧称为递归 recursion)。 

说的通俗点,就是函数里用了函数本身。

int Strlen(const char*str) 
{
     if(*str == '\0')
         return 0;
     else
         return 1 + Strlen(str+1);
}

这是用递归的方法模拟了 strlen 函数,这个函数调用了函数自身。

递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身 的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
递归的主要思考方式在于:把大事化小

2. 递归的两个必要条件

递归大不可一直进行下去,否则就会像《盗梦空间》里的镜子那样碎掉,所以递归要有停止的条件,给递归一个限制。

于是就有了递归的第一个必要条件: 存在限制条件。

        以上面的模拟 strlen 函数为例, *str == '\0'  就是限制条件,当达到这个条件时函数就会返回。

有了限制条件就可么?其实不是,如果递归一直停留在一个位置或者向非限制条件的方向进行,那么限制条件存在的意义不大。

所以还要有一个必要条件:每次递归后要接近这个限制条件。

        同样以模拟 strlen 函数为例, Strlen(str+1) 的意思就是每进行一次递归,指向单个字符的指针不断加一,越来越接近 '\0'

🧑🏻‍💻总结:

递归的两个必要条件: 

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

3. 递归和迭代(循环) 

不知道大家在学习递归的时候有没有考虑几个问题:

• 递归和循环是不是有些相似?

• 何时选择递归,何时选择循环?

是的,大多数情况下 递归存在重复运算,与循环相似

这里总结下递归和迭代(循环)的优缺点:

• 递归代码简洁,思路较简单,有时甚至是所想即所得;

• 但递归多次调用函数本身,而每次调用函数都会有时间和空间消耗,都会在内存栈中分配空间,效率较低,容易导致栈溢出。

所以我对递归的理解是: 方便了自己,麻烦了电脑

• 迭代(循环)对程序员来说可能思路复杂,但不会对电脑造成大的压力,不会出现栈溢出的情况,且效率较高。

迭代(循环)的理解是: 方便了电脑,麻烦了自己。

一个建议: 优先选择迭代(循环),实在没思路选择递归。

4. 一个练习

求第n个斐波那契函数(不考虑溢出)。

 1、1、2、3、5、8、13、21、34、… 

著名的生兔子数列,这个数列从第三项开始,每一项都等于前两项之和。

用递归,所想即所得:

int fib(int n) 
{
    if (n <= 2)         
       return 1;
    else
       return fib(n - 1) + fib(n - 2);
}

 但,假如要求 fib(10) :

虽然只求第10个斐波那契数,但是要进行 1000 多次函数调用!

可见是非常危险的。

这种情况下,选择循环比较好:

int fib(int n)
{
	if (n <= 2)
		return 1;
	int fibn = 0;
	int fibone = 1;
	int fibtwo = 1;
	int i = 1;
	for (i = 1; i < n - 1; i++)
	{
		fibn = fibone + fibtwo;
		fibone = fibtwo;
		fibtwo = fibn;
	}
	return fibn;
}

总结:

递归虽好,但不要贪杯哦 ~

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

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

相关文章

【编程入门】开源记事本(Flutter版)

背景 前面已输出多个系列&#xff1a; 《十余种编程语言做个计算器》 《十余种编程语言写2048小游戏》 《17种编程语言10种排序算法》 《十余种编程语言写博客系统》 《十余种编程语言写云笔记》 本系列对比云笔记&#xff0c;将更为简化&#xff0c;去掉了网络调用&#xff0…

数据结构入门(力扣算法)

数据结构入门前面的题号为力扣的题号数组的217. 存在重复元素53. 最大子数组和1. 两数之和88. 合并两个有序数组350. 两个数组的交集 II121. 买卖股票的最佳时机566. 重塑矩阵118. 杨辉三角36. 有效的数独73. 矩阵置零字符串的387. 字符串中的第一个唯一字符383. 赎金信242. 有…

LeetCode 437. 路径总和 III

LeetCode 437. 路径总和 III 给定一个二叉树的根节点 root &#xff0c;和一个整数 targetSum &#xff0c;求该二叉树里节点值之和等于 targetSum 的 路径 的数目。 路径 不需要从根节点开始&#xff0c;也不需要在叶子节点结束&#xff0c;但是路径方向必须是向下的&#xff…

JUC面试(十一)——LockSupport

可重入锁 可重入锁又名递归锁 是指在同一个线程在外层方法获取锁的时候&#xff0c;再进入该线程的内层方法会自动获取锁(前提&#xff0c;锁对象得是同一个对象)&#xff0c;不会因为之前已经获取过的锁还没释放而阻塞。 Java中ReentrantLock和synchronized都是可重入锁&am…

第一章 概述

第一章 概述 1.1 计算机网络在信息时代中的作用 21世纪的一些重要特征 数字化&#xff0c;网络化和信息化 以网络为核心的信息时代 互联网的两个重要基本特点 连通性共享&#xff08;资源共享&#xff09; 1.2 互联网概述 计算机网络由若干个结点货连接这些结点的链路组成…

【唐诗学习】四、边塞诗派代表

四、边塞诗派代表 边塞诗派起源 盛唐是中国历史上一个空前的盛世&#xff0c;国库丰盈&#xff0c;社会十分安定&#xff0c;百姓的幸福指数高。 盛唐是中国历史上一个空前的盛世&#xff0c;国库丰盈&#xff0c;社会十分安定&#xff0c;百姓的幸福指数高。唐太宗以后的几个…

Citadel——Dusk网络的Zero-Knowledge KYC解决方案

1. 引言 近期&#xff0c;Dusk网络宣布其已支持名为Citadel的Zero-Knowledge KYC解决方案&#xff0c;使得用户和机构可控制其权限以及个人信息分享。该架构可用于all claim-based KYC requests&#xff0c;并让用户完全控制他们共享的信息以及与谁共享信息&#xff0c;同时完…

详解Java中的BIO、NIO、AIO

1、 详解Java中的BIO、NIO、AIO 1.1、引言 IO流是Java中比较难理解的一个知识点&#xff0c;但是IO流在实际的开发场景中经常会使用到&#xff0c;比如Dubbo底层就是NIO进行通讯。本文将介绍Java发展过程中出现的三种IO&#xff1a;BIO、NIO以及AIO&#xff0c;重点介绍NIO。…

【c语言进阶】常见的静态通讯录

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;c语言学习 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我…

2.H3CNE-网络参考模型

OSI参考模型产生背景各大IT设备厂商只支持自己的私有协议&#xff0c;跨厂商设备兼容性差用户购买和维护成本高不利于网络技术发展概念定义了网络中设备所遵守的层次结构优点开放的标准化接口&#xff0c;协议不再封闭多厂商设备兼容易于理解、学习和更新协议标准实现模块化工程…

【Leetcode刷题】141、环形链表

原题链接&#xff1a;https://leetcode.cn/problems/linked-list-cycle/?favorite2cktkvj给你一个链表的头节点 head &#xff0c;判断链表中是否有环。如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的…

Python数据可视化(二)使用统计函数绘制简单图形

该文会讲解一些大家比较熟悉却又经常混淆的统计图形&#xff0c;掌握这些统计图形可以对数据可视化有一个深入理解&#xff0c;并正确使用。2.1 函数 bar()——用于绘制柱状图函数功能&#xff1a;在 x 轴上绘制定性数据的分布特征。调用签名&#xff1a;plt.bar(x,y)。参数说明…

day21|216.组合总和III、17.电话号码的字母组合

216.组合总和III 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k 3, n 7 输出: …

说说配置中心

什么是配置中心在微服务的环境下,将项目需要的配置信息保存在配置中心,需要读取时直接从配置中心读取,方便配置管理的微服务工具可以将部分yml文件的内容保存在配置中心一个微服务项目有很多子模块,这些子模块可能在不同的服务器上,如果有一些统一的修改,需要逐一修改这些子模块…

python数据可视化开发:Matplotlib库基础知识

文章目录前言01.工具栏组件02.图表数据03.设置字体字典&#xff08;1&#xff09;全局字体样式&#xff08;2&#xff09;常用中文字体对应名称&#xff08;3&#xff09;查询当前系统所有字体04.图像配置实例05.图表标题06.文本组件07.坐标轴标签组件08.网格组件09.绘制折线10…

【头歌】双向链表的基本操作

双向链表的基本操作第1关&#xff1a;双向链表的插入操作任务描述本关任务&#xff1a;编写双向链表的插入操作函数。相关知识双链表中用两个指针表示结点间的逻辑关系&#xff1a;指向其前驱结点的指针域prior&#xff0c;指向其后继结点的指针域next。双向链表的结点结构如图…

MySQL数据库面试题[万字汇总]

1) MySQL数据库相关错题本1、存储引擎相关1、MySql的存储引擎的不同MySQL存储引擎主要有InnoDB, MyISAM, Memory, 这三个区别在于:Memory是内存数据引擎, 会断电重启(在双M或者主从架构下会产生较多异常), 且不支持行级锁. 默认索引是数组索引, 支持B索引InnoDB和MyISAM的区别:…

流批一体计算引擎-5-[Flink]的Python Table API和SQL程序

参考Flink从入门到入土&#xff08;详细教程&#xff09; 参考flink的默认窗口触发机制 参考彻底搞清Flink中的Window 参考官方Python API文档 1 IDEA中运行Flink 从Flink 1.11版本开始, PyFlink 作业支持在 Windows 系统上运行&#xff0c;因此您也可以在 Windows 上开发和…

【数据结构】极致详解:树与二叉树(上)——结构与概念

目录 &#x1f6eb;前言&#x1f6eb;&#xff1a; &#x1f680;一、树&#x1f680;&#xff1a; 1.树的概念&#xff1a; 2.树的相关概念&#xff1a; 3.树的表示&#xff1a; 4.树的实际使用场景&#xff1a; &#x1f6f0;️二、二叉树&#x1f6f0;️&#xff1a;…

acwing-Diango项目 (后半)

acwing-Django项目 文章目录acwing-Django项目前言5. 创建账号系统5.1用户名密码登录写登录界面写注册界面写动作 实现三个函数 register login logout5.2 Web端acapp一键登录在django中集成redis(准备工作)首先 pip install django_redis配置一下缓存启动redis-serverredis在d…