首页 > 编程语言 >python 插值搜索-迭代与递归(Interpolation Search)

python 插值搜索-迭代与递归(Interpolation Search)

时间:2024-04-05 11:29:57浏览次数:15  
标签:Search arr python lo pos hi 搜索 low Interpolation

 

        给定一个由 n 个均匀分布值 arr[] 组成的排序数组,编写一个函数来搜索数组中的特定元素 x。 
        线性搜索需要 O(n) 时间找到元素,跳转搜索需要 O(? n) 时间,二分搜索需要 O(log n) 时间。 插值搜索是对实例二分搜索的改进,其中排序数组中的值是均匀分布的。

        插值在一组离散的已知数据点的范围内构造新的数据点。二分查找总是到中间元素去检查。

        另一方面,插值搜索可以根据正在搜索的键的值去不同的位置。例如,如果键的值更接近最后一个元素,则插值搜索很可能从末尾侧开始搜索。为了找到要搜索的位置,它使用以下公式。 

// 公式的思想是
当要搜索的元素更接近arr[hi]时,返回较高的pos值。 
// 当接近 arr[lo] 时值更小
arr[] ==> 需要查找元素的数组
x ==> 要搜索的元素
lo ==> arr[] 中的起始索引
hi ==> arr[] 中的结束索引

        有许多不同的插值方法,其中一种称为线性插值。线性插值采用两个数据点,我们假设为 (x1,y1) 和 (x2,y2),公式为:在点 (x,y) 处。
        该算法的工作原理类似于我们在字典中搜索单词。插值搜索算法改进了二分搜索算法。查找值的公式为:K = 数据-低/高-低。
        K是一个常数,用于缩小搜索空间。在二分查找的情况下,该常数的值为:K=(low+high)/2。

pos 的公式可以推导如下:
        我们假设数组的元素是线性分布的,直线的一般方程:y = m*x + c,y 是数组中的值,x 是其索引。
现在将 lo、hi 和 x 的值代入方程:
arr[hi] = m*hi+c ----(1) 
arr[lo] = m*lo+c ----(2) 
x = m* pos + c ----(3) 
m = (arr[hi] - arr[lo] )/ (hi - lo)
从 (3) x - arr[lo] = m * (pos - lo) 减去 eqxn (2) lo) 
lo + (x - arr[lo])/m = pos 
pos = lo + (x - arr[lo]) *(hi - lo)/(arr[hi] - arr[lo])

算法
除了上面的划分逻辑之外,插值算法的其余部分是相同的。 
        步骤1:在循环中,使用探针位置公式计算“pos”的值。 
        步骤2:如果匹配,则返回该项的索引,并退出。 
        步骤3:如果该项小于arr[pos],则计算左子数组的探针位置。否则,在右侧子数组中计算相同的值。 
        步骤4:重复直到找到匹配项或子数组减少到零。

下面是算法的实现: 

# Python3 program to implement
# interpolation search
# with recursion
 
# If x is present in arr[0..n-1], then
# returns index of it, else returns -1.
 
 
def interpolationSearch(arr, lo, hi, x):
 
    # Since array is sorted, an element present
    # in array must be in range defined by corner
    if (lo <= hi and x >= arr[lo] and x <= arr[hi]):
 
        # Probing the position with keeping
        # uniform distribution in mind.
        pos = lo + ((hi - lo) // (arr[hi] - arr[lo]) *
                    (x - arr[lo]))
 
        # Condition of target found
        if arr[pos] == x:
            return pos
 
        # If x is larger, x is in right subarray
        if arr[pos] < x:
            return interpolationSearch(arr, pos + 1,
                                       hi, x)
 
        # If x is smaller, x is in left subarray
        if arr[pos] > x:
            return interpolationSearch(arr, lo,
                                       pos - 1, x)
    return -1
 
# Driver code
 
 
# Array of items in which
# search will be conducted
arr = [10, 12, 13, 16, 18, 19, 20,
       21, 22, 23, 24, 33, 35, 42, 47]
n = len(arr)
 
# Element to be searched
x = 18
index = interpolationSearch(arr, 0, n - 1, x)
 
if index != -1:
    print("Element found at index", index)
else:
    print("Element not found")
 
# This code is contributed by Hardik Jain

输出
在索引 4 处找到的元素
时间复杂度:平均情况为O(log 2 (log 2 n)),最坏情况为 O(n) 
辅助空间复杂度: O(1) 

另一种方法:
这是插值搜索的迭代方法。
步骤1:在循环中,使用探针位置公式计算“pos”的值。 
步骤2:如果匹配,则返回该项的索引,并退出。 
步骤3:如果该项小于arr[pos],则计算左子数组的探针位置。否则,在右侧子数组中计算相同的值。 
步骤4:重复直到找到匹配项或子数组减少到零。

下面是算法的实现: 

# Python equivalent of above C++ code 
# Python program to implement interpolation search by using iteration approach
def interpolationSearch(arr, n, x): 
   
    # Find indexes of two corners 
    low = 0
    high = (n - 1) 
   
    # Since array is sorted, an element present 
    # in array must be in range defined by corner 
    while low <= high and x >= arr[low] and x <= arr[high]: 
        if low == high: 
            if arr[low] == x: 
                return low; 
            return -1; 
   
        # Probing the position with keeping 
        # uniform distribution in mind. 
        pos = int(low + (((float(high - low)/( arr[high] - arr[low])) * (x - arr[low])))) 
   
        # Condition of target found 
        if arr[pos] == x: 
            return pos 
   
        # If x is larger, x is in upper part 
        if arr[pos] < x: 
            low = pos + 1; 
   
        # If x is smaller, x is in lower part 
        else: 
            high = pos - 1; 
       
    return -1
   
