【算法与数据结构】二分查找、插值查找、斐波那契查找—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)

 

posted @ 2020-07-31 10:12  DJames23  阅读(199)  评论(0编辑  收藏  举报