← Backend / Go / 基础专题

10_递归与终止条件

识别递归的基例、规模缩小和栈开销。

Go 基础专题 10:递归与终止条件

学习目标:识别递归的基例、规模缩小和栈开销。

核心知识

递归函数会调用自己,必须有基例终止,并在每次调用中缩小问题规模。若忘记终止条件,调用会不断增长并最终失败。递归适合树结构等天然分层的问题;简单计数用循环通常更直接。

package main

import "fmt"

func factorial(n int) int {
    if n <= 1 {
        return 1
    }
    return n * factorial(n-1)
}

func main() { fmt.Println(factorial(5)) }

上述例子仅展示递归结构;实际函数应拒绝负数,并考虑 int 溢出。递归的每层调用都需要栈空间。斐波那契数列的朴素双重递归会重复计算大量子问题,可用迭代或记忆化优化。写递归前可先画出输入 3、2、1 的调用和返回过程。

遇到错误时,递归调用也应返回并处理错误,不要静默忽略。处理目录树时还要考虑符号链接循环与访问权限。

逐步理解

递归要能回答三个问题:最小输入是什么、这一层如何缩小问题、返回时如何组合答案。factorial(3) 展开为 3 * factorial(2),再是 3 * 2 * factorial(1),基例返回 1 后逐层回收。生产代码还应处理负数和结果溢出;示例只用于理解调用结构。

动手练习

练习:写递归求 1 到 n 的和,并解释 n=0 的结果。答案要点:基例 n <= 0 返回 0;其余返回 n + sum(n-1)。