插值查找算法

article/2025/9/30 5:53:39

插值查找算法

插值查找算法又称插值搜索算法,是在二分查找算法的基础上改进得到的一种查找算法。

插值查找算法只适用于有序序列,换句话说,它只能在升序序列或者降序序列中查找目标元素。作为“改进版”的二分查找算法,当有序序列中的元素呈现均匀分布时,插值查找算法的查找效率要优于二分查找算法;反之,如果有序序列不满足均匀分布的特征,插值查找算法的查找效率不如二分查找算法。

所谓均匀分布,是指序列中各个相邻元素的差值近似相等。例如,{10, 20, 30, 40, 50} 就是一个均匀分布的升序序列,各个相邻元素的差值为 10。再比如 {100, 500, 2000, 5000} 是一个升序序列,但各相邻元素之间的差值相差巨大,不具备均匀分布的特征。

插值查找算法的解题思路

对于已经学过二分查找算法的读者来说,学习插值查找算法会变得非常容易,因为插值查找算法完全照搬了二分查找算法的解题思路,仅对一些实现细节做了修改。

首先,我们通过一个实例回忆一下二分查找算法的解题思路。例如,在 {1,2,3,4,5,6,7,8,9,10} 升序序列中查找元素 2,二分查找算法的查找过程如下图所示:

在这里插入图片描述

图 1 二分查找算法的实现过程

如图 1 所示,先找到搜索区域中的中间元素,然后和目标元素进行比较,如果相同表示查找成功;反之,根据比较结果选择中间元素左侧或右侧的区域作为新的搜索区域,以同样的方式继续查找。

插值查找算法的解题思路和二分查找算法几乎相同,唯一的区别在于,每次与目标元素做比较的元素并非搜索区域内的中间元素,此元素的位置需要通过如下公式计算得出:

Mid = Begin + ( (End - Begin) / (A[End] - A[Begin]) ) * (X - A[Begin])

式子中,各部分的含义分别是:

Mid:计算得出的元素的位置;

End:搜索区域内最后一个元素所在的位置;

Begin:搜索区域内第一个元素所在的位置;

X:要查找的目标元素;

A[]:表示整个待搜索序列。

为了方便讲解,我们仍将 Mid 位置上的元素称为 “中间元素”。

使用插值查找算法在 {1,2,3,4,5,6,7,8,9,10} 升序序列中查找元素 2,查找过程如下:

  1. 假设序列中各个元素的位置为 0~9,搜索区域为整个序列,通过公式计算出 “中间元素” 的位置:

Mid = 0 + ( (9-0)/(10-1) ) * (2-1) = 1

“中间元素” 的位置为 1,也就是元素 2,显然这是我们要找的目标元素,查找结束。整个查找过程如下所示:

在这里插入图片描述

图 2 插值查找算法的实现过程

对比图 1 和图 2 不难看出,在 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 这个满足均匀分布的升序序列中查找元素 2,插值查找算法的执行效率要优于二分查找算法。

插值查找算法的具体实现

如下用伪代码给大家展示了插值查找算法的具体实现过程:

输入 arr[]               // 输入有序序列
输入 ele                 // 输入查找的目标元素  
interpolation_search( arr , begin , end , ele):      // [begin,end] 指定搜索区域,ele 为要搜索的目标元素// [begin,end] 不存在时,返回一个错误值(比如 -1)if begin > end: return -1// [begin,end] 只包含 1 个元素时,判断此元素是否为目标元素if begin == end:if ele == arr[begin]:return beginelse:return -1// 找到 [begin,end] 区域“中间值”的下标mid <- begin + ( (end-begin)/(arr[end] - arr[begin]) * (ele - arr[begin]) )// 递归的出口,即 ele 和中间元素的值相等if ele == arr[mid]:                                   return midif ele < arr[mid]:         // 比较 ele 和中间元素的值,进一步缩小搜索区域return binary_search(arr , begin , mid-1 , ele)else:return binary_search(arr , mid+1 , end , ele)

结合伪代码,如下是使用插值查找算法在 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 序列中查找元素 2 的 C 语言程序:

#include <stdio.h>
//实现插值查找算法,ele 表示要查找的目标元素,[begin,end] 指定查找区域
int interpolation_search(int* arr, int begin, int end, int ele) {int mid = 0;//如果[begin,end] 不存在,返回 -1if (begin > end) {return -1;}//如果搜索区域内只有一个元素,判断其是否为目标元素if (begin == end) {if (ele == arr[begin]) {return begin;}//如果该元素非目标元素,则查找失败return -1;}// 找到"中间元素"所在的位置mid = begin + ((end - begin) / (arr[end] - arr[begin]) * (ele - arr[begin]));//递归的出口if (ele == arr[mid]) {return mid;}//比较 ele 和 arr[mid] 的值,缩小 ele 可能存在的区域if (ele < arr[mid]) {//新的搜索区域为 [begin,mid-1]return interpolation_search(arr, begin, mid - 1, ele);}else {//新的搜索区域为 [mid+1,end]return interpolation_search(arr, mid + 1, end, ele);}
}
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//输出元素 2 所在位置的下标int pos = interpolation_search(arr, 0, 9, 2);if (pos != -1) {printf("%d", interpolation_search(arr, 0, 9, 2));}else {printf("查找失败");}return 0;
}

