插值查找(Interpolation Search):是根据要查找的关键字key与查找表中最大最小记录的关键字比较后的查找方法,其核心在于插值的计算公式。
插值计算公式(折半查找为1/2):(key - a[low]) / (a[high] - a[low])
mid计算公式:mid = low + (high - low) *
(key - a[low]) / (a[high] - a[low]);
插值查找是基于折半查找进行了优化的查找方法。
优势在于:当表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能要比折半查找要好得多。
代码实现:
// Filename: interpolation_search.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "public.h"
// 计数器,评估性能使用
extern int count;
// 插值查找
// a[n]为待查找数组,a[0]不使用,n为数组长度(不包含a[0])
// 查找成功,则返回key所在的地址;查找失败,则返回0
int InterpolationSearch(int a[], int n, int key)
{
int low = 1, high = n, mid;
count = 0;
while (low <= high)
{
count++;
mid = low + (high - low) * (key - a[low]) / (a[high] - a[low]);
if (key < a[mid])
{
high = mid - 1;
}
else if (key > a[mid])
{
low = mid + 1;
}
else
{
return mid;
}
}
return 0;
}
// 插值查找主函数
int InterpolationSearchMain()
{
int value;
int retval;
int arr[12] = {0xFF, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1};
printf("插值查找演示(a[0]未使用,不参与排序): \n");
printf("静态查找表数据:\n");
PrintArray(arr, sizeof(arr) / sizeof(int));
printf("\n");
while (1)
{
// 查找元素
printf("请输入要查找的数据: \n");
scanf("%d", &value);
// 退出查找
if (0xFF == value) break;
retval = InterpolationSearch(arr, 10, value);
if (0 == retval)
{
printf("查找失败! 总计比较次数: %d.\n", count);
}
else
{
printf("查找成功,元素所在位置: %d. 总计比较次数: %d.\n", retval, count);
}
}
return 0;
}