

💡 核心概念: 递归函数是指在函数体内部直接或间接调用自己的函数。
一个合法的递归必须有两个要素:
1. 递归公式:把大问题拆成小问题(自己调自己)。
2. 终止条件 (Base Case):什么时候停下来。没有这个,程序就会崩溃!
我们来看一个最简单的递归:计算阶乘(Factorial)。
5! = 5 * 4 * 3 * 2 * 1
可以理解为:5! = 5 * 4!
package main
import "fmt"
func Factorial(n int) int {
// 🛑 1. 终止条件:如果不写这个,就会无限递归,直到栈溢出
if n == 0 {
return 1
}
// 🔄 2. 递归调用:自己调用自己,但是规模变小了
return n * Factorial(n-1)
}
func main() {
fmt.Println(Factorial(5)) // 输出 120
}
函数调用就像叠罗汉,每调用一次,就在内存的“栈”上压一层。只有最上面的人下来了(返回了),下面的人才能动。
执行过程 Factorial(3):
如果你的递归没有终止条件,或者层数太深(成千上万层),内存的栈空间就会被用光,程序直接崩溃。
func DeadLoop() {
DeadLoop() // 没完没了,只有去没有回
}
// 运行结果:fatal error: stack overflow
经典的递归应用:1, 1, 2, 3, 5, 8, 13... (当前数 = 前两个数之和)
func Fib(n int) int {
if n < 2 {
return n
}
return Fib(n-1) + Fib(n-2)
}
注意: 这种写法虽然代码简单,但效率极低(重复计算太多)。如果 n 很大,唐伯虎头发白了都算不出来。实战中建议用循环或带缓存的递归。
假设你正在爬华府的高塔,一次可以爬 1 个台阶,也可以爬 2 个台阶。如果有 n 个台阶,一共有多少种爬法?
提示:
爬 1 阶:1 种 (1)
爬 2 阶:2 种 (1+1, 2)
爬 3 阶:3 种 (1+1+1, 1+2, 2+1) -> 等于 爬2阶 + 爬1阶
这是不是和斐波那契数列很像?
func ClimbStairs(n int) int {
// 基准条件
if n <= 2 {
return n
}
// 递归公式:要么从 n-1 爬上来,要么从 n-2 爬上来
return ClimbStairs(____) + ClimbStairs(____)
}
任务: 填空完成递归公式。
答案: n-1 和 n-2
解析: f(n) = f(n-1) + f(n-2)。到达第 n 阶只有两种可能:从 n-1 阶迈一步,或者从 n-2 阶迈两步。