有序表查找
一、二分查找(折半查找)
线性表中的数据必须是关键码有序(一般从小到大排列),且线性表必须采用顺序存储。
基本思想:将给定值与中间值进行比较,若小于中间值则在左半区继续比较,若大于中间值,则在右半区进行比较,一直重复,直到中间值等于给定值。或者所有查找区域无记录,查找失败为止。
int Binary_Search(int * a, int n, int key)
{
int low = 1, high = n, mid;
while(low <= high)
{
mid = (low + high)/2;
if (key < a[mid])
{
high = mid - 1;
}
else if (key > a[mid])
{
low = mid + 1;
}
else
{
return mid;
}
}
return 0;
}
二、插值查找
思想与二分查找相同,只是折的位置不同,更适用于大规模均匀的数据
int Binary_Search(int * a, int n, int key)
{
int low = 1, high = n, mid;
while(low <= high)
{
mid = (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
{
return mid;
}
}
return 0;
}
三、斐波那契查找
思想:还是二分查找的思想,区别还是在于折的位置的不同
它利用了黄金分割的原理,如下图是斐波那契数列。
int Fibonacci_Search(int * a , int n, int key)
{
int low, high, mid, i, k;
low = 1;
high = n;
k = 0;
while(n > F[k] - 1)
{
k++; //计算n在数列中的位置
}
for (i = n; n < F[k] -1; i++)
{
a[i] = a[n]; //将要查找的数列补齐,这一步很重要,不然有可能会在查找的过程中溢出。
}
while(low <= high)
{
mid = low + F[k-1] - 1;
if (key < a[mid])
{
high = mid - 1; //
k = k - 1; //数列下标减一位
}
else if (key > a[mid])
{
low = mid + 1;
k = k - 2;
}
else
{
if(mid <= n)
{
return mid; //相等则返回mid
}
else
{
return n; //此时越界,应返回n
}
}
}
return 0;
}