1.二分查找
二分查找又叫折半查找,它的前提是线性表中的记录必须是关键码有序(通常从小到大有序,线性表必须采用顺序存储)。
假设有一个有序表数组{0,1,16,24,35,47,59,62,73,88,99},共10个数字,对其进行查找是否存在62这个数。
/* 二分查找 */
int Binary_Search(int *a, int n, int Key)
{
int low, high, mid;
low = 1; //定义最低小标为记录首位
high = n; //定义最高下标为记录末位
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; //若相等即说明mid为查找的位置
}
return 0;
}
二分查找的时间复杂度为O(logn),优于顺序查找O(n)。
2.插值查找
二分查找的中值选取条件为:
改进方法:
插值查找的代码为:
mid = low+ (high-low) * (key-a[low]/a[high]-a[low])
算法时间复杂度同为O(logn),当表长度较大且关键字分布比较均匀时,使用插值查找方法效果较好!
3.斐波那契查找
Fibonacci Search 是通过黄金分割原理进行实现的。代码如下:
/* Fibonacci Search */
int Fibonacc_Search(int *a, int n, int Key)
{
int low,high,mid,i,k;
low = 1; //定义最低下标为记录首位
high = n; //定义最高下标为记录末位
k = 0;
while(n>F[k]-1) //计算n位于Fibonacci数列中的位置
k++;
for(i=n;i<F[k]-1;i++) //将不满的数值补全
a[i] = a[n];
while(low<=high)
{
mid = low+F[k-1]-1; //计算当前分隔的下标
if(key<a[mid]) //若查找记录小于当前分隔符
{
high = mid-1; //最高下标调整到分隔符下标mid-1处
k = k-1; //Fibonacci数列下标减一位
}
else if (key>a[mid]) //若查找记录大于当前分隔符
{
low = mid+1; //最低下标调整到分隔符下标mid+1处
k = k-2;
}
else
{
if(mid<=n)
return mid; //若相等则说明mid即为查找的位置
else
return n; //若mid>n,说明是补全数值,返回n
}
}
return 0;
}
三种有序表的查找本质上是分隔点的选择不同,各有优劣。