7️⃣ 递归函数
在函数内部调用自身的函数,就是递归函数。递归是编程中一个非常常用、也非常直观的逻辑结构,用于解决可拆解为相似子问题的问题。
- 一、方法速查表(含示例)
- 二、 递归计算阶乘
- 三、 尾递归实现(理论优化)
- 四、 递归应用:汉诺塔
- 五、使用递归的注意事项
- 六、小结
一、方法速查表(含示例)
方法/概念 | 示例代码片段 | 说明 |
---|---|---|
定义递归函数 | def fact(n): return 1 if n==1 else n*fact(n-1) | 用于计算阶乘 |
终止条件 | if n == 1: return 1 | 防止无限递归 |
调用自身 | return n * fact(n-1) | 递归核心调用 |
尾递归优化写法 | fact_iter(num-1, num*product) | 避免嵌套表达式,理论上防栈溢出 |
判断栈溢出 | RuntimeError: maximum recursion depth exceeded | 递归层数太多时报错 |
二、 递归计算阶乘
def fact(n):if n == 1:return 1return n * fact(n - 1)print(fact(5)) # 输出 120
过程解析(计算 fact(5)
):
fact(5)
=> 5 * fact(4)
=> 5 * (4 * fact(3))
=> ...
=> 5 * 4 * 3 * 2 * 1 = 120
三、 尾递归实现(理论优化)
def fact(n):return fact_iter(n, 1)def fact_iter(num, product):if num == 1:return productreturn fact_iter(num - 1, num * product)
⚠️ 注意:Python 并不会优化尾递归,这种写法在 Python 中仍然可能栈溢出。
四、 递归应用:汉诺塔
def move(n, a, b, c):if n == 1:print(a, '-->', c)else:move(n - 1, a, c, b)print(a, '-->', c)move(n - 1, b, a, c)move(3, 'A', 'B', 'C')
输出:
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C
🧵 别纠结中间过程
五、使用递归的注意事项
- ✅ 优点:逻辑清晰、结构简洁,适合处理分治类问题。
- ⚠️ 缺点:层数过深会导致 栈溢出(Python 默认最大递归深度约为 1000)。
📌 尾递归并不能避免栈溢出(在 Python 中),因为 Python 没有进行尾递归优化。
六、小结
- 递归适合分解重复结构的问题(如阶乘、树结构、汉诺塔)。
- 所有递归都可以转换为循环,但递归写法通常更清晰。
- 尾递归在理论上可优化栈使用,但在 Python 中无实际效果。
- 使用递归时,务必写好终止条件,防止死递归导致崩溃。