查找问题——顺序&折半&分块
根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)
关键字:用于表示一个数据元素的某个数据项的值
主关键字:唯一标识一个记录
次关键字:识别若干记录的关键字
查找表:是由同一类型的数据元素构成的集合。“集合”中数据元素直接按存在着松散的关系,因此查找表是一种应用灵便的结构。
静态查找表:仅作“查询”检索的查找操作
动态查找表:作“插入”和“删除”操作的查找表,查找后查找表发生变化
查找算法的评价指标:
关键字的平均比较次数,也叫平均查找长度ASL.
线性表的查找
顺序查找(顺序查找)
优点:算法简单,逻辑次序无要求,不同存储结构均适用
缺点:ASL太长,时间效率太低
- 顺序表或线性链表表示的静态查找表
- 表内元素无序
typedef struct{
ElemType *R;
int length;
}SSTable;
SSTable ST;
在上面顺序表 ST中查找值为key的数据元素。
int Search_Seq(SSTable ST,KeyType key){
for(i=ST.length;i>=1;--i)
return i;
retuen 0;
}
顺序查找如何优化------设置“哨兵”,不需要检查越界
int Search_Seq(SSTable ST,KeyType key){
ST.R[0].key=key; //设置为哨兵
for(i=ST.length; ST.R[i] .key != key ;--i)
return i;
retuen 0;
}
/*
当length,此时优化平均查找时间几乎减少一半
时间效率分析 ,比较次数于key位置有关
- 查找第i个需要比较n-i-1次
- 查找失败,比较n+1次
- 时间复杂度:O(n),设表中个记录查找概率相等
- ASL=(1+2+…+n)/n=(n+1)/2
- 空间复杂度:一个辅助空间 --------O(1)
-
如果查找概率不相等,如何高效查找?
按查找概率高低存储 -
查找概率无法预测时,如何高效查找?
按查找概率动态调整记录顺序
在每个记录中设置一个访问频度域
始终保持记录按非递增有序的次序排列
每次查找后将刚查找的记录表直接移动到表头
折半查找(二分或对分查找)
每次将待查找记录所在区间缩小一半
优:效率高
缺:只适用于有序表,限于顺序存储结构(等于线性链表无效)
折半查找算法(非递归 算法)
非递归算法较为简单,在函数参数上加入low和high 的定义,将函数体的顺序稍加变动即可。
判定树的应用—分析折半查找性能
分块查找(索引顺序表的查找)
优点:插入和删除比较容易,无需进行大量移动
缺点:需要增加一个索引的存储空间,并进行排序运算
适应:既要快速查找又要经常动态变化,则可以采用分块查找
方法:
- 将表分成几块,且有序或分块有序
- 建立索引表,每个结点含有最大关键字域和指向本快第一个结点的指针,且按关键字有序)
查找过程:
- 先确定待查找记录所在块,再在块内查找(顺序或折半均可)
性能分析:ASL=索引表查找ASL+块内查找ASL