查找算法
1. 查找的基本概念
- 查找定义:在数据集合中寻找满足某种条件的数据元素的过程
- 查找表:同一种类型元素构成的集合
- 关键字:数据元素中某个可以唯一标识该元素的数据项
2. 查找的分类
2.1 静态查找
- 查询每个“特定的”数据元素是否在查找表中
- 读取每个“特定的”数据元素和各种属性
使用线性查找结构来组织数据,这样可以使用顺序查找折半查找等高效查找
2.2 动态查找
- 查找时插入数据
- 查找时删除数据
考虑二叉排序树和散列表结构
3. 顺序查找
3.1 基本顺序查找 (O(2n))
- 从前往后:每次都要判断是否越界
//顺序查找,a为数组,n为要查找的数组个数,key为要查找的关键字
int Seq_search(int a[], int n, int key)
{
int i;
for (i = 0; i < n;i++)
{
if (a[i] == key)
return i;
}
return 0;
}
3.2 优化后的顺序查找(O(n))
- 从后往前:不需要判断是否越界,性能更优
int Seq_search(int a[], int n, int key)
{
int i = n;
a[0] = key; //设置哨兵
while(a[i] != key){
//如果不是要找的元素
i--; //从后往前找
}
return i; //返回0表示没有找到,返回其它数字代表找到
}
4. 有序表查找
有序表查找要求,数据是有序的,是排序好的,我们只需要进行查找
4.1 折半查找与顺序查找动图
4.2 折半查找代码( O l o g n )
int Binary_Search(int a[], int n, int key)
{
int low, high, mid;
low = 0;
high = n - 1;
//[low,high]
while (low<=high)
{
mid = (low + high) / 2; //二分查找
if (a[mid] < key)
low = mid + 1; //[mid+1,high]
else if (a[mid]>key)
high = mid - 1; //[low,mid-1]
else
return mid;
}
return -1;
}
对于折半查找,为什么一定要,而不是1/4或者其他?
比如:我们查字典Apple,我们会先从中间查找,还是有一定目的的向前找。
4.3 插值查找 O l o g n
对折半查找到的优化,将查找点的选择改为自适应选择
对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。
其余部分不变,只对mid值进行优化
4.3.1 二分查找mid值
- m i d =