函数递归的介绍

news2025/1/21 6:21:19

1.递归的定义

C语言中,递归就是函数自己调用自己

上面的代码就是 main 函数在函数主体内 自己调用自己

但是,上面的代码存在问题:main 函数反复地 自己调用自己 ,不受限制,停不下来。

最终形成死递归,导致栈溢出

1.0栈溢出

 每一次函数调用,都要从内存上的栈区为这次函数调用分配内存空间

栈区的大小是有限的,如果无限的调用函数就会导致栈区空间被使用完,

从而发生栈溢出的现象,导致程序运行停止

1.1递归的思想

将一个大问题细分为一个个子问题,直到子问题不可拆分为止就是递归的思想。

递归就是将大事化小的过程。

递,就是递推;归,就是回归。

1.2.递归的书写条件

(1)递归存在限制条件,当条件满足时,递归便不再继续

(2)每次递归调用之后,越来越接近这个限制条件

2.举例

2.1阶乘

我们知道,n! = n * (n-1) * (n-2) * (n-3) * ……* 2 * 1

又注意到,2! = 2 * 1!  ||   3! = 3 * 2! || 4! = 4 * 3!

所以 n! = n * (n -1)!

int Fact1(int n)
{
	if (n == 0)
		return 1;
	else return n * Fact1(n - 1);
}

当 n = 3 时

Fact1(3) = 3*Fact1(2) 

Fact1(2)  = 2*Fact1(1) 

Fact1(1) = 1*Fact1(0) 

Fact1(0)  = 1

先是递推,每次函数调用之后,接近 n 等于 0 这个限制条件

然后回归

Fact1(0)  = 1

Fact1(1) = 1*Fact1(0) = 1

Fact1(2)  = 2*Fact1(1)  = 2

Fact1(3) = 3*Fact1(2)  = 6

2.2顺序打印整数的每一位

运用递归时,我们要相信我们所创建的函数能够完成相应的任务

例如,顺序打印 123 中的每一位

void Print1(int n)
{
	if (n > 9)
		Print1(n / 10);

	printf("%d ", n % 10);
}

 

在上面的代码实现中:

Print(123)中 123 > 9 所以 先调用函数Print(123/10)打印 12 再打印3

Print(123 / 10)中 12 > 9 所以 先调用函数Print(12/10)打印 1 再打印2,

Print(12 / 10)中 1  < 9 开始 打印 1,函数Print(12 / 10)调用完毕

然后返回函数Print(123 / 10)打印 2, 再返回函数Print(123)打印3

Print(123)  -> Print(123 / 10) -> Print(12 / 10)

这是递推, 将 大问题转化位 小问题, 只打印个位数

Print(12 / 10)  - > Print(123 / 10)  -> Print(123)

这是回归 ,因为只有函数调用任务实现后,才会继续后面的操作

2.3斐波那契数列

1,1,2,3,5,8,13,21,34........

第一二个数为1,其余的数等于前两个数相加,就是斐波那契数列的规律

代码实现:

int Fib(int n)
{
	if (n < 3)
		return 1;
	else return Fib(n - 1) + Fib(n - 2);
}

例如 n = 4

Fib(4) = Fib(3) + Fib(2)

Fib(3) = Fib(2) + Fib(1)

Fib(2) = 1

这是递推,然后回归

Fib(3) = 1 +Fib(1)

Fib(1) = 1

所以Fib(3) = 1+ 1 = 2

继续回归

Fib(4) = 2 + Fib(2)

Fib(2) = 1

Fib(4) =  2 +1 = 3

注意:只用当前一个Fib函数调用完毕后才会调用后面的Fib函数

 

3.递归与迭代

上述例子用递归的思想实现时,代码较为简洁

但不可避免的是,如果递归的层次太深,栈溢出的现象就不可避免

所谓层次太深,就是说许多函数被调用后,未被销毁,依然占据着栈区的部分内存

最终导致栈区空间被使用完,出现栈溢出的现象

 

 

虽然存在限制条件 n > 10000 但是 3988次调用之后,程序就自动停止了 ,

因为递归层次太深,出现了栈溢出的现象

注意到,Fib函数虽然被调用了很多次,但是却没有出现栈溢出的现象

这是因为Fib(40)最深只会调用40次,然后就会被销毁,再继续后面的调用 

..........................................................................................................................................

注意到,Fib(40)重复调用的Fib函数太多,运行效率非常低

