插值查找法(按比例查找)

折半查找法:https://blog.csdn.net/qq_35423154/article/details/101383518

当我们在使用折半查找法的时候,都会有个疑问,为什么一定要用折半,为什么不能折三分之一,四分之一呢?为什么我们不能根据我们查找的数值的不同而制定不同的比例来查找呢?于是,经过算法科学家的努力,插值查找法(按比例查找)诞生了。
这个方法的实现非常简单,它仅仅修改了折半查找法之中一条语句
首先我们先写出折半查找法的核心语句
mid = (right + left) / 2;
代换为
mid =left+ (right - left) / 2;
算法科学家通过对这个1/2进行改进,得到了下面这个算法
mid = left + (key - a[left]) * (right - left) / (a[right] - a[left]);

	int a[] ={1,3,5,7,9,11,13,15,17,19};

例如我们要在上面这个数据中查找17
mid = 0 + (17-1)*(9-0)/(18) = 8;
仅仅一次我们就可以查找到想要的数据‘
而它这次中直接按照88%左右的效率直接查到了结尾的17,效率一下子就高了很多,如果这里采用的是折半查找法,要查找三次,差距十分明显。
虽然从时间复杂度来看它和折半查找都是O(log n),但是对于表长比较大,数据分布均匀的查找表,它的性能要比折半查找法优秀很多,但是他也不是完全高于折半查找,如果数组中分布数据极度不均匀,它的效率可能会低折半查找法略低。
代码如下

#include
int Search(int right,int key,int a[])
{
	int left =0,mid;
	while(left <= right)
	{
		mid = left +  (key - a[left]) * (right - left) / (a[right] - a[left]);
		if( key > a[mid] )
		{
			left = mid + 1; 
		} 
		else if( key < a[mid])
		{
			right = mid - 1;
		}
		else if( key == a[mid])
		{
			return mid;
		}
	}
	
	if(left > right)
	{
		return -1;
	}
}
int main()
{
	int a[] ={1,3,5,7,9,11,13,15,17,19};
	int key,i,right,left,mid;
	right = sizeof(a)/sizeof(a[0])-1;
	left =0;
	
	printf("请输入要查找的数据:");
	scanf("%d",&key);
	mid = Search(right,key,a);
	
	if( -1 == mid )
	{
		printf("查找失败 ");	 
	}
	else
	{
		printf("下标为:%d",mid);
	}
	return 0;
}

你可能感兴趣的:(数据结构)