递归
约 537 字大约 2 分钟
2025-04-04
人理解函数,神理解递归。递归的精华是一递一归。所谓递,就是不断嵌套函数;所谓归,就是逐个将值返回。递而不归,就会越嵌套越深,直至突破内存极限而出错。
递归函数的定义有两个方面:
- 不断调用自己本身(只满足这个条件的是死递归)
- 有明确的结束条件
例如,下面的这个函数就是一个死敌归:
def func():
print(1)
func()
func()
程序并没有一直运行,持续打印 1
,而是运行到一定深度(层次)后就停止了。
这是因为 Python 为了保护计算机而设置了递归的深度限制。官方声明的限制是 1000 层,但实际测试往往在 998/997 层左右。
我们也可以修改系统设置的迭代深度限制:
import sys
sys.setrecursionlimit(800)
现在,让我们用递归写一个阶乘的函数:
def factorial(n):
if n == 1:
return 1
else:
return factorial(n - 1) * n
print(factorial(5)) # 120
递归的思路是:找到 f(n)
与 f(n - 1)
之间的关系,然后将这种关系作为返回值或者其他操作。通过设置起始位置或终止位置的函数值实现函数的结束条件。
对于上个例子来说,factorial(n)
与 factorial(n - 1)
之间的关系是 factorial(n) = factorial(n - 1) * n
。而当 n
为 1
时,factorial(1) = 1
。
把上面的例子拆开看就是下面这个样子:
函数层数 | n | 返回值 |
---|---|---|
factorial(5) | 5 | factorial(4) * 5 |
1 | 4 | factorial(3) * 4 * 5 |
2 | 3 | factorial(2) * 3 * 4 * 5 |
3 | 2 | factorial(1) * 2 * 3 * 4 * 5 |
4 | 1 | 1 * 2 * 3 * 4 * 5 |
有些问题使用递归解起来会有很奇妙的感觉,比如解决汉诺塔问题等。
但是因为层层嵌套,层层调用,递归非常占用内存,运行速度也相对缓慢。而且很多情况下,递归是可以转换成循环的,比如计算阶乘的函数可以写成:
def factor(n):
result = 1
while n > 0:
result *= n
n -= 1
return result
print(factor(5))
版权所有
版权归属:Shuo Liu