1、递归:
人理解函数,神理解递归。
函数调用函数本身,就叫递归。
一般递归100次都没解决的问题,那么放弃递归。
测试递归最大深度:
count = 0 def func1(): global count count += 1 print(count) func1() func1()
从上面的例子可以看出,递归的默认深度为998,但是递归深度可以修改
import sys print(sys.setrecursionlimit(1100)) count = 0 def func1(): global count count += 1 print(count) func1() func1()
递归深度也取决于电脑的配置,配置低则深度就低,配置高,则递归深度就高
示例:
"""
年龄问题:
1、问eric今年几岁,他说比tom大两岁
2、问tom今年几岁,他说比olia大两岁
3、问olia今年几岁,他说比张三大两岁
4、问张三今年几岁,他说他今年31岁
用递归求eric 年龄
"""
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 def age(a): 2 if a == 1: 3 return 31 4 else: 5 return age(a-1) + 2 6 print(age(4)) 7 8 结果:37
解析:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 def age(4): 2 if a == 1: 3 return 31 4 else: 5 return age(a-1) + 2 age(3) + 2 age(3)就等于35 然后在 + 2,返回给age(4),age(4) 就等于37 6 7 def age(3): 8 if a == 1: 9 return 31 10 else: 11 return age(a-1) + 2 age(2) + 2 age(2)就等于33 然后在 + 2,返回给age(3) 12 13 def age(2): 14 if a == 1: 15 return 31 16 else: 17 return age(a-1) + 2 age(1) + 2 age(1)就等于31 然后在 + 2,返回给age(2) 18 19 def age(1): 20 if a == 1: 21 return 31 到这一步,返回31给age(1) 22 else: 23 return age(a-1) + 2 age(0) + 2
2、二分查找:
错误的写法,因为每次切片改变了原列表的长度,同时也改变了原列表的索引
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 l = [1,7,9,11,13,14,17,19,20,21,22,25,26,27,30,35,41,55,61,67,80] 2 def recursion(l,aim): 3 aim_index = len(l) // 2 4 if aim > l[aim_index]: 5 return recursion(l[aim_index:],aim) 6 elif aim < l[aim_index]: 7 return recursion(l[:aim_index],aim) 8 elif aim == l[aim_index]: 9 return aim_index 10 else: 11 return '没有这个数' 12 print(recursion(l,13))
正确写法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 l = [1,7,9,11,13,14,17,19,20,21,22,25,26,27,30,35,41,55,61,67,80] 2 def recursion(l, aim, start=0, end=len(l)-1): # start=0表示列表的初始索引,end=len(l)-1表示列表的最后那个值,以为列表通过索引取值是顾头不顾尾的 3 aim_index = (end - start) // 2 + start # (end - start)表示取切片后列表的长度,在整除2后加start的值表示原有列表长度 4 if end >= start: 5 if aim > l[aim_index]: 6 return recursion(l, aim, start=aim_index+1, end=end) # 当取的值大于中间的值时,start=aim_index+1表示中间索引值加1,end=end表示源列表的最后的索引值不变,这样取到的就是后面一半列表的长度,但是原有列表的长度没变 7 elif aim < l[aim_index]: 8 return recursion(l, aim, start=0, end=aim_index - 1) # 当取的值小于中间值时,start=0不变表示原有列表的起始索引值,end=aim_index-1表示中间索引值减1,取列表的左半部分的长度,原有列表的长度不变 9 elif aim == l[aim_index]: # 如果取的值等会中间索引值的话,就直接返回给原函数的执行者,就是函数名 10 return aim_index 11 else: 12 return '没有这个数' 13 else: 14 return '没有这个数' 15 16 print(recursion(l, 22))