1. 二分法
(1)先将查找表排序
(2)取中间元素进行比较
1)若给定数据=中间元素,则查找成功
2)若给定数据<中间元素,则在中间元素左区间进行二分查找
3)若给定数据>中间元素,则在中间元素右区间进行二分查找
例如:
//递归版本:效率低,但可读性高
int binary_search(int *a, int low, int high, int key) //O(logn)
{
int ret = -1;
int mid;
if(low <= high)
{
mid = (low+high)/2;
printf("mid:%d\n", mid);
if(a[mid] == key)
ret = mid;
else if(a[mid] > key)
ret = binary_search(a, low, mid-1, key);
else if(a[mid] < key)
ret = binary_search(a, mid+1, high, key);
}
return ret;
}
//循环版本(推荐使用):效率高,但可读性差
int binary_search_ex(int *a, int low, int high, int key) //O(logn)
{
int ret = -1;
int mid = -1;
while(low <= high)
{
mid = (low + high)/2;
printf("mid:%d\n", mid);
if(a[mid] == key)
{
ret = mid;
break;
}
else if(a[mid] < key)
low = mid+1;
else if(a[mid] > key)
high = mid-1;
}
return ret;
}
2.插值查找
核心:mid = low + f(key)*(high - low)
f(x) = (x - a[low])/(a[high] - a[low])
例如:
int interpolation_search(int a[], int low, int high, int key)
{
int ret = -1;
while( (low <= high) && (a[low] <= key) && (key <= a[high]) )
{
float fx = 1.0f * (key - a[low]) / (a[high] - a[low]);
int mid = low + fx * (high - low);
if( a[mid] == key )
{
ret = mid;
break;
}
else if( key < a[mid] )
{
high = mid - 1;
}
else if( key > a[mid] )
{
low = mid + 1;
}
}
return ret;
}