◎学完你会
- 看清递归的执行过程:递出去、到底、收回来;
- 理解每一层调用是一个栈帧(保存参数和返回点);
- 记住忘了出口 → 栈溢出。
1动一动:调用栈逐帧
int f(int n){
if(n<=1) return 1; // 出口
return n * f(n-1); // 先递归,再乘
}
调用 f(3) 的栈:[]
一层层压栈(递),到出口后一层层弹栈(归)。
2关键命令
| 要素 | 说明 | 例子 |
| 出口(基准情形) | 停止递归的条件 | n<=1 |
| 递(压栈) | 带更小参数调用自己 | f(n-1) |
| 归(弹栈) | 返回后继续算 | n * 返回值 |
每次调用 f(n) 都压一个栈帧(存 n 和返回地址),到底后从最深一层逐层返回。f(3) = 3·f(2) = 3·2·f(1) = 3·2·1 = 6。
⚠易错点
忘记出口 → 栈溢出:没写 if(n<=1) return,递归永不停止,栈帧无限压,最终栈溢出崩溃(运行时 Error)。先写出口再写递归体。
递归太深也溢出:即使有出口,n 极大(如 1e6)也会压太深爆栈。深递归改用循环/递推(见 14.2)。
?跨学科:递归像“套娃”和“逐级上报”
小盒子里套大盒子再套更大……最里层算完,逐层向外返回结果。像逐级上报:你问你的上家,上家再问上家,问到最顶层拿到答案,再一层层传回来。
“把大问题拆成同型小问题,直到能直接答”是递归的核心,也是分治(14.3)的基石。
✎练一练
递归函数里“出口”(基准情形)的作用是?
出口是递归的终止条件:满足就直接返回,不再递归。没出口就会无限压栈、栈溢出崩溃。
递归函数忘记写出口,运行时会?
答案:栈溢出(无限递归,栈帧一直压到撑爆,程序崩溃)。任何递归都必须有能到达的基准情形。