1、折半查找
折半查找又称二分查找,时间复杂度为,它的前提t条件是有序顺序存储,对于静态查找表,一次排序后不再变化,这样的算法已经比较好了。但对于需要频繁插入或删除操作的数据来说,维护有序的排序会带来不小的工作量,不建议使用。
2、插值查找
插值查找是另一种有序表查找算法,其核心就在于插值公式,时间复杂度也是
,但对于表长较大且关键字分布均匀的查找表来说,插值查找平均性能比折半查找要好得多。
3、斐波那契查找
斐波那契查找原理是采用黄金分割点作为拆分点的,因为Fibonacci数列F[k]=F[k-1]+F[k-2],所以可以将长度为F[k]的有序顺序表中数据分割成F[k-1]和F[k-2],分割点就是,斐波那契数列随着数列增长越接近0.618。
4、三种有序表查找算法比较
三种有序表查找本质上是分隔点的选择不同,折半查找分隔点是,插值查找分隔点是插值点
,斐波那契查找分隔点是黄金分割点0.618。各有优劣,实际开发时根据数据的特点综合考虑作出选择。
折半查找进行加法和除法运算(mid=(low+high)/2),插值查找进行复杂的四则运算(mid=low+(high-low)*(key-a[low])/(a[high]-a[low])),而斐波那契查找只有简单的加减法运算(mid=low+F[k-1]-1),在海量数据查找过程中,这种微小的差别可能会影响最终的查找效率。
#include<iostream>
#include<algorithm>
using namespace std;
#define Max 100
//折半查找
int BinarySearch(int *a,int n,int key)
{
int low=0,high=n-1,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 InterpolationSearch(int *a,int n,int key)
{
int low=0,high=n-1,mid;
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;
}
//斐波那契查找
int *F; //存储Fibonacci数
//生成Fibonacci数组
void Fibonacci(int n)
{
F=(int*)malloc(n*sizeof(int));
if(n>2)
{
F[0]=0;
F[1]=1;
int i=2;
while(i<=n)
{
F[i]=F[i-1]+F[i-2];
i++;
}
}
}
int FibonacciSearch(int *a,int n,int key)
{
int low=0,mid,high=n-1,i,k=0;
//找到n位于斐波那契数列的位置且F[k-1]<=n<F[k]
while(F[k]<=n)
k++;
//将不满的数值补全,也就是数组a下标从n到F[k]-1填充a[n-1]
for(i=n;i<F[k];i++)
a[i]=a[n-1];
//斐波那契查找是以黄金分割点作为分割,F[k]=F[k-1]+F[k-2]也就是对F[k]分割成0到F[k-1]-1共F[k-1]个数字和F[k-1]到F[k]-1共F[k-2]个数字两段
//如果key<mid则对0到F[k-1]-1段查找,也就是将这一段F[k-1]=F[k-2]+F[k-3]分成了0到F[k-2]-1和F[k-2]到F[k-1]-1,所以k=k-1
//如果key>mid则对F[k-1]到F[k]-1段查找,也就是将这一段F[k-2]=F[k-3]+F[k-4]分成了0到F[k-2]-1和F[k-2]到F[k-1]-1,所以k=k-2
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
{
//如果mid小于n,则直接返回mid
if(mid<=n-1)
return mid;
//如果mid大于n,则直接返回n-1说明找到的位于填充的位置
else
return n-1;
}
}
return 0;
}
int main()
{
int a[Max]={2,5,6,8,3,1,17,39,70,90};
int n=10,key=1;
sort(a,a+n);
Fibonacci(n);
cout<<FibonacciSearch(a,n,key)<<endl;
cout<<BinarySearch(a,n,key)<<endl;
cout<<InterpolationSearch(a,n,key)<<endl;
return 0;
}