有序表查找_插值查找

来源:互联网 发布:淘宝卖家服务热线 编辑:程序博客网 时间:2024/05/01 22:01

为什么一定要二查找,而不是四分之一或者更多呢?


插值查找(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次才找到。