2019.7.21 递归函数
递归函数:函数运行过程中会调用自身的函数
举例:阶乘 n!=1×2×3×……×(n-1)×n
def fact(n): if n==1: return 1 return n*fact(n-1) print(fact(1)) print(fact(5)) print(fact(10)) #结果 1 120 3628800
递归函数的构建有两个条件:1、有递归终止条件(如上文的if n==1) 2、能够达到递归终止条件(上文fact(n-1),n在每一层的递归中是不断减小的,而且可以减小到1)
递归的实现在计算机中依靠栈,递归层数越多则栈越多,所以要预防递归次数过多引起的栈溢出
fact(1000) Traceback (most recent call last): File "<input>", line 1, in <module> File "C:/Users/Le/Desktop/Test/T2.py", line 4, in fact return n*fact(n-1) File "C:/Users/Le/Desktop/Test/T2.py", line 4, in fact return n*fact(n-1) File "C:/Users/Le/Desktop/Test/T2.py", line 4, in fact return n*fact(n-1) [Previous line repeated 986 more times] File "C:/Users/Le/Desktop/Test/T2.py", line 2, in fact if n==1: RecursionError: maximum recursion depth exceeded in comparison
可以通过尾递归的方式解决栈溢出问题,尾递归是指,在函数返回时调用自身,且return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归优化,使得递归函数无论调用多少次本身,都只占用一个栈。
尾递归在本质上与循环等价,可以将循环视为特殊的尾递归
上文的fact(n),由于return n*fact(n-1)引入了乘法,所以不是尾递归,要修改成尾递归的方式,就要把每一步的乘积传入到递归函数中:
def fact(n): return fact_iter(n,1) def fact_iter(num,product): if num==1: return product return fact_iter(num-1,num*product)
fact_iter函数的return仅返回递归函数本身,不包含其他表达式,作为参数传入的乘法会在函数调用前计算好,不影响函数的调用,这样就构成了一个尾递归。
尾递归调用时,如果做了优化,栈不会增长,无论调用多少次递归函数都不会栈溢出
遗憾的是,大多数编程语言包括Python都没有对尾递归做优化,因此即使用了尾递归,也会在递归层次很大时导致栈溢出
What???这跟“欲练此功 必先自宫 即使自宫 未必成功”有什么区别??
https://www.liaoxuefeng.com/wiki/897692888725344/897693398334720

浙公网安备 33010602011771号