折半查找
我们把每次取中间记录查找的方法叫做折半查找。又称为二分查找。他的前提是线性表中的记录必须是关键码(数据项)有序的(通常是从小到大有序)。线性表必须采用顺序存储。其时间复杂度为O[logn]其时间复杂度远远小于顺序查找,但是对于需要频繁执行插入或者删除操作的数据集来说,维护有序的排序会带来不少开销,不建议使用。
int Binary_Search(int *a, int n, int key)
{
int low, high, mid;
low = 1;
high = n;/*数组从1开始计数*/
while(low <= high)
{
/*注意是小于等于,要不然最后一次比如 key = 4,low = 3, high = 4 , (3+4)/2 取整 = 3,这样key就找不到了。 */
mid = (low + high) / 2;
if (key < a[mid])
{
high = mid - 1;
}
else if (key > a[mid])
{
low = mid + 1;
}
else
{
return mid;
}
}
return 0;/*查找失败*/
}
插值查找(Interpolation Search)
插值查找是根据要查找的关键字key与查找表中最大最小记录的关键字比较后的查找算法,其核心就在于插值的计算公式。
k e y − a [ l o w ] a [ h i g h ] − a [ l o w ] \frac{key-a[low]}{a[high]-a[low]} a[high]−a[low]key−a[low]
而插值查找的代码部分就是将以上折半查找的mid更新语句变化为:
m i d = l o w + k e y − a [ l o w ] a [ h i g h ] − a [ l o w ] ( h i g h − l o w ) mid = low + \frac{key-a[low]}{a[high] - a[low]}(high - low) mid=low+a[high]−a[low]key−a[low](high−low)
其实是将最初的 mid = (low + high) / 2 变形为 mid = low + (high-low) / 2, 再将这个公式中的1/2替换成插值。
int Interpolation_Search(int *a, int n, int key)
{
int low, high, mid;
low = 1;
while(low <= high)
{
mid = low + (key - a[low])/(a[high] - a[low]) * (high - low); /*插值*/
if (key < a[mid])
{
high = mid - 1;
}
else if (key > a[mid])
{
low = mid + 1;
}
else
{
return mid;
}
}
return 0;/*查找失败*/
}