插值查找
算法简介
插值查找是根据要查找的关键字key与查找表中最大最小记录的关键字比较后的查找方法,其核心就在于插值的计算公式:
mid = low+(key-a[low])/(a[high]-a[low])*(high-low)。
算法思想
基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。
注:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么插值查找未必是很合适的选择。
复杂度分析
时间复杂性:如果元素均匀分布,则O(log log n)),在最坏的情况下可能需要 O(n)。
空间复杂度:O(1)。
代码实现
#include<iostream>
using namespace std;
int interpolation_search(int nums[], int begin, int end, int key){
if (begin>=end) return -1;
int mid = begin+((key-nums[begin])*(end-begin)/(nums[end]-nums[begin]));
cout<<"debug: search: mid="<<mid<<endl;
if(nums[mid]==key)
return mid;
else if(nums[mid]>key)
return interpolation_search(nums,begin,mid-1,key);
else
return interpolation_search(nums,mid+1,end,key);
}
int main(){
int nums[] = {1,3,4,6,8,9,10,13,16,19,20,21};
int len = sizeof(nums)/sizeof(nums[0]);
int key, location;
cin >> key;
location = interpolation_search(nums, 0, len-1, key);
if(location == -1)
cout<<key<<" is no in nums"<<endl;
else
cout<<key<<" is at: "<<location<<endl;
return 0;
}