hongxiangping 2020-04-30
1.在一个函数体内调用它自身,被称为函数递归。函数递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
例1.己知有一个数列:f(0) = 1,f(1) = 4,f(n + 2) = 2*f(n+ 1) +f(n),其中 n 是大于 0 的整数,求 f(10) 的值?
分析:
f(10)=2*f(9)+f(8);f(9)=2*f(8)+f(7);f(8)=2*f(7)+f(6);f(7)=2*f(6)+f(5);f(6)=2*f(5)+f(4);f(5)=2*f(4)+f(3);f(4)=2*f(3)+f(2);f(3)=2*f(2)+f(1)==>f(1),f(2)已知,所以可以推出f(9),f(8)的值。所以我们的目的就是通过递归函数反复调用自身,直到将欲求函数的表达式用已知变量f(1),f(2)代替。
def fun(n): if n==0: return 1 elif n==1: return 4 else: return 2*fun(n-1)+fun(n-2) print(fun(10))
例2.如果把上面数学题改为如此。己知有一个数列:f(20)=1,f(21)=4,f(n + 2)=2*f(n+1)+f(n),其中 n 是大于 0 的整数,求 f(10) 的值?
分析:
fn(10) = fn(12)-2*fn(11),而 fn(11) =fn(13)-2*fn(12)……依此类推通过函数递归,直到 fn(19) 等于 fn(21)-2*fn(20),此时就可以得到 fn(19) 的值,然后依次反算到 fn(10) 的值
def fn(n) : if n == 20 : return 1 elif n == 21 : return 4 else : return fn(n + 2) - 2*fn(n + 1) print(fn(10))
运行结果:
10497 -3771
tips:仔细看上面递归的过程,当一个函数不断地调用它自身时,必须在某个时刻函数的返回值是确定的,即不再调用它自身:否则,这种递归就变成了无穷递归,类似于死循环。
因此,在定义递归函数时有一条最重要的规定: 递归一定要向已知方向进行。(对于求 fn(10) 而言,如果 fn(0) 和 fn(1) 是已知的,则应该采用 fn(n)=2*fn(n-1)+fn(n-2) 的形式递归,因为小的一端已知;如果 fn(20) 和 fn(21) 是已知的,则应该采用 fn(n)=fn(n+2)-2*fn(n+1) 的形式递归,因为大的一端已知。)
例3.用循环和递归分别求 ∑100 (求1到100的和)
#循环 def sum1(n): sum = 0 for i in range(1,n+1): sum+=i return sum print("循环累加:",sum1(100)) #递归 def sum2(n): while n==0: return 0 while n!=0: return n+sum2(n-1) print("递归累加1:",sum2(100)) def sum3(n): if n==1: return 1 else: return n+sum3(n-1) print("循环累加2:",sum3(100))
运行结果:
循环累加: 5050 递归累加1: 5050 循环累加2: 5050
例4.用循环和递归分别求 10!(阶乘)
#循环 def jiecheng1(n): res = 1 for i in range(1,n+1): res*=i return res print("循环阶乘:",jiecheng1(10)) #递归 def jiecheng2(n): while n==1: return 1 while n!=1: return n*jiecheng2(n-1) print("递归阶乘1:",jiecheng2(10)) def jiecheng3(n): if n==1: return 1 else: return n*jiecheng3(n-1) print("递归阶乘2:",jiecheng3(10))
运行结果:
循环阶乘: 3628800 递归阶乘1: 3628800 递归阶乘2: 3628800