递归:汉诺塔 + 青蛙跳台阶

**
**
递归核心:把大问题拆解成规模更小的相同子问题,设置递归出口(终止条件)
1. 青蛙跳台阶问题
题目
一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级台阶。求跳上 n 级台阶总共有多少种跳法。
分析
设 f(n):跳到第 n 阶的跳法总数
最后一步:要么跳 1 阶(前面是 f(n‑1)),要么跳 2 阶(前面是 f(n‑2))
递推公式:f(n) = f(n‑1) + f(n‑2)
递归出口:
n = 1:只有 1 种,跳 1 步 → f(1)=1
n = 2:两种:1+1 、2 → f(2)=2
本质就是变形斐波那契数列
c
#include <stdio.h>
// 递归版本
int jump(int n)
{
if(n == 1)
return 1;
if(n == 2)
return 2;
return jump(n-1) + jump(n-2);
}
int main(void)
{
int n;
printf("请输入台阶数:");
scanf("%d", &n);
printf("总跳法:%d\n", jump(n));
return 0;
}
缺点:递归重复计算多,n 大效率低;可以改用循环迭代优化。
2. 汉诺塔问题
题目
有 A、B、C 三根柱子,A 上有 n 个圆盘,圆盘从上到下从小到大。
规则:
一次只能移动一个圆盘
小圆盘永远不能压在大圆盘下面
把全部圆盘从 A 移动到 C,打印每一步移动。
递归思路
把 n‑1 个圆盘,借助 C,从 A 移动到 B
把第 n 个(最大圆盘),直接 A → C
把 n‑1 个圆盘,借助 A,从 B 移动到 C
递归出口:n == 1:直接 A→C
c
#include <stdio.h>
// n个盘子,从 src 借助 temp 移动到 dest
void hanoi(int n, char src, char temp, char dest)
{
if(n == 1)
{
printf("%c --> %c\n", src, dest);
return;
}
hanoi(n-1, src, dest, temp); // n‑1个:src → temp,借助dest
printf("%c --> %c\n", src, dest); // 最大盘子直接移过去
hanoi(n-1, temp, src, dest); // n‑1个:temp → dest,借助src
}
int main(void)
{
int n;
printf("输入汉诺塔圆盘数量:");
scanf("%d", &n);
hanoi(n, 'A', 'B', 'C');
return 0;
}
样例 n=3 输出
plaintext
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C
递归通用模板:
c
函数(规模n)
{
if(递归出口条件)
return 结果;
return 函数(更小的子问题);
}
3.两个题对比总结
问题 递归公式 出口
青蛙跳台 f(n)=f(n‑1)+f(n‑2) n=1→1;n=2→2
汉诺塔 移动 n 个 = 移动 n‑1 个 + 移动最大盘 + 移动 n‑1 个 n=1 直接移动
青蛙跳台:求数量;汉诺塔:输出移动步骤。