此时就可以采用迭代的方法实现斐波那契数列。

循环是一种迭代,迭代不仅仅是循环

int Fact2(int n)
{
	int a = 1;//前两个数
	int b = 1;//前一个数
	int c = 1;//当前的数
 

//当n 小于等于 2时
//直接返回c 为 1
//当n 大于 2时
//1 + 1 = 2  1+ 2 = 3 2+ 3 = 5
//第n个数需要迭代n-2次

	for (int i = 0; i < n - 2; ++i)
	{
		c = a + b;
		a = b;
		b = c;
	}

   return c;

}

运行一下就知道,迭代实现斐波那契数列比递归更快!

但是解决实际问题时

递归比较好想,如果能保证不会出现栈溢出等问题就可优先考虑使用递归

其次是迭代

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

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

相关文章

四、华为交换机 STP

生成树协议&#xff08;STP&#xff09;的核心目的是在存在冗余链路的网络中&#xff0c;构建一个无环的拓扑结构&#xff0c;从而防止网络环路带来的广播风暴等问题 一、STP 原理 选举根桥&#xff1a;网络中的每台交换机都会有一个唯一的桥 ID&#xff08;BID&#xff09;&am…

前端炫酷动画--图片(一)

目录 一、四角线框的跟随移动 二、元素倒影(-webkit-box-reflect) 三、模特换装(maskblend) 四、元素平滑上升 五、无限视差滚动 六、判断鼠标进入方向(轮播方向) 七、环形旋转效果 八、黑白小球交替旋转 九、hover时圆形放大 十、画一棵随机树(canvas) 十一、代码雨…

AI刷题-病毒在封闭空间中的传播时间

目录 问题描述 输入格式 输出格式 解题思路&#xff1a; 问题理解 数据结构选择 算法步骤 代码实现&#xff1a; 1.初始化&#xff1a; 2.设置边界条件&#xff1a; 3.判断 4.更新&#xff1a; 5.返回 最终的实现代码如下&#xff1a; 运行结果&#xff1a; …

SQL表间关联查询详解

简介 本文主要讲解SQL语句中常用的表间关联查询方式&#xff0c;包括&#xff1a;左连接&#xff08;left join&#xff09;、右连接&#xff08;right join&#xff09;、全连接&#xff08;full join&#xff09;、内连接&#xff08;inner join&#xff09;、交叉连接&…

路由器旁挂三层网络实现SDWAN互联(爱快SD-WAN)

近期因公司新办公区建设&#xff0c;原有的爱快路由器的SDWAN功能实现分支之间互联的服务还需要继续使用。在原有的小型网络中&#xff0c;使用的爱快路由器当作网关设备&#xff0c;所以使用较为简单,如下图所示。 现变更网络拓扑为三层网络架构&#xff0c;但原有的SDWAN分支…

麦田物语学习笔记:制作[SceneName]Attribute特性

基本流程 因为在现有的项目中,像开始场景的切换或者Telepot组件都需要手动输入场景名,有时还可能键入出错,而该特性能用选择的方式去解决这一问题 1.代码实现 SceneNameDrawer.cs //参数绘制 using UnityEditor; using UnityEngine; #if UNITY_EDITOR [CustomPropertyDrawer(…

HTML之拜年/跨年APP(改进版)

目录&#xff1a; 一&#xff1a;目录 二&#xff1a;效果 三&#xff1a;页面分析/开发逻辑 1.页面详细分析&#xff1a; 2.开发逻辑&#xff1a; 四&#xff1a;完整代码&#xff08;不多废话&#xff09; index.html部分 app.json部分 二&#xff1a;效果 三&#xff1a;页面…

【2024 年度总结】从小白慢慢成长

【2024 年度总结】从小白慢慢成长 1. 加入 CSDN 的契机2. 学习过程2.1 万事开头难2.2 下定决心开始学习2.3 融入技术圈2.4 完成万粉的目标 3. 经验分享3.1 工具的选择3.2 如何提升文章质量3.3 学会善用 AI 工具 4. 保持初心&#xff0c;继续前行 1. 加入 CSDN 的契机 首次接触…

一文大白话讲清楚webpack基本使用——2——css相关loader的配置和使用

