查找
查找
基本概念
定义
-
查找:在数据结合中寻找满足某种条件的数据元素的过程。
-
查找表(查找结构):用于查找的数据集合称为查找表,它由同一类型的数据元素(或记录)组成。(table/graph/)
- 静态查找表:查找
- 动态查找表:查找,增删数据
-
关键字:唯一标识数据元素的某个数据项的值,使用基于关键字的查找,查找结果应该是唯一的。(key)
-
查找长度:在查找运算中,需要对比关键字的次数称为查找长度。
-
平均查找长度(ASL):所有查找过程中进行关键字的比较次数的平均值。
\(ASL= \displaystyle \sum^{n}_{i=1}{P_iC_i}\)
n:数据元素个数
\(P_i\):查找第i个元素的概率
\(C_i\):查找第i个元素的查找长度
查找任何一个元素的概率都是相同的
ASL的数量级反映了查找算法时间复杂度。
顺序查找
线性查找:线性表(顺序表、链表)
算法实现
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;
}
//哨兵,无需判断是否越界,效率更高
int Search_Seq(SSTable ST,ElemType key){
//0号位置存哨兵,1号位置存数据
ST.elem[0]=key;
int i;
for(i=ST.TableLen;ST.elem[i]!=key;--i);
return i;
}
//一个成功结点的查找长度=自身所在层数
//一个失败结点的查找长度=其父节点所在层数
//优化:被查概率不相等,可按被查概率降序排序,查找成功时ASL更少
//表中元素有序:关键字大于或小于目标关键字时,查找失败.
//查找失败时ASL更少.
折半查找
二分查找,用于有序的顺序表。
typedef struct{
ElemType *elem;
int TableLen;
}SSTable;
//折半查找
int Binary_Search(SSTable L,ElemType key){
int low=0,high=L.TableLen-1,mid;
while(low<=high){
mid=(low+high)/2; //取中间位置
if(L.elem[mid]==key)
return mid; //查找成功则返回所在位置
else if(L.elem[mid]>key)
high = mid-1; //前半部分继续查找
else
low=mid+1; //后半部分继续查找
}
return -1; //查找失败,返回-1
}
B树
//5叉查找树
struct Node{
Elem Type keys[4]; //最多4个关键字
struct Node*child[5]; //最多5个孩子
int num; //结点中关键字
}
//m叉查找树中,除了根节点外,任何结点至少又[m/2]个分叉,即至少含有[m/2]-1个关键字
| m阶B树 | m阶b+树 | |
|---|---|---|
| 类比 | 二叉查找树->m叉查找树 | 分块查找->多级分块查找 |
| 关键字 | n个关键字对应n个分叉 | |
| 包含信息的结点 | 所有结点 | 最下层叶子结点 |
| 查找方式 | 查找成功可能停在任何一层结点 | 顺序查找。查找成功或失败都会到达最下一层结点 |
| 查找速度 | 不稳定 | 稳定 |
| 相同点 | 除根结点外,最少\([m/2]\)个分叉,任何一个结点的子树都要一样高 |
散列表
散列表(Hash Table)哈希表:是一种数据结构,数据元素的关键字与其存储地址直接相关。
关键字通过散列函数(哈希函数)Addr=H(key)建立与存储地址的联系。chy
构造方法
同义词 :不同的关键字通过散列函数映射到同一个值
冲突:通过散列函数确定的位置已经存放了其他元素
拉链法(链接法)(链接地址法):把所有“同义词”存储在一个链表中处理冲突
除留余数法:散列表表长为m,取一个不大于m但最接近或等于m的质数p
直接定址法:H(key)=key或H(key)=a*key+b
其中a和b是常数。这种方法计算最简单,且不会产生冲突。它适合关键字的分布基本连续的情况,否则空位多会浪费存储空间。
数字分析法:选取数码分布较为均匀的若干位作为散列地址。
处理冲突的方法
开放定址法:

浙公网安备 33010602011771号