### 递归函数
“”"
递归函数: 自己调用自己的函数时递归函数
递:去
归:回
一去一回叫做递归
“”"
简单递归
def digui(n):
print(n,"<===1===>")
if n > 0 :
digui(n-1)
print(n,"<===2===>")
digui(5)
“”"
去的过程:
n = 5 print(5 , “<=1=>”) 5 > 0 digui(5-1) <=> digui(4) <=> 当前代码在第14行,代码暂停阻塞.
n = 4 print(4 , “<=1=>”) 4 > 0 digui(4-1) <=> digui(3) <=> 当前代码在第14行,代码暂停阻塞.
n = 3 print(3 , “<=1=>”) 3 > 0 digui(3-1) <=> digui(2) <=> 当前代码在第14行,代码暂停阻塞.
n = 2 print(2 , “<=1=>”) 2 > 0 digui(2-1) <=> digui(1) <=> 当前代码在第14行,代码暂停阻塞.
n = 1 print(1 , “<=1=>”) 1 > 0 digui(1-1) <=> digui(0) <=> 当前代码在第14行,代码暂停阻塞.
n = 0 print(0 , “<=1=>”) 0 > 0 条件不满足,返回False,不执行调用,print(0,"<=2=>")
回的过程:
n = 1 从阻塞位置14行继续向下执行 print(1,"<=2=>")
n = 2 从阻塞位置14行继续向下执行 print(2,"<=2=>")
n = 3 从阻塞位置14行继续向下执行 print(3,"<=2=>")
n = 4 从阻塞位置14行继续向下执行 print(4,"<=2=>")
n = 5 从阻塞位置14行继续向下执行 print(5,"<=2=>")
到此代码全部执行结束 543210012345
“”"
“”"
递归函数有回的过程,有两种情况可以触发:
(1) 当最后一层函数全部执行结束的时候,有触底反弹的过程(回马枪),回到上层函数空间的调用处
(2) 遇到return 返回值,直接返回上层空间的调用处
函数在运行的时候,需要内存开辟空间才可以,这个空间叫做栈帧空间
递归:
(1)去的过程就是不停的开辟栈帧空间,在回的时候,就是在不停的释放栈帧空间,
递归函数就是不停的开辟和释放栈帧空间的一个完整的过程
(2)回的时候有两种触发的机制,要么是最后一层函数空间全部执行完毕,要么是遇到return,都会触底反弹(回马枪).
(3)写递归函数时候,必须给与跳出的条件,如果递归的层数过多,不推荐使用,容易内存溢出或者蓝屏
(4)递归调用每一层空间都是独立的个体,独立的副本,资源不共享,可以通过return来完成值的传递.
“”"
官方说法,递归最大深度是1000层,具体按照机器来看.
def deepfunc():
deepfunc()
deepfunc() # 996
1.求任意数n的阶乘 : 5! = 54321(阶乘要注意零的问题)
普通方法
def func(n):
total = 1
for i in range(1,n+1):
total *= i
"""
total = total * i => 1 * 1
total = total * i => 1 * 1 * 2
total = total * i => 1 * 1 * 2 * 3
total = total * i => 1 * 1 * 2 * 3 * 4
total = total * i => 1 * 1 * 2 * 3 * 4 * 5
"""
return total
res = func(5)
print(res)
递归写法
def jiecheng(n):
if n <= 1:
return 1
return n * jiecheng(n-1)
res = jiecheng(5)
print(res)
jiecheng(1) => 1
“”"
代码解析:
去的过程
n = 5 return 5 * jiecheng(5 - 1) => 5*jiecheng(4)
n = 4 return 4 * jiecheng(4 - 1) => 4*jiecheng(3)
n = 3 return 3 * jiecheng(3 - 1) => 3*jiecheng(2)
n = 2 return 2 * jiecheng(2 - 1) => 2*jiecheng(1)
n = 1 return 1
回的过程
n = 2 return 2*jiecheng(1) => 2*1 [jiecheng(2)]
n = 3 return 3*jiecheng(2) => 3*2*1 [jiecheng(3)]
n = 4 return 4*jiecheng(3) => 4*3*2*1 [jiecheng(4)]
n = 5 return 5*jiecheng(4) => 5*4*3*2*1 [jiecheng(5)]
res = jiecheng(5) <=> 5*4*3*2*1 = 120
“”"
尾递归(自己调用自己,并且非表达式) 把值放到参数中运算
“”"
无论调用多少次函数,都只占用一份空间
好处: 只需要考虑最后一层空间的结果是多少,就不用额外考虑回的过程了;
cpython解释器目前不支持.
“”"
def jiecheng(n,endval):
if n <= 1:
return endval
return jiecheng(n-1, endval*n)
res = jiecheng(5,1)
print(res)
优化一 (防止用户乱传参数)
def outer(n):
def jiecheng(n,endval):
if n <= 1:
return endval
return jiecheng(n-1, endval*n)
return jiecheng(n,1)
print(outer(5))
优化二 (防止用户乱传参数)
def jiecheng(n,endval=1):
if n <= 1:
return endval
return jiecheng(n-1, endval*n)
print(jiecheng(5))
“”"
代码解析:
去的过程
n = 5,endval = 1
return jiecheng(5-1,endval*n ) => return jiecheng(4,1*5)
n = 4,endval = 1*5
return jiecheng(4-1,endval*n ) => return jiecheng(3,1*5*4)
n = 3,endval = 1*5*4
return jiecheng(3-1,endval*n ) => return jiecheng(2,1*5*4*3)
n = 2,endval = 1*5*4*3
return jiecheng(2-1,endval*n ) => return jiecheng(1,1*5*4*3*2)
n = 1,endval = 1*5*4*3*2
if 1 <= 1 条件满足 return endval => return 1*5*4*3*2
回的过程
n = 2 return 1*5*4*3*2
n = 3 return 1*5*4*3*2
n = 4 return 1*5*4*3*2
n = 5 return 1*5*4*3*2
到此程序全部结束;
“”"
2.斐波那契数列 用递归 1 1 2 3 5 8 13 …
def feb(n):
if n ==1 or n == 2:
return 1
# 当前值n = 上一个值(n-1) + 上上个值(n-2)
return feb(n-1) + feb(n-2)
res = feb(5)
print(res)
#代码解析:
n = 5 return feb(4) + feb(3) <=> 3 + 2 => 5
feb(4) feb(3)
feb(3) + feb(2) feb(2) + feb(1)
feb(2)+feb(1)
feb(4) feb(3)
feb(3) + feb(2) feb(2) + feb(1)
1+1
feb(4) feb(3)
2 + 1 1 + 1
feb(4) = 3 feb(3) = 2
“”"