python實現插值查找(遞歸、迭代)

算法思想

二分查找的改進,但中間值計算改成了利用公式預測數據所在的位置,該方法假設數據分佈是呈線性的,因此由公式(1)得到中間值 mid 的計算公式(2)。
midlowhighlow=valuedata[low]data[high]data[low](1)\frac{mid-low}{high-low}=\frac{value-data[low]}{data[high]-data[low]}(1)
mid=low+(highlow)(valuedata[low])data[high]data[low](2)mid=low+\frac{(high-low)*(value-data[low])}{data[high]-data[low]}(2)

分析

  1. 時間複雜度取決於數據分佈,數據分佈越平均,查找速度越快,平均而言優於O(logn)O(\log n)
  2. 數據也需要經過先排序。

注:來源於吳燦銘《圖解數據結構-使用Python》

代碼實現

import random

class Search(object):

    def interpolation_search(self, data, value):
        """
        插值查找迭代法實現
        :param data: list 待查找序列
        :param value: int 待查數據
        :return: int 索引(查找不到返回-1)
        """
        low = 0
        high = len(data) - 1
        while low <= high:
            # 數據分佈不均勻,data[high] = data[low]時會報錯
            mid = low + int(((value - data[low]) * (high - low)) / (data[high] - data[low]))
            # 邊界條件
            # 否則 當data=[1, 1, 1, 3, 4, 6, 6, 7, 9, 10],value=5時
            # 會一直死循環(low=5,hight=9,mid=4)
            if mid > high or mid < low:
                return -1
            if value == data[mid]:
                return mid + 1
            elif value < data[mid]:
                high = mid - 1
            elif value > data[mid]:
                low = mid + 1
        return -1

    def interpolation_search_recursion(self, data, low, high, value):
        """
        插值查找遞歸法實現
        :param data: list 待查找序列
        :param low: int low指針
        :param high: int high指針
        :param value: int 待查數據
        :return: int 索引(查找不到返回-1)
        """
        if low <= high:
            mid = low + int(((value - data[low]) * (high - low)) / (data[high] - data[low]))
            if value < data[mid]:
                return self.binary_search_recursion(data, low, mid - 1, value)
            elif value > data[mid]:
                return self.binary_search_recursion(data, mid + 1, high, value)
            else:
                return mid + 1
        return -1


def main():
    search = Search()
    data = [0] * 10
    for index in range(len(data)):
        data[index] = random.randint(1, 10)
    data = sorted(data)
    print("待查找序列:", data)
    res_index = search.interpolation_search(data, 5)
    print("結果索引爲:", res_index)
    res_index = search.interpolation_search_recursion(data, 0, len(data) - 1, 5)
    print("結果索引爲:", res_index)


if __name__ == '__main__':
    main()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章