zoukankan      html  css  js  c++  java
  • 【算法与数据结构】二分查找、插值查找、斐波那契查找—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)
  • 相关阅读:
    3-AII--BroadcastReceiver实现锁、开屏、短信监听
    grpc入门2
    关于golang中某些包无法下载的解决方法
    grpc入门
    grpc安装
    小鼠试毒问题(二进制)
    gomod
    POJ 1743 Musical Theme ——后缀数组
    SPOJ DISUBSTR ——后缀数组
    BZOJ 4066 简单题 ——KD-Tree套替罪羊树
  • 原文地址:https://www.cnblogs.com/DJames23/p/13408141.html
Copyright © 2011-2022 走看看