CDay06
递归
定义:在函数调用过程中又调用自身的现象
斐波拉契数列
Fibnacci数列:0,1,1,2,3,5,8,13,...
Fn = 0, n = 0 ;
Fn = 1, n = 1 ;
Fn = Fn-2 + Fn-1
long long fib(int n)
{
if(n == 0||n == 1) return 0;
return fib(n-2) + fib(n-1);
}
时间复杂度O(2^n),此方法很耗时,不要采用。

Q:如何避免重复计算问题?
答:顺序求解子问题,这也就可以避免重复计算(动态规划)
最优解:
long long fib(int n)
{
if(n == 0||n == 1) return n;
long long a = 0, b = 1;
for(int i = 2;i <= n;i++)
{
//计算fib(i)的值
long long tmp = a + b;
a = b;
b = tmp;
}
return b;
}
汉诺塔问题
- 边界条件
- 假设会移动 n-1 个盘子,如何移动 n 个盘子(数学归纳法)
递归公式(核心):
- 将 n-1 个盘子移动到 B 上
- 将最大的盘子移动到 C 上
- 将 B 杆上的 n-1 个盘子移动到 C 上
只需关心这一步与递归上一步的关系及边界条件,不要纠结于函数的入栈出栈。
void hanoi(int n, char start, char middle, char target)
{
int count = 0;
//边界条件
if (n == 1)
{
printf("%c --> %c\n", start, target);
return;
}
//递归公式
//把 n-1 个盘子移动到 middle 上
hanoi(n - 1, start, target, middle);
//把最大的盘子移动到 target 上
printf("%c --> %c\n", start, target);
//把 n-1 个盘子移动到 target 上
hanoi(n - 1, middle, start, target);
}
有关移动的次数 s(n)
故:
s(n) + 1 = 2s(n-1) + 2 = 2[s(n-1) + 1],为公比为 2 的等比数列
所以,s(n) = 2^n - 1
总结
1、什么情况下可以考虑使用递归?
递归的结构:
- 递:大问题可以分解成若干个子问题,并且子问题的求解与大问题一致。
- 归:可以将子问题的解合并成大问题的解。
2、使用递归时需要注意的问题?
- 重复计算
- 递归的层次不能太深
3、如何写递归?
- 边界条件
- 递归公式
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库