一文大白话讲清楚webpack基本使用——2——css相关loader的配置和使用 1. 建议按文章顺序从头看是看 第一篇&#xff1a;一文大白话讲清楚啥是个webpack第二篇&#xff1a;一文大白话讲清楚webpack基本使用——1——完成webpack的初步构建然后看本篇&#xff0c;Loader的配置…

如何将 session 共享存储到 redis 中

文章目录 一. 分布式 session 登录1.1 什么是分布式&#xff1f;1.2 Session 共享1.3 为什么服务器 A 登录后&#xff0c;请求发到服务器 B&#xff0c;不认识该用户&#xff1f;1.4 共享存储 二. Session 共享实现Redis三. 测试session共享四. cookie设置4.1 前端4.2 后端 一.…

Debezium日常分享系列之:对于从Oracle数据库进行快照的性能优化

Debezium日常分享系列之&#xff1a;对于从Oracle数据库进行快照的性能优化 源数据库Kafka Connect监控测试结果 源数据库 Oracle 19c&#xff0c;本地&#xff0c;CDB数据库主机的I/O带宽为6 GB/s&#xff0c;由此主机上运行的所有数据库共享临时表空间由42个文件组成&#x…

STM32 FreeROTS Tickless低功耗模式

低功耗模式简介 FreeRTOS 的 Tickless 模式是一种特殊的运行模式&#xff0c;用于最小化系统的时钟中断频率&#xff0c;以降低功耗。在 Tickless 模式下&#xff0c;系统只在有需要时才会启动时钟中断&#xff0c;而在无任务要运行时则完全进入休眠状态&#xff0c;从而降低功…

Redis - General - 未授权访问漏洞(用户配置问题)

0x01&#xff1a;产品简介 Redis&#xff08;Remote Dictionary Service&#xff0c;远程数据服务&#xff09;&#xff0c;是一款开源的基于内存的键值对存储系统&#xff0c;其主要被用作高性能缓存服务器使用&#xff08;比如作为消息中间件和用于 Session 共享&#xff09…

学习threejs,使用OrbitControls相机控制器

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.OrbitControls 相机控…

SQL和MySQL以及DAX的日期表生成?数字型日期?将生成的日期表插入到临时表或者实体表中

几种生成日期表的方法 如何用SQL语句生成日期表呢&#xff1f; 如何用MySQL语句生成日期表呢&#xff1f; 如何用DAX语句生成日期表呢&#xff1f; 1. MySQL生成日期表 1.1 日期格式&#xff1a;yyyy-MM-dd 字符型 2024-01-02 -- 生成日期表 WITH RECURSIVE temp_dateTable …

C# 动态创建Label和ComboBox控件并修改Text

背景&#xff1a;在做项目的时候可能需要根据一定数量创建某些控件并修改其属性&#xff0c;本文以控件label、ConboBox控件进行动态创建。 程序运行前后的的Form动态图 代码如下&#xff1a; using System; using System.Collections.Generic; using System.ComponentModel; …

2025年编程语言热度分析:Python领跑,Go与Rust崛起

TIOBE Index&#xff08;TIOBE 编程语言指数&#xff09;是一个衡量编程语言流行度的排名系统。它通过分析多种搜索引擎、在线编程社区、技术论坛、问答网站&#xff08;如 Google、Bing、Yahoo、Wikipedia、Stack Overflow&#xff09;等的搜索和讨论数据&#xff0c;评估不同…

【从零开始入门unity游戏开发之——C#篇46】C#补充知识点——命名参数和可选参数

考虑到每个人基础可能不一样&#xff0c;且并不是所有人都有同时做2D、3D开发的需求&#xff0c;所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】&#xff1a;主要讲解C#的基础语法&#xff0c;包括变量、数据类型、运算符、…

python学opencv|读取图像(三十九 )阈值处理Otsu方法

【1】引言 前序学习了5种阈值处理方法&#xff0c;包括(反)阈值处理、(反)零值处理和截断处理&#xff0c;还学习了一种自适应处理方法&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像&#xff08;三十三&#xff09;阈值处理-灰度图像-CSDN博客 python学o…

【Idea】编译Spring源码 read timeout 问题

Idea现在是大家工作中用的比较多的开发工具&#xff0c;尤其是做java开发的&#xff0c;那么做java开发&#xff0c;了解spring框架源码是提高自己技能水平的一个方式&#xff0c;所以会从spring 官网下载源码&#xff0c;导入到 Idea 工具并编译&#xff0c;但是发现build的时…