【算法与数据结构】二分查找、插值查找、斐波那契查找—Python实现
1 # 二分查找 2 def BinarySearch(arr, left, right, findVal): 3 print("二分查找") 4 # 找到就返回 5 if left > right: 6 return -1 7 mid = (left + right) // 2 # 中间值索引 8 midVal = arr[mid] # 中间值 9 if findVal > midVal: # 要查找的值大于中间值则向右递归 10 return BinarySearch(arr, mid+1, right, findVal) 11 elif findVal < midVal: # 要查找的值小于中间值则向左递归 12 return BinarySearch(arr, left, mid-1, findVal) 13 else: # 找到后返回 14 return mid 15 16 17 def insertSearch(arrA, left, right, findVal): 18 # 插值查找 19 # 找到就返回 20 print("差值查找") 21 # 必须添加findVal > arrA[len(arrA)-1] or findVal < arrA[0]两个条件,防止index超出边界 22 if left > right or findVal > arrA[len(arrA)-1] or findVal < arrA[0]: 23 return -1 24 mid = left + (right - left) * (findVal - arrA[left]) // (arrA[right] - arrA[left]) 25 midVal = arrA[mid] # 中间值 26 if findVal > midVal: # 要查找的值大于中间值则向右递归 27 return BinarySearch(arrA, mid+1, right, findVal) 28 elif findVal < midVal: # 要查找的值小于中间值则向左递归 29 return BinarySearch(arrA, left, mid-1, findVal) 30 else: # 找到后返回 31 return mid 32 33 34 def binarySearch2(arr, left, right, findVal): 35 non = [] # 找不到就返回空列表 36 resArr = [] # 找到后将索引添加到此列表 37 if left > right: 38 return non 39 mid = (left + right) // 2 40 # 二分查找相当于是用中间值参与运算 41 # mid = left + (right - left) * (midValue - arr[left]) / (arr[right] - arr[left]) 42 # 下面是插值查找 43 # mid = left + (right - left) * (findVal - arr[left]) / (arr[right] - arr[left]) 44 midValue = arr[mid] 45 if findVal > midValue: 46 return binarySearch2(arr, left, mid+1, findVal) 47 elif findVal < midValue: 48 return binarySearch2(arr, mid-1, right, findVal) 49 else: 50 temp = mid-1 51 while True: 52 if temp < 0 or arr[temp] != findVal: 53 # 若当前索引已超过左边界或者当前值不等于要查找的值就退出 54 break 55 resArr.append(temp) # 找到后添加到了表 56 temp -= 1 57 resArr.append(mid) # 将中间值添加到列表 58 temp = mid + 1 59 while True: 60 if temp > len(arr)-1 or arr[temp] != findVal: 61 # 向右查找 62 break 63 resArr.append(temp) 64 temp += 1 65 return resArr 66 67 68 if __name__ == '__main__': 69 # 二分查找,找到所有值 70 arr = [1,24,35,67,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,1234] 71 resArr = binarySearch2(arr, 0, len(arr)-1, 89) # 向左查找时索引值会倒序排列 72 resArr = sorted(resArr) # 将找到的索引值排序 73 print("二分查找结果为", resArr) 74 75 # 插值查找与二分查找次数比较 76 # 插值查找 77 arrA = [i + 1 for i in range(100)] # [1,2,3,.....100] 78 print(arrA) 79 resA = insertSearch(arrA, 0, len(arrA)-1, 99) 80 print(resA) 81 # 二分查找 82 res = BinarySearch(arrA, 0, len(arrA)-1, 99) 83 print(res)
----------------------------------------------------------------------------------------
2020.8.4更新
斐波那契查找代码如下:
1 def Fib(): 2 # 生成斐波那契数列[1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 3 arr = [0 for i in range(10)] 4 arr[0] = 1 5 arr[1] = 1 6 i = 2 7 while i < len(arr): 8 arr[i] = arr[i - 1] + arr[i - 2] 9 i += 1 10 return arr 11 12 13 def FibSearch(arr, key): 14 low = 0 15 high = len(arr) - 1 16 k = 0 17 f = Fib() 18 print(f) 19 while high > f[k] - 1: 20 # 寻找k值 21 k += 1 22 temp = arr 23 while f[k] > len(temp): 24 # 将待查找数列的最大值填充到扩充后的数组 25 temp.append(arr[high]) 26 while low <= high: 27 mid = low + f[k-1] - 1 # 找到中间值 28 if temp[mid] > key: 29 high = mid - 1 # 向前寻找,mid值前面有f[k-1]-1个值,在这个数量中在找到一个黄金分割点 30 k -= 1 31 elif temp[mid] < key: # 向后寻找 32 low = mid + 1 33 k -= 2 34 else: 35 if mid >= high: 36 return high 37 else: 38 return mid 39 return -1 40 41 42 if __name__ == '__main__': 43 arr = [3, 56, 78, 90, 123, 345, 5678] 44 index = FibSearch(arr, 345) 45 print(index)