女孩和机器人一起思考

一起动脑筋 · 先看一个小故事

机器人不断说“请下一位来帮忙”,却没有任何一位真正完成最小任务。这条队伍就停不下来。

把过程摊开来看

沿着编号看一遍,再用自己的话讲一遍
  1. 任务 n = 2交给 n = 1
  2. 任务 n = 1交给 n = 0
  3. 终止条件n = 0 直接回答
  4. 返回不再新增任务

终止条件让最小情况直接得到答案,而不继续递归。

还要检查每一次调用是否真的朝它靠近。写了 n == 0,却每次 n 加 1,仍然可能永远到不了。

01什么是停止条件?

递归里更准确的说法通常是基本情况(base case)

if (n == 0) {
    return;
}

它告诉函数:“到这里已经不用再拆了,可以直接结束。”

02只有停止条件就够了吗?

不够。

void f(int n) {
    if (n == 0) {
        return;
    }

    f(n + 1);  // 越走越远
}

如果从 f(3) 开始,n 会变成 4、5、6……根本到不了 0。

03正确递归需要两件事

有终点

存在可以直接结束的基本情况。

朝终点前进

每次递归都让问题更接近基本情况。

04如果没有终止,会发生什么?

f(5)f(4)f(3)f(2)...

活跃调用不断增加,占用的调用状态越来越多。

实际系统的调用栈空间有限,最终常见结果是栈溢出或程序异常终止。

05停止条件一定写成 n == 0 吗?

当然不是。

if (left > right) {
    return;
}

或者:

if (node == nullptr) {
    return;
}

基本情况取决于问题本身。

06怎样检查递归会不会停?

可以问三个问题:

终点是什么?

什么情况不再递归?

每层变了什么?

问题规模是否更小?

一定能到吗?

所有合法输入都会最终到达吗?

你已经知道了什么

  • 递归需要基本情况来停止继续调用。
  • 只有基本情况还不够,递归过程还必须向它靠近。
  • 无限递归会不断增加活跃调用。
  • 调用层数过深可能导致栈溢出。
  • 基本情况的形式由具体问题决定。

下一篇:递归时调用栈发生了什么?

轮到你来试一试

规则是 n == 0 停止,每次 n 减 2;从 3 开始会碰到 0 吗?

想好了吗?点开看解释

不会,序列是 3、1、-1……应重新设计递减规则或终止条件,并明确输入范围。