为什么一定要二查找,而不是四分之一或者更多呢?
插值查找(Interpolation Search)是根据要查找的关键字key与查找表中最大最小记录的关键字比较后的查找方法,其核心就在于插值的计算公式。
插值查找时间复杂度O(logn)。
对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好得多。
反之,数组中如果分布极端不均匀,用插值查找则未必合适。
代码:
#include <iostream>
using namespace std;
int Interpolation_Search(int *a, int n, int key)
{
int mid = 0;
int high = n-1;
int low = 0;
while (low <= high)
{
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 if (key == a[mid])
{
return mid;
}
}
return -1;//查找失败
}
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int key = 2;
cout<<Interpolation_Search(a, 10, key)<<endl;
key = 99;
cout<<Interpolation_Search(a, 10, key)<<endl;//如果返回-1,则查找失败
getchar();
return 0;
}
结果:
加一个round标识来比较两种算法的查找次数。
#include <iostream>
using namespace std;
int Interpolation_Search(int *a, int n, int key)
{
int mid = 0;
int high = n-1;
int low = 0;
int round = 0;//round标识,用于记录查找次数
while (low <= high)
{
round ++;
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 if (key == a[mid])
{
cout<<"Round: "<<round<<endl;
return mid;
}
}
return -1;//查找失败
}
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int key = 2;
cout<<Interpolation_Search(a, 10, key)<<endl;
key = 99;
cout<<Interpolation_Search(a, 10, key)<<endl;//如果返回-1,则查找失败
getchar();
return 0;
}

#include <iostream>
using namespace std;
int Binery_Search(int *a, int n, int key)
{
int mid = 0;
int high = n-1;
int low = 0;
int round = 0;//round标识,用于记录查找次数
while (low <= high)
{
round ++;
mid = (low+high)/2;//二分查找
if(key < a[mid])
{
high = mid-1;
}
else if (key > a[mid])
{
low = mid+1;
}
else if (key == a[mid])
{
cout<<"Round: "<<round<<endl;
return mid;
}
}
return -1;//查找失败
}
int main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int key = 2;
cout<<Binery_Search(a, 10, key)<<endl;
key = 99;
cout<<Binery_Search(a, 10, key)<<endl;//如果返回-1,则查找失败
getchar();
return 0;
}

说明插值查找第1次就找到了,而二分查找在第2次才找到。