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 年龄

"""

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
View Code

解析:

 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
View Code

2、二分查找:

错误的写法,因为每次切片改变了原列表的长度,同时也改变了原列表的索引

 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))
View Code

正确写法:

 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))
View Code

 

 

 

posted on 2018-06-19 16:23  花豆豆  阅读(467)  评论(0编辑  收藏  举报