插值搜索核心代码由二分搜索(区间左闭右开)m = l + 1.0/2*(r - 1 - l) = 1.0(l + r - 1)/2 更改为m = l +1.0*(key - a[l])/(a[r - 1] - a[l])*(r - 1 - l).
利用关键字所在位置的估值(key - a[l])/(a[r - 1] - a[l])代替1/2,对于随机分布为常规分布的关键字,平均时间复杂度lg lg N.即如果N为10亿,平均查找小于5次.
//
// main.cpp
// 插值搜索
//
// Created by Lance on 13-3-14.
// Copyright (c) 2013年 Lance. All rights reserved.
//
#include <iostream>
#include <cstdio>
using std::cin;
using std::cout;
using std::endl;
typedef int Item;
#define key(A) (A)
#define less(A, B) (key(A) < key(B))
#define exch(A, B) { Item t = A; A = B; B = t; }
#define compexch(A, B) if (less(B, A)) exch(A, B)
void insertion (Item a[], int l, int r) { //插入排序
int i;
for (i = r - 1; i > 1; --i) //设置观察哨
compexch(a[i - 1], a[i]);
for (i = l + 2; i < r; ++i) {
int j = i;
Item v = a[i];
while (less(v, a[j - 1])) { //确定位置并移位数组
a[j] = a[j - 1];
--j;
} // end of while
a[j] = v;
}
}
Item search (Item a[], Item key, int l, int r) {
//插值搜索核心代码
int m = l + 1.0*(key - a[l])/(a[r - 1] - a[l])*(r - 1 - l);
if (l > r) return -1;
if (key == a[m]) return m;
if (key < a[m]) return search(a, key, l, m);
else return search(a, key, m + 1, r);
}
int main(int argc, char *argv[]) {
const int N(10);
int i(0);
Item *a = new Item[N];
for (i = 0; i < N; ++i)
a[i] = 1000*(1.0*rand()/RAND_MAX);
Item compare(a[N/2]);
printf("old data:\n");
for (i = 0; i < N; ++i)
printf("%3d ", a[i]); //便于格式控制
printf("\n");
insertion(a, 0, N);
printf("sorted:\n");
for (i = 0; i < N; ++i)
printf("%3d ", a[i]);
printf("\n");
int ans = search(a, compare, 0, N) + 1;
cout << endl << endl;
cout << "compare is " << compare << endl;
cout << "ans is " << ans << endl;
delete a;
}