文章目录
- 查找
- 查找的基本概念
- 线性表的查找
- 一、顺序查找(线性查找)
- 二、折半查找(二分或对分查找)
- 三、分块查找(索引顺序查找)
查找
查找的基本概念
查找表
查找表是同一类型的数据元素(或记录)构成的集合。
关键字
关键字是数据元素中某个数据项的值。若此关键字能唯一的标识一个记录,那么此关键字称为主关键字。反之,称用以识别若干记录的关键字称为次关键字。
动态查找表和静态查找表
若在查找的同时对表执行修改操作(如插入和删除),则称相应的表为动态查找表,否则称为静态查找表。
查找算法的评价指标:
关键字的平均比较次数,也称平均查找长度。
ASL(Average Search Length)
(关键字的比较次数的期望值)
n:记录的个数。
pi:查找第i个记录的概率(通常认为pi=1/n)
ci:找到第i个记录所需的比较次数
线性表的查找
//数据元素类型
typedef struct {
KeyType key;//关键字域
//...其他域
}ElemType;
typedef struct {
ElemType* R;//存储空间的基地址
int length;//当前长度
}SSTable;
一、顺序查找(线性查找)
int Search_Seq(SSTable ST, KeyType key) {
int i;
//若成功返回其位置信息,否则返回0;
for (i = ST.length; i >= 1; i--) {
if (ST.R[i].key==key) {
return 0;
}
}
}
改进:把待查关键字key存入表头(“监视哨”),从后往前逐个比较,可免去查找过程中每一步都要检测是否查找完毕,加快速度。
//改进:加监视哨
int Seacher_Seq(SSTable ST, KeyType key) {
int i;
ST.R[0].key = key;
for (i = ST.length; ST.R[i].key; --i);
return i;
}
分析:
1.时间复杂度:O(n)
查找成功的平均查找长度,记录各记录查找概率相等。
2.空间复杂度:
申请了一个辅助空间:O(1)。
讨论:
1.查找表存储记录原则----按查找概率高低存储:
1)查找概率越高,比较次数越少。
2)查找次数越低,比较次数越多。
2.记录的查找概率无法测定时如何提高查找效率?
方法----按查找概率动态调整记录顺序:
1)在每个记录中设一个访问的频度域;
2)始终保持记录按非递增有序地排列;
3)每次查找后将刚查找的记录直接移至表头。
优点:
算法简单,逻辑次序无要求,且不同存储结构适用。
缺点:平均查找长度较大,查找效率低。
二、折半查找(二分或对分查找)
每次将待查记录所在区间缩小一半。
//折半查找
int SearchBin(SSTable ST, KeyType key) {
int low = 1;
int high = ST.length;//置区间初值
while (low <= high) {
int mid = (low + high) / 2;
if (ST.R[mid].key == key) {
return mid;//找到待查元素
}
else if(key<ST.R[mid].key) {//缩小查找区间
high = mid - 1;//继续在前半截查找
}else {
low = mid + 1;
}
return 0;
}
}
折半查找的优点:效率比顺序查找高。
折半查找缺点:只适用于有序表,且限于顺序存储结构(对线性表无效)。
三、分块查找(索引顺序查找)
条件:1.将表分为几块,且表或者有序,或者分块有序。