第一章 查找
重要概念
查找表:由同一类型的数据元素(或记录)构成的集合。
关键字:数据元素(或记录)中某个数据项的值,用它可以表示一个数据元素。若该关键字可以唯一地标识一个记录,则称此关键字为主关键字。
查找:根据给定的某个值,再查找表中确定一个器关键字等于给定值的记录或数据元素
平均查找长度(Average Search Length):为确定记录在查找表中的位置,需和给定值进行比较的关键字个数的期望值称为查找算法在查找成功时的平均查找长度,计算公式如下:
对于有n个记录的表,查找成功时的平均查找长度如上,为查找表中第i个记录的概率,Ci为找到表中其关键字与给定值相等的第i个记录时,和给定值已进行过比较的关键字个数。
查找算法的评价标准
- 查找速度
- 占用存储空间大小
- 算法的复杂度
查找方式
顺序查找
- 方法:从表中最后一个记录开始,逐个进行记录的关键字和给定值的比较
- 适用:顺序表、线性链表
- ASL:
在假设每个记录的查找概率相等时,即Pi=1/n
则在等概率情况下顺序查找的平均查找长度为:
//顺序查找:
typedef struct searchList {
ElemType* data;
int length;
}searchList;
int Search_Seq(searchList array,int key) {
array.data[0] = key;//监测哨兵
int n = array.length;
while (array.data[i] != key)
i--;
return i;
}
折半查找
- 方法:先确定待查记录所在范围(区间),然后每次将待查记录所在区间缩小一般,适用于采用顺序存储结构的有序表
- 适用:有序表
- ASL:
//折半查找:
typedef struct searchList {
ElemType* data;
int length;
}searchList;
int Search_Seq(searchList array,int key) {
int low = 1;//0留给哨兵用
high = array.length;
int mid;
while (low <= high)
{
mid = (low + high) / 2;
if (array.data[mid] > key)
low = low + 1;
else if (array.data[mid] < key)
high = mid - 1;
else
return mid;
}
return 0;
}
分块查找(索引顺序查找)
- 方法:先使用折半查找/顺序查找确定待查记录所在的块(子表),然后在块中顺序查找
- 特点:块内无序,块间有序;建立表(n个子表)+索引表(子表索引项=关键字项+指针项即子表第一个记录在该表中的位置)
- 适用:顺序表+线性链表
- ASL:
其中:sx指使用顺序查找来确定所在块,zb指用折半查找确定所在块
哈希表
- 概念:
在记录存储位置和它的关键字之间确定一个对应关系,使得每个关键字和结构中唯一的存储位置相对应。查找时,只需要根据这个对应关系f找到给定值K的像f(K),若结构中存在关键字和K相等的记录,则必定存在f(K)的存储位置上,由此不需要进行比较便可获取所在信息。对应关系称为哈希函数,按这个思想建立的表为哈希表。
- 哈希表:根据设定的哈希函数与处理冲突的方法将一组关键字映像到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“像”作为记录在表中的存储位置,所得的存储地址称为哈希地址
- 哈希冲突:对不同的关键字可能得到同一哈希地址,即key1≠key2,f(key1)=f(key2)。冲突可以尽可能的少,但不能完全避免。可以使用开放寻址法或链表法等方式。
查找方法比较: