从前有有座山,山里有座庙,庙里有个老和尚给小和尚们讲故事,讲的什么呀,讲的是,从前有有座山,山里有座庙,庙里有个老和尚给小和尚们讲故事,讲的什么呀?讲的是?......
递归:1、一个函数再内部调用了自己,这种写法就叫递归( recursion)。
2、递归额层数 在pytohn 里是有限制
3、写递归函数必须要有一个结束条件
例1:求阶乘 n= 7 7*6*5*4*3*2*1
1 def func(n): 2 if n == 1: 3 return 1 4 return n*func(n-1) 5 6 print(func(4)) 7 8 #分解步骤 9 n = 4 10 def func(4):#4*6 = 24 func(3)*4 11 if 4 == 1: 12 return 1 13 return 4*func(3)#当N=4时,if 条件不成立,先执行了func(3)然后进入下一步了递的过程 14 n = 3 15 def func(3): 16 if 4 == 1: 17 return 1 18 return 3*func(2)#当N=3时,if 条件不成立,先执行了func(2)然后进入下一步了以此类推 19 #下面说了。fun(2) =2 又到上一部 3*2=6 20 n = 2 21 def func(2): 22 if 2 == 1: 23 return 1 24 return 2*func(1) #2*1 =2 又回归到上一步 25 n = 1 26 def func(1): 27 if 1 == 1: 28 return 1#当N=1时,妇fun(1) =1 又执行回归的过程
例2 用递归函数,找索引 lis = [2,3,4,6,7,9,12,16,19,21,25,35,43,57,66,84,88,92,94,99]
1 # lis = [2,3,4,6,7,9,12,16,19,21,25,35,43,57,66,84,88,92,94,99] 2 #print(lis.index(57))13 3 # index = 0 4 # for i in lis: 5 # if i == 57: 6 # print(index) 7 # index += 1 8 #这种找法太慢,如果序列有100W个数字呢? 9 #所有使用2分算法 每次把列表分成一半来找 10 #思路1 11 # def search(num,lis): 12 # #先找中间的数字 13 # mid = len(lis)//2 #整除 14 # if lis[mid] > num :#如果中间的值大于要找的值 15 # lis = lis[0:mid]#那就从前面找值 16 # search(num,lis)#再去前面值得中间值因为lis已经改变 17 # elif lis[mid] <num :#如果中间的值小于要找的值 18 # lis = lis[mid+1:]#从后面找 19 # search(num,lis)#去后面值得中间值因为lis已经改变 20 # elif lis[mid] == num: 21 # return lis[mid] 22 #这个程序是错误的,因为你找的时候列表变小了。不是原来的列表了 23 #思路2 24 #你不能改变列表,你要改变索引的位置 25 lis = [2,3,4,6,7,9,12,16,19,21,25,35,43,57,66,84,88,92,94,99] 26 def search(num,lis,start = None,end=None): 27 start = start if start else 0#如果start没值使用0,有值使用传的值 28 end = end if end else len(lis)-1#如果end没值就计算,有值使用传的值 29 #先找中间的数字 30 mid = (end - start)//2 + start 31 #mid = (end-start) //2 这样不对,如果索引缩小后,值就不正确必须加前面的数字 32 if lis[mid] > num :#如果中间的值大于要找的值从左开始, 33 return search(num,lis,start,mid-1)#修改索引的位置从做开始从中间-1结束 34 elif lis[mid] < num :#如果中间的值小于要找的值从右开始, 35 return search(num,lis,mid+1,end)#中间开始,最后结束 36 elif lis[mid] == num: 37 return mid,lis[mid] 38 print(search(57,lis)) 39 #此函数只有递的过程没有归的过程
例3 三级菜单实例
1 #三级菜单 2 menu = {'北京':{ 3 '海淀':{ 4 '永定路':{}, 5 '香山街':{} 6 }, 7 '朝阳区':{ 8 '小红门':{}, 9 '太阳宫':{}, 10 '潘家园':{} 11 } 12 } 13 ,'陕西':{ 14 '西安':{ 15 '临潼区':{ 16 '兵马俑':{} 17 }, 18 '碑林区':{ 19 '大雁塔':{} 20 } 21 }, 22 '宝鸡':{ 23 '凤翔县':{ 24 '长青镇':{} 25 }, 26 '岐山县':{ 27 '某某镇':{} 28 } 29 } 30 } 31 ,'甘肃':{'兰州':{ 32 '安宁区':{ 33 '黄河':{} 34 }, 35 '城关区':{ 36 '乌金峡':{} 37 } 38 }, 39 '天水':{ 40 '秦州区':{ 41 '县家路':{} 42 }, 43 '麦积区':{ 44 '麦积山':{} 45 } 46 } 47 48 }} 49 def Three_Level_Menu(menu): 50 while True:#如果输入的菜单不存在,就让用户一直输入。 51 for name in menu:print(name)#显示第一级菜单 52 key = input('请输入名称,如果退出请输入‘Q/q,如果返回上一层请输入B/b',) 53 if key.lower() == 'b':break#只跳出了当前函数的循环, 54 elif key.lower() == 'q':#和 ret相互结合,直接退出整个函数() 55 return 'q' 56 elif key in menu: 57 # for key1 in menu[key]:print(key1)# 打印2级菜单 58 # key2 = input('请输入名称') 59 #有没有发现上面2行代码,和函数定义的第一行和第二行基本差不多一样? 60 #相同的数据类型嵌套在一起,是不是感觉可以用递归呢?是不是感觉进入一个轮回? 61 #那我们继续调用这个函数即可 62 ret = Three_Level_Menu(menu[key])#不能继续传入menu了,不然和原来的菜单一样了 63 if ret == 'q': return 'q' 64 Three_Level_Menu(menu)