# Main function
if __name__ == "__main__":
    # Array of items on whighch search will 
    # be conducted.
    arr = [10, 12, 13, 16, 18, 19, 20, 21,
           22, 23, 24, 33, 35, 42, 47]
    n = len(arr) 
   
    x = 18 # Element to be searched
    index = interpolationSearch(arr, n, x) 
   
    # If element was found
    if index != -1: 
        print ("Element found at index",index)
    else: 
        print ("Element not found")

输出
在索引 4 处找到的元素
时间复杂度:平均情况为 O(log2(log2 n)),最坏情况为 O(n) 
辅助空间复杂度: O(1)  

标签:Search,arr,python,lo,pos,hi,搜索,low,Interpolation
From: https://blog.csdn.net/hefeng_aspnet/article/details/137069869

相关文章

  • PHP 插值搜索(Interpolation Search)
            给定一个由n个均匀分布值arr[]组成的排序数组,编写一个函数来搜索数组中的特定元素x。         线性搜索需要O(n)时间找到元素,跳转搜索需要O(?n)时间,二分搜索需要O(logn)时间。插值搜索是对实例二分搜索的改进,其中排序数组中的值是均......
  • Python自学:类 构造方法练习(思路打不通,还遇到赋值错乱!)
    开始学习类一个练习,就是输入学生信息,并且要用到forinput结合,构造方法等。自己思考时,这个应该先设计一个类,然后用input输入,之前练习过main架构 tools调用两个py文件相互辅助,这个是不是也是,还有全局变量,想了很多结果不是,乱的。看了课件,用到forxinrange(1,11):开......
  • Python基础
    本人以前学习python基础时的两个简单实战1.模拟网上购物流程#创建空的购物车list=[]foriinrange(5):goods=input("请输入对应的商品编号和商品名称入库,每次只能输入一个产品:")list.append(goods)foriteminlist:print(item)#创建一个空列表,购物车......
  • Python线程池的概念涉及创建一个线程集合(即线程池)
    Python线程池的概念涉及创建一个线程集合(即线程池),这些线程预先被初始化并保存在内存中,等待任务的分配和执行。使用线程池可以有效地管理和复用线程资源,提高程序的执行效率。以下是Python线程池相关的概念及其示例程序:1.线程池(ThreadPool)线程池是一个管理线程的集合,它负责线......
  • LeetCode in Python 88. Merge Sorted Array (合并两个有序数组)
    合并有序数组也有两种方法,区别是空间复杂度不同。第一种,重新开辟一个数组空间,大小为O(m+n),另外需要三个指针分别指向两个有序数组和新开辟的数组,依次判断两个数组内元素大小,不断更新指针即可。第二种,无需单独开辟空间,在第一个数组(该数组空间足够存放两个数组总长的数据)内进行......
  • nodejs+python开发基于uniapp的校园跑腿系统 微信小程序
    本文先提出了开发基于uniapp的高校校园跑腿系统的背景意义,然后通过功能性和非功能性分析阐述本系统的需求,然后从功能设计和数据库设计两方面进行系统的设计建模。在技术实现部分采用了nodejs作为开发后台的编程语言,客户端使用uniapp,数据库选择MySQL。最后进行了代码的编写,并说......
  • 【python毕业设计】社区居民健康档案管理系统8cgo7
    典型的应用系统中还需要系统维护这一功能,其主要包括:(1)可以完成社区居民家庭和个人基本信息的维护和查询功能。(2)可以完成社区居民健康档案管理系统用户的添加、删除、修改等功能。(3)可以完成用户组的维护和用户组的查询功能。(4)可以完成数据备份和恢复的功能。(5)可以完成......
  • python3.12.2银河麒麟v10鲲鹏离线快速部署
    python3.12.2银河麒麟v10鲲鹏离线快速部署背景清明假期忙活了一整天发现自己方向走错了.部署效率巨慢无比.其实简单情况下很快就可以弄好.自己最开始使用python3.9使用的是libressl发现最新版已经不需要了.并且使用仓库中的就可以.系统版本说明公司的银河麒麟v10......
  • Python进阶:使用requests库轻松发送HTTP请求并获取响应
    Python进阶:使用requests库轻松发送HTTP请求并获取响应简介:本文将带您深入了解Python中强大的requests库,学会如何使用它发送各种HTTP请求,并轻松获取响应内容。无论您是初学者还是有一定经验的Python开发者,本文都将为您提供实用、详细的指导,助您在网络请求与响应的处理上更上......
  • python相机校准
    文章目录张正友标定法角点检测标定去畸变张正友标定法相片是三维世界在二维平面上的投射,故而其深度信息是损失掉了的。但是,如果把拍照看作理想的小孔成像过程,那么相片中的每个像素,都将通过一个锥体与世界中真实的点一一对应,这时如果再来一条参考光线,那么理论上就可......