算法与数据结构——插值查找(c/c++实现)

本文深入探讨了插值查找算法的原理,展示了其基于二分查找的改进之处,特别是在数据有序且分布均匀的情况下,查找效率可达O(logn)。文章通过实例解释了如何避免特定数据集引起的死循环,并提供了简易的算法实现代码。

算法原理

算法基于二分查找(binary search) 演变而成,拥有二分查找时间复制度小的优点,而思想也几乎是继承了二分查找。
相比 斐波那契查找 ,插值查找一样有特殊的middle选取方式:
在这里插入图片描述
该公式即为middle点的选取方式,而在 key < A[middle] 时则将high取为middle - 1,这点与二分查找同理,key > A[middle]时则同理将 low 取为 middle + 1
但这有一个问题,在清华大学邓老师的课中有一个很不错的例子,当数组/向量的数据为

int a[19] = { 5,10,12,14,26,31,38,39,42,46,49,51,54,59,72,79,82,86,92 }

low和middle的计算很容易陷入10与11的死循环,按照公式的判断流程如下(引自清华大学邓老师数据结构与算法课PPT)
注意插值查找的mi和lo最后一个变化,有可能导致程序死循环因此在使用插值查找时 ,要用某些方法防止数据导致的死循环,这是网上很多博客没提到的,而防止的方法很多,我的代码则用的是针对这一组数据

算法代码(简易)

include<iostream>
using namespace std;

int Interpolation_search(int *a, int search_value, int low, int high)
{
	if (low > high)
		return -1;
	int lo = low, hi = high;
	int mid = lo + (hi - lo)*((search_value - a[lo]) / (a[hi] - a[lo]));
	
	if(mid>=10)
		reurn -1;
	
	if (a[mid] < search_value)
		return Interpolation_search(a, search_value, mid + 1, hi);
	else if (search_value < a[mid])
		return Interpolation_search(a, search_value, lo, mid - 1);
	else if (a[mid] == search_value)
		return mid + 1;

}

int InterpolationSearch(int *A, int e, int low, int high)
{
	while (low < high)
	{
		int mid = low + (high - low - 1)*(e - A[low]) / (A[high - 1] - A[low]);
		if (mid >= 10) //在这里防止死循环退出
			return -1;
		if (e < A[mid])
			high = mid;
		else if (e > A[mid])
			low = mid + 1;
		else
			return mid;
	}
	return -1;
}

int main()
{
	int a[19] = { 5,10,12,14,26,31,38,39,42,46,49,51,54,59,72,79,82,86,92 };
	//	cout<<Interpolation_search(a,50,0,18)<<endl;;
	cout << InterpolationSearch(a, 50, 0, 18);
	cout << endl;
	return 0;
}

优缺点

插值查找限制条件也是其查找时间成本为 o(logn) 的原因之一,要求数据有序且分布均匀分布均匀可以理解为每个数据在某个区间内的某个恰当位置(可见下图,图源依旧为清华大学邓老师的课)。当需要查找的数据源极大的时候,插值查找可以很大程度上缩短所需的时间,而在极小的数据源中,顺序查找更优,二分查找以及斐波那契查找则相较占中些(个人理解),因此查找更需要的是正确的选择,避免小题大做,以及最重要的是有序数据

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杜景今天吃雪糕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值