日常生活中,我们通过搜索引擎(百度,谷歌)进行关键字的搜索,来搜寻我们需要的资料。
一个查找算法的好与坏直接影响着程序甚至是系统的执行效率。
所以可见其的普遍性,重要性。
查找
分类
- 静态查找:数据集合稳定,没有添加,删除,修改等操作。(常用结构:线性表。常用方法:顺序查找,折半查找(已排序),斐波那契查找等)
- 动态查找:在查找过程中需要添加,删除,修改等操作。(二叉排序树,散列表)
静态查找
1.顺序表
从第一个(或最后一个)记录开始,逐个进行记录的关键字与给定值进行一一比较。
最基础代码:
void Sq_Search(int*a, int n, int key)
{
int i;
for(i=1;i<=n;i++)
{
if(a[i]==key)
return 1;
}
return 0;
}
缺陷:每对一个记录需要进行两次判断(i<=n,a[i]=key),总共需进行2n次,效率不高
优化:设置哨兵。把key赋值给a[0],来做为循环推退出点,一次来减少比较的次数。效率提高一倍。
int Sq_Sort(int*a, int n, int key)
{
int i=n;
a[0]=key;
while(a[i]!=key)
i--;
return i;
}
2.插值查找
列如图书馆中找书的情景,本质上是折半查找(对所有记录的关键字进行排序,每一次缩小一半数据,来进行查找,效率达到O(log2n),相对较高)。
折半查找代码:
(设置三个标记:low,high,mid;依次折半比较,当low大于high时跳出循环,未成功查找)
int Half_Search(int *a; int n, int key)
{
int low=0, high=n-1, mid;
while(low<=high)
{
mid = (low + high)/2;
if(a[mid]<key)
low = mid + 1;
else if(a[mid]>key)
high = mid - 1;
else
return mid;
}
return -1;
}
**插值查找:**按比例划分的折半查找(仅有一处不同)。
int Half_Search(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);\\确定mid所指的合适比例
if(a[mid]<key)
low = mid + 1;
else if(a[mid]>key)
high = mid - 1;
else
return mid;
}
return -1;
}
斐波那契查找(黄金分割法查找):
斐波那契数列F[k]:1,1,2,3,5,8,13,21,34,55,89…
前后两数字的比值,越往后越接近黄金比例0.618