day 14 递归 二分法
递归
递归就是函数自己调自己,官方给的递归最大深度为1000,永远也跑不到1000,我实测是998
#例1 def func(): print("我是递归") func() func() #例2 import os def func(lujing,n): lst = os.listdir(lujing) for i in lst: path = os.path.join(lujing,i) #判断是文件还是文件夹 if os.path.isdir(path): print("..." * n,i) func(path,n + 1 ) else: print(i) func("e:/a",0)
二分法
二分法查找,每次能够除掉一半的数据,查找效率非常高,但是局限性比较大,必须是有序序列才可以使用二分法查找 缺点:所有数据必须是有序序列
方法1:切片查找
lst = [1,3,42,2,4,2,51,53,5,2,34,6,4,12,3] lst1 = sorted(lst) # [1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 12, 34, 42, 51, 53] #排序后的数据 n = int(input("请输入你要找的数字>>>")) left = 0 right = len(lst1) -1 #这里"-1" 是因为索引是从0开始数的,len计算的长度是从1开始数,所以会大于索引的位置. while left <= right: #这里用 "<=" 是为了判断最后一个数字 index_site = (left + right) // 2 #索引只能是整数,这里用地板除,整除得到索引的位置,把索引放在while循环里是为了让每次查找数字的时候缩小范围. if n > lst1[index_site]: #若果用户输入的数字大于列表里面的索引 left = index_site + 1 #左边的指针向索引位置移动,缩小查找范围从右边查找 elif n < lst1[index_site]: #如果用户输入的数字小于列表例的索引 right = index_site -1 #右边的指针向索引位置移动,缩小范围从左边查找 else: print('已经找到你要的数字,位置是:"%s"' % index_site) break #找到数据后要退出循环 else: print('你要的数字不在此列表中')
方法2:递归版本二分法
def func(n,lst,left=0,right = None): #定义形参,n为要查找的数字,lst为列表,left(左边的长度)可以默认都是0,right(右边的长度)也可以默认都是列表的总长度,但是函数不让直接写len所以先定义None用函数体的功能来改. if right == None: right = len(lst) -1 #用函数体的功能来更改right的值 if left <= right: index_site = (left + right) // 2 if n > lst[index_site]: left = index_site + 1 elif n < lst[index_site]: right = index_site - 1 else: return True return func(n,lst,left,right) #当函数体的功能执行完一遍,并且没找到数据的时候,用递归来反复执行查找,这里必须用return把数据返回给调用者,否者就会返回None else: return False lst = [1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 12, 34, 42, 51, 53] ret = func(1,lst) print(ret)
方法3:另类二分法,很难计算位置(非常耗内存,不建议使用,仅供参考)
def binary_search(ls, target): left = 0 right = len(ls) - 1 if left > right: print("不在这里") middle = (left + right) // 2 if target < ls[middle]: return binary_search(ls[:middle], target) elif target > ls[middle]: return binary_search(ls[middle+1:], target) else: print("在这里") binary_search(lst, 567)