【入门级-C++程序设计:9、函数与递归:递归函数】

一、递推概念
讲解递归之前,首先介绍一下递推,顾名思义递推是通过已知的初始条件和递推关系式,逐步推导出后续结果的方法。它通常表现为循环结构。
举例说明:求阶乘的递推实现
int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}
程序思路说明:例如我们要求出5的阶乘,如果我已经知道4的阶乘,再乘以5就可以了,那么我们要求4的阶乘,只要我们知道3的阶乘,再乘以4就可以了,以此类推,最终,如果我们知道1的阶乘,反过来一次乘以2,然后将结果再乘以3,等等,最终就可以求出5的阶乘。通过上面这个程序,利用循环就可以实现。

递推特点
循环结构:使用循环语句实现
自底向上:从已知条件开始逐步构建,逐步细化,求出最终结果
状态保存:通常使用变量或数组保存中间结果
效率较高:没有函数调用开销

二、递归函数
概念:是指在函数体内直接或间接调用自身的函数(说白了就是函数自己调用自己)。递归主要是解决某些特殊问题的强大技术,特别是那些可以分解为相似子问题的问题。
举例说明:求阶乘的递推实现
unsigned long long factorial(int n) {
// 基准条件
if(n == 0 || n == 1) {
return 1;
}
// 递归条件
else {
return n * factorial(n - 1);
}
}

程序思路说明:例如我们要求出5的阶乘,如果有人可以告诉我4的阶乘的话,我将4的阶乘乘以5就可以得到5的阶乘,至于4的阶乘是怎么求出来的,我并不关心;同样,如果有人告诉我3的阶乘的话,我将3的阶乘乘以4就可以求出4的阶乘了,以此类推,要求2的阶乘,只要将1的阶乘乘以2就可以求出2的阶乘,而1的阶乘是1,0的阶乘等于 1。这个是不需要求的。
上面这段程序的说明:
1、函数factorial是一个递归函数,实现求一个数的阶乘,factorial是函数名
2、当我们求0的阶乘的时候,函数形参n等于0,函数factorial执行的时候,进人到if分支,此时函数返回值为1,实现计算0的阶乘,结果为1。
3、当我们求1的阶乘的时候,函数形参n等于1,函数factorial执行的时候,进人到if分支,此时函数返回值为1,实现计算1的阶乘,结果为1。
4、当我们求2的阶乘的时候,函数形参n等于2,函数factorial执行的时候,进人到else分支,此时函数调用语句n * factorial(n - 1),语句展开后为2* factorial(1),这里factorial(1)本身就是一个函数,是函数自己调用自己,也就是函数的递归调用;factorial(1)这个函数调用后,函数进人到if语句,执行结果为1,然后2* factorial(1)展开后,就是2*1,结果为2,最终结算出2的阶乘是2。
5、读者可以自己尝试,当n等于3,等于4的时候,自己去一步一步的分析,这个递归函数的调用关系,体会函数递归调用的原理。

递归的基本要素
基准条件:递归终止的条件,防止无限递归
递归条件:函数调用自身的条件
逐步逼近基准条件:每次递归调用都应使问题向基准条件靠近

递归优点:
代码简洁,可读性强,易于理解和实现
递归将问题分解为子问题,避免了重复编写处理相似逻辑的代码,降低维护成本
适合解决具有递归结构问题,如树遍历、排序算法等

递归缺点:
可能有较高的内存开销(每次调用都会在栈上创建新的栈帧)
空间开销大,可能导致栈溢出(对于深度递归)
调试难度高,错误定位(如死循环、边界条件错误)比循环更复杂。例如,若递归缺少终止条件,会导致无限递归,最终引发栈溢出,且调试时难以跟踪每层的状态。
逻辑理解门槛高,递归的 “自调用” 逻辑需要逆向思维(从问题结果反推子问题)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

papership

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值