如下是使用插值查找算法在 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 序列中查找元素 2 的 Java 程序:

public class Demo {// 实现插值查找算法,ele 表示要查找的目标元素,[begin,end] 指定查找区域public static int interpolation_search(int[] arr, int begin, int end, int ele) {// 如果[begin,end] 不存在,返回 -1if (begin > end) {return -1;}//如果搜索区域内只有一个元素,判断其是否为目标元素if (begin == end) {if (ele == arr[begin]) {return begin;}//如果该元素非目标元素,则查找失败return -1;}// 找到中间元素所在的位置int mid = begin + ((end - begin) / (arr[end] - arr[begin]) * (ele - arr[begin]));// 递归的出口if (ele == arr[mid]) {return mid;}// 比较 ele 和 arr[mid] 的值,缩小 ele 可能存在的区域if (ele < arr[mid]) {// 新的搜索区域为 [begin,mid-1]return interpolation_search(arr, begin, mid - 1, ele);} else {// 新的搜索区域为 [mid+1,end]return interpolation_search(arr, mid + 1, end, ele);}}public static void main(String[] args) {int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// 输出目标元素 2 所在位置的下标int add = interpolation_search(arr, 0, 9, 2);if(add != -1) {System.out.print(add);}else {System.out.print("查找失败");}}
}

如下是使用插值查找算法在 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 序列中查找元素 2 的 Python 程序:

#实现插值查找算法,ele 表示要查找的目标元素,[begin,end] 指定查找区域
def interpolation_search(arr,begin,end,ele):#如果[begin,end] 不存在,返回 -1if begin > end:return -1if begin == end:if arr[begin] == ele:return beginreturn -1#找到中间元素所在的位置mid = int(begin + ((end - begin) / (arr[end] - arr[begin]) * (ele - arr[begin])))#递归的出口if ele == arr[mid]:return mid#比较 ele 和 arr[mid] 的值,缩小 ele 可能存在的区域if ele < arr[mid]:return interpolation_search(arr,begin,mid-1,ele)else:return interpolation_search(arr,mid+1,end,ele)
arr = [1,2,3,4,5,6,7,8,9,10]
#输出元素 2 所在位置的下标
add = interpolation_search(arr, 0, 9, 2);
if add != -1:print(add)
else:print("查找失败")

以上程序的输出结果均为:

1


http://chatgpt.dhexx.cn/article/wNYfZ2rN.shtml

相关文章

图像常用的插值算法:最近邻插值、双线性插值和双三次插值算法

图像常用的插值算法 最近邻插值算法双线性插值算法双三次插值(bicubic)算法三种插值算法的优缺点 插值算法是图像缩放中的一项基本且重要的算法&#xff1b;在图像缩放中&#xff0c;输出图像像素点坐标可能对应输入图像上几个像素点之间的位置&#xff0c;这个时候就需要通过灰…

插值拟合算法

一.插值算法 1.插值概念 构造一个函数使得所有已知点在函数图像上 2.一维插值插值方法 &#xff08;1&#xff09;一般多项式插值 &#xff08;2&#xff09;拉格朗日插值 &#xff08;3&#xff09;分段线性插值 采用线性函数 &#xff08;4&#xff09;牛顿插值 &#xf…

插值与逼近_数值分析计算方法

传送门&#xff1a; 线性和非线性方程数值解法_数值分析计算方法 &#x1f449;插值与逼近_数值分析计算方法 ⚠️施工中&#x1f477;… 1 插值 1.1 多项式插值 1.1.1 Lagrange插值 插值误差的事后估计&#xff1a;用两个结果的差来估计插值误差 使用注意 当插值点x位于…

数学建模-插值算法(Matlab)

注意&#xff1a;代码文件仅供参考&#xff0c;一定不要直接用于自己的数模论文中 国赛对于论文的查重要求非常严格&#xff0c;代码雷同也算作抄袭 如何修改代码避免查重的方法&#xff1a;https://www.bilibili.com/video/av59423231 //清风数学建模 一、基础知识 简单来说…

插值算法总结

1、最邻近元法 这是最简单的一种插值方法&#xff0c;不需要计算&#xff0c;在待求象素的四邻象素中&#xff0c;将距离待求象素最近的邻象素灰度赋给待求象素。设iu, jv(i, j为正整数&#xff0c; u, v为大于零小于1的小数&#xff0c;下同)为待求象素坐标&#xff0c;则待求…

插值算法基本原理

插值&#xff1a;数据处理的手段 将缺失数据补全处理 线性内插 拉格朗日插值法 牛顿插值 拟合&#xff1a;预测&#xff0c;寻找规律的手段 是插值的外延 插值算法&#xff1a;使用在现有的数据极少&#xff0c;不足以支撑分析的进行&#xff0c;这时就需要使用一些数学方法…

插值算法——分段线性插值(1)

