有一個列表l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88],用二分查找法實現查找
版本一:能夠實現查找,但由於切片會開辟新的內存存放列表新的列表,所以不能返回元素在原列表的下標
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] def find(l,site): half = len(l) // 2 #長度切一半,下標鎖定在范圍中間 if l[half] < site: #參數大於列表中間的元素,表面參數在列表右邊 new_l = l[half:] #從中間切到最后得到新的列表 find(new_l,site) #調用本身,傳入新的列表 elif l[half] > site: #參數小於列表中間的元素,表面參數在列表左邊 new_l = l[0:half+1] #從開始切到列表中間 find(new_l, site) #調用本身,傳入新的列表 else: #等於參數 print('找到了',l[half]) find(l,66)
版本二:不通過切片的方式,能夠返回元素下標位置,但還有細節可以改進
l = [2, 3, 5, 10, 15, 16, 18, 22, 26, 30, 32, 35, 41, 42, 43, 55, 56, 66, 67, 69, 72, 76, 82, 83, 88] def seek(l,arg,start = 0,end = len(l)) #接收列表起始和結尾的位置 long = (end - start) // 2 + start #結尾減去起始再切成一半,+start則是獲取右半邊范圍的起始位置 if l[long] < arg: #參數大於列表中間的元素,表面參數在列表右半邊 seek(l,arg,start = long+1,end = end) #新的查詢范圍鎖定在列表右半邊 elif l[long] > arg: #參數小於列表中間的元素,表面參數在列表左半邊 seek(l,arg,start = start,end = long-1) #新的查詢范圍鎖定在列表左半邊 else: print('找到了',long,l[long]) seek(l,66)
版本二升級:
1、函數的形參當中調用了已知列表l,應該考慮列表未知的情況
2、返回值的問題
l = [2, 3, 5, 10, 15, 16, 18, 22, 26, 30, 32, 35, 41, 42, 43, 55, 56, 66, 67, 69, 72, 76, 82, 83, 88] def seek(l,arg,start = 0,end = None):#關鍵字參數end默認為空 end = len(l) if end == None else end#如果為空,第一次進來用列表l的原始長度,不為空則用上一個end的值 if start < end: long = (end - start) // 2 + start if l[long] < arg: return seek(l,arg,start = long+1,end = end) elif l[long] > arg: return seek(l,arg,start = start,end = long-1) else: return '找到了,{}的位置在{}號'.format(l[long],long)#遞歸的返回值是逐級向上返回,所以需要每個條件都return else: return '未查到' print(seek(l,10))