函数调用自己的编程方式被称为函数的递归调用。递归通常能够将一个大型的复杂问题的递归条件,一层一层的回溯到终止条件,然后再根据终止条件的运算结果,一层一层的递进运算到满足全部的递归条件。它能够使用少量程序描述出解题过程中的重复运算部分,减少程序的代码量。要使用递归的方式进行编程,需要在编程的时候规划好终止条件,写好递归条件,用回溯的逻辑方法解决问题。
下面我们来举个例子:
1.使用递归函数,求斐波那契数列的前10个数
def fib(n):
if n==1 or n==0:
return 1
else:
return fib(n-2)+fib(n-1)
for n in range(10):
print(fib(n),end='\t')
说明:斐波那契数列是一个常用的数学数列,第n个斐波那契数fib(n)由以下两个条件决定:
(1) n = 0或n = 1时:
fib(0) = 1,fib(1) = 1
(2) n > 1时:
fib(n) = fib(n-1) + fib(n-2)
【代码分析】
(1) 第1行,在定义一个名为fib的函数,传递给这个函数的参数为n。
(2) 由题设,斐波那契数列中,n == 0或n == 1时,fib(0) 与fib(1) 都等于 1,我们把这个叫做终止条件。
(3) 第2、3行,在程序中实现终止条件。终止条件,一般都会给定一个或多个数值,或实现某些特定操作。
(4) 由题设,斐波那契数列中,从第三个数开始,第n个斐波那契数的数值,是由公式fib(n) = fib(n-1) + fib(n-2)计算得到,我们称这个是递归条件。
(5) 第5行,在程序中实现了递归条件。
(6) 第7、8行,使用循环,传递0到9,共10个数字进fib函数。
(7) 当n == 0 和n == 1时,fib的返回值都为1。
(8) 当n == 2时,第3行不会运行,会运行第5行。第5行中,会调用fib(0)和fib(1),会执行:fib(2) = fib(0) + fib(1)。
(9) 当n == 3时,第2行、第3行不会运行,会运行第5行。第5行中,会调用fib(1)和fib(2),会执行:fib(3) = fib(1) + fib(2)。但是fib(2)此时会重复(7)中所描述的动作,所以此时fib(3) = fib(1) + fib(2) = fib(1) + (fib(0) + fib(1))。
(10) 当n == 4时,第2行、第3行不会运行,会运行第5行。第5行中,会调用fib(2)和fib(3),会执行:fib(4) = fib(2) + fib(3)。但是fib(2)此时会重复(7)中所描述的动作,fib(3)会重复(8)中所描述过程,所以此时fib(4) = fib(2) + fib(3) = (fib(0) + fib(1)) + (fib(1) + fib(2)) = (fib(0) + fib(1)) + (fib(1) + (fib(0) + fib(1)))。
每次n无法满足终止条件时,fib(n)都会回溯到fib(n-1)和fib(n-2),只有当n满足了终止条件(n == 0和n == 1)时,fib(n)才会返回一个确定值,然后根据这个确定的值开始计算。简单的说,递归函数,会执行上述过程……、(10)、(9)、(8),直到(7)。
注意:
当递归层数超过了系统允许的最大递归深度。默认情况下,当递归调用到1000层,Python解释器将终止程序。递归深度是为了防止无限递归错误而设计的,当用户编写的正确递归程序需要超过1000层时,可以通过如下代码设定:
import sys
sys.setrecursionlimit(2000) #2000是新的递归层数