目录
以此分为静态查找表和动态查找表:编辑1.3查找算法的评价指标
1.查找的基本概念
1.1基本概念
查找一一在数据集合中寻找满足某种条件的数据元素的过程称为查找
查找表(查找结构的统称,并非新的数据结构)一一用于查找的数据集合称为查找表,它由同一类型的数据元素(或记录)组成(线性结构、树状结构、图状结构等都可)
关键字——数据元素中唯一标识该元素的某个数据项的值,使用基于关键字的查找,查找结果应是唯一的。
1.2对查找表的常见操作
①查找符合条件的数据元素
②插入、删除某个数据元素
以此分为静态查找表和动态查找表:
1.3查找算法的评价指标
查找长度——在查找运算中,需要对比关键字的次数称为查找长度
平均查找长度(⭐ASL, Average Search Length)——所有查找过程中进行关键字的比较次数的平均值
题目没有要求的话,默认查找任何一个元素的概率相等
例子:
ASL的数量级反映了查找算法的时间复杂度
如果一颗二叉排序树是平衡二叉树(胖胖的、丰满的树;高度较小,从而对比次数就会较少),那么它的ASL值更小,故平衡二叉树有更高的搜索效率。
回顾一下之前关于二叉排序树和平衡二叉树的笔记(在我的其他数据结构的博客里):
2.顺序查找
2.1算法思想
顺序查找,又叫“线性查找”,通常用于线性表(顺序表、链式表)。
算法思想:从头到脚挨个找(或者反过来也OK)——对线性表的无差别的遍历
2.2算法实现
时间复杂度O(n)
2.2.1顺序表查找的实现
//顺序表(动态分配)查找的实现
typedef struct{
ElemType *elem;
int TableLen;
}SSTable;//sequential search table
//顺序查找
//在顺序表中找到元素值为key的元素,查找成功返回元素下标,否则返回-1
int Search_Seq(SSTable ST,ElemType key){
int i;
for(i=0; i<ST.TableLen && ST.elem[i]!=key; ++i);
return i==ST.TableLen? -1 : i;
}
2.2.2顺序表查找的实现(哨兵)
为什么叫“哨兵”?——找到即停,类似于见到哨兵即停
0号位置存哨兵,数据从1号开始存,从后往前找;找到返回下标,找不到则正好以-1结束循环,而返回-1
//顺序查找(“哨兵”)
int Search_Seq(SSTable ST,ElemType key){
ST.elem[0] = key;//0号位置存哨兵
int i;
for(i=ST.TableLen; ST.elem[i]!=key; --i);//从后往前找
return i;
}
2.3顺序查找效率及算法优化
顺序表查找的实现(哨兵)的查找效率分析(ASL):
▶优化方法一:前提是线性表中元素有序
▶优化方法二:前提是各元素被查找的概率不相等
被查概率大的放前面
3.折半查找⭐
3.1算法思想
又称“二分查找”,仅适用于有序的顺序表
[low,high]是动态的搜索范围,mid指向对比目标
例子:假设顺序表是升序排列:
向下取整( / 运算已经实现了向下取整)——数轴逆向找;向上取整——数轴正向找
3.2算法实现
假设顺序表是升序排列:
//顺序表(动态分配)
typedef struct{
ElemType *elem;//动态数组基址
int TableLen;//表长
}SSTable;//sequential search table
//顺序表具有随机访问的特性,链表没有
//折半查找
//假设顺序表是升序排列:查找成功返回数组下标,否则返回-1
int Binary_Search(SSTable L,ElemType key){
int low = 0,high = L.TableLen-1;
while(low <= high){
mid = (low+high)/2;
if(L.elem[mid] == key)
return mid;
else if(L.elem[mid] > key)
high = mid-1;
else//if(L.elem[mid] < key)
low = mid+1;
}
return -1;//low>high时退出循环
}