文章目录
插值查找(比例查找法)
摘要
当我们在使用**折半查找法**的时候,都会有个疑问,为什么一定要用折半,为什么不能折三分之一,四分之一呢?为什么我们不能根据我们查找的数值的不同而制定不同的比例来查找呢?于是,经过算法科学家的努力,插值查找法(按比例查找)诞生了。
首先我们先写出折半查找法的核心语句
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),但是对于表长比较大,数据分布均匀的查找表,它的性能要比折半查找法优秀很多,但是他也不是完全高于折半查找,如果数组中分布数据极度不均匀,它的效率可能会低折半查找法略低。
插值查找
int search(int* p, int number, int under, int top)
{
//int mind = (under + top) / 2; //二分法查找
//按比例查找(插值查找)
int mind = under + (number - p[under]) * (top - under) / (p[top] - p[under]);
if (mind < under || mind > top)
{
return 0;
}
else if (p[mind] < number)
{
return search(p, number, mind + 1, top);
}
else if (p[mind] > number)
{
return search(p, number, under, mind - 1);
}
else return mind+1;
}
测试代码
#include <stdio.h>
int search(int* p, int number, int under, int top)
{
//int mind = (under + top) / 2; //二分法查找
//按比例查找(插值查找)
int mind = under + (number - p[under]) * (top - under) / (p[top] - p[under]);
if (mind < under || mind > top)
{
return 0;
}
else if (p[mind] < number)
{
return search(p, number, mind + 1, top);
}
else if (p[mind] > number)
{
return search(p, number, under, mind - 1);
}
else return mind+1;
}
int main()
{
int number[] = { 1,3,5,7,9,11,13,15,17,19 };
int c;
for (int i = 0; i < 10; i++)
printf("%4d",number[i]);
printf("\n请输入你需要查找的数字:");
scanf_s("%d", &c);
if (search(number, c, 1, 10))
{
printf("你所查找的数字位置为:%d\n", search(number, c, 1, 10));
}
else {
printf("未查找到");
}
return 0;
}