在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
例如,我们用fact(n)函数来计算n的阶乘,即:
fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n
根据阶乘的特点,可以得出这个结果:
fact(n) = n x fact(n-1)
依此类推:
fact(n-1) = (n-1) x fact(n-1-1)
直到:
fact(1) = 1 x fact(1-1)
这里fact(0)的值确定之后,就可以逐级算出每一个fact(n-1),直到最后的fact(n),这就是递归函数的思维。
上面的函数可以写成:
# 使用递归函数求阶乘
def fact(n):
if n == 1:
return 1
else:
return n*fact(n-1)
print(fact(5))
执行结果为:
120
计算fact(5)时,可以根据函数定义看到计算过程如下:
===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120
在还没有求出fact(1)的时候,前面的fact(5), fact(4)等函数的调用都没有返回,等在那里,等待fact(n-1)的结果回来,好计算本次函数的返回值n*fact(n-1),直到fact(1)返回了确定的值1,然后逐级的fact(2)有了结果,然后fact(3)也有了结果,最后fact(5)也返回了确定的结果值,于是递归函数计算出了结果。
于是在逐级的等待中,fact(5), fact(4)等函数没有返回,没有返回时的函数,是放在一个栈的数据结构中的,调用结束时,从栈中删除。由于递归函数在执行过程中,前面n-1个函数都没有返回,所以都在栈中堆积。栈的大小有限,如果超出了范围,就会导致栈溢出。所以递归函数的调用次数不能过多。