首先&#xff0c;科普一下插值的含义&#xff1a;在离散数据的基础上补插连续函数&#xff0c;使得这条连续曲线通过全部给定的离散数据点。 插值是离散函数逼近的重要方法&#xff0c;利用它可通过函数在有限个点处的取值状况&#xff0c;估算出函数在其他点处的近似值。 插…

Matlab实现常见的插值算法

本文介绍如何使用 Matlab 实现常见的插值算法&#xff1a;分段三次埃尔米特插值和三次样条插值。 分段三次埃尔米特插值 (1) pchip&#xff08;x, y, new_x&#xff09;函数表示分段三次埃尔米特插值&#xff0c;x表示已有的数据 点&#xff0c;y表示数据点代表的纵坐标值&am…

图像插值算法及其实现

sensor、codec、display device都是基于pixel的&#xff0c;高分辨率图像能呈现更多的detail&#xff0c;由于sensor制造和chip的限制&#xff0c;我们需要用到图像插值&#xff08;scaler/resize&#xff09;技术&#xff0c;这种方法代价小&#xff0c;使用方便。同时&#x…

插值算法(数学建模学习)

本系列参考清风老师的数学建模课程 插值算法 一、算法介绍 &#xff08;一&#xff09;算法引入 对于数据量少到不足以去分析问题&#xff0c;而必须生成一些合理的数据的情况要用到插值算法。 &#xff08;二&#xff09;算法详解 &#xff08;1&#xff09;定义 设函数 …

MATLAB-插值算法汇总

前言 数模比赛中常常需要对数据进行分析&#xff0c;当数据不足时就需要补充数据&#xff0c;所用到的方法就是插值法。本文汇总了一些常用的插值算法。 Hermite插值 埃尔米特插值(Hermite)会在给定的节点处&#xff0c;要求插值多项式的函数值与原函数值相同&#xff0c;同时…

第三讲 插值算法

数模比赛中&#xff0c;常常需要根据已知的函数点进行数据&#xff0c;模型的处理和分析&#xff0c;而有时候现有的数据是极少的&#xff0c;不足以支撑分析的进行&#xff0c;这时就需要使用一些数学的方法&#xff0c;“模拟产生”一些新的但又比较靠谱的值来满足需求&#…

opencv中插值算法详解

导读 做图像处理的同学应该经常都会用到图像的缩放&#xff0c;我们都知道图片存储的时候其实就是一个矩阵&#xff0c;所以在对图像进行缩放操作的时候&#xff0c;也就是在对矩阵进行操作&#xff0c;如果想要将图片放大&#xff0c;这里我们就需要用到过采样算法来扩大矩阵…

几种插值算法对比

1.拉格朗日插值 2.牛顿插值 3.分段线性插值 4. 分段三次埃尔米特插值 5.样条插值函数 6.五种样条函数比较 所以&#xff0c; 7. 五种插值方法的实际应用

转载:一文讲解图像插值算法原理

最近在研究插值算法&#xff0c;看到这篇CSDN博主Datawhale学习介绍的博文&#xff0c;觉得介绍得挺不错&#xff0c;转载过来。原文地址&#xff1a;https://blog.csdn.net/Datawhale/article/details/105697264 寄语&#xff1a;本文梳理了最近邻插值法、双线性插值法和三次…

插值算法

插值&#xff0c;通俗来说当在一个离散的事件中&#xff0c;想知道某一个位置确定的值时&#xff0c;就可以利用插值方式计算得到&#xff0c;即利用已知数据估计未知位置数值。插值的方式有很多&#xff0c;下面介绍几种常用的插值方式。 一、最近邻插值(Nearest Neighbour …

几种插值算法对比研究

[研究内容] 目前比较常用的几种插值算法 [正文] 目前比较常用的插值算法有这么几种&#xff1a;最邻近插值&#xff0c;双线性二次插值&#xff0c;三次插值&#xff0c; Lanczos插值等等&#xff0c;今天我们来对比一下这几种插值效果的优劣。 1&#xff0c;最邻近插值 最…

【3.0】 常见的插值算法

插值算法的概念一维插值问题一般插值多项式的原理拉格朗日插值法牛顿插值法埃尔米特插值法分段 三次埃尔米特插值和分段三次样条插值&#xff08;常用&#xff0c;附代码&#xff09; 一、插值算法的概念 数学建模比赛中&#xff0c;常常需要根据已知的函数点进行数据、模型的…

常用的三种插值算法

在做数字图像处理时&#xff0c;经常会碰到小数象素坐标的取值问题&#xff0c;这时就需要依据邻近象素的值来对该坐标进行插值。比如做图像的几何校正&#xff0c;也会碰到同样的问题。 1、最近邻插值法&#xff08;Nearest Neighbour Interpolation&#xff09; 这是最简单的…

数学建模常见算法:插值算法

目录 一、插值的定义 二、拉格朗日多项式插值&#xff08;Lagrange插值&#xff09; 三、龙格现象&#xff08;Runge phenomenon&#xff09; 四、牛顿插值&#xff08;Newton&#xff09; 五、分段线性插值 六、埃尔米特插值(Hermite 插值) 七、三次样条插值 八、插值…