---
key - value 键值映射
当多个关键字映射到同一个值时,则称发生了冲突,下面介绍一种解决冲突的方法:
Chaining with hash
“拉链法”
将映射值相同的关键字称为同义词,拉链法将同义词链接在一起
- 查找成功:
-
查找失败:
ASL
- 查找成功:
-
查找失败:
实际上,上式中分子部分就是表中存储的记录数(n),分母部分等于散列表的表长(槽的个数m),因此,上式的结果0.92也就是此时该表的装填因子 α = n/m
如何优化?
”设计冲突更少的散列函数“
常见的散列函数
- 除留余数法
Q:下面这个例子中显然模 8后的冲突比模 7更小,为什么还一定要用素数?
A:如果实际问题中关键字不像上例一样连续出现,例如考虑下面的情况,不难发现用素数取模虽然会牺牲部分槽位,但显然可以使分布更加均匀
-
直接定址法
对于关键字连续分布的情况,可以使用直接定址法
-
数字分析法
-
平方取中法
Open addressing
“开放定址法 ”
与“拉链法”不同,所谓“开放”,是指对于多个同义词而言,如果发现目标槽位已经被占据,可以把待定位的同义词放到其它槽中
增量序列有以下几种取法:
Probing Strategies
“探查策略 ”
线性探测法
“Linear Probing”
① Insert
注意上例中哈希值是对H(key)是对13取模,而冲突时的递推公式是以表长16取模:
tips:
上图递推式中的 di为增量序列,对照6.006中对 Open Addressing的解释,这里计算出的 H0,H1,H2 ... Hi也就是所谓的探查序列(probe sequence),即对m个槽位的一次排列,每次寻找新的空槽位时都按这条探查序列搜索,注意区分概念
link:https://www.cnblogs.com/potofsalt/p/14941814.html
显然,线性探测法就是指 di从0开始连续 ++取值:
② Search
③ Delete
同样地,在6.006中已经介绍过,由于搜索时是按照同一个探查序列搜索,因此删除并不能直接将相应槽置为空,否则可能会使搜索失败,解决方法是为要删除的槽设置一个DELETE标志表示这个槽的内容已被删除
可能造成一种情况就是有可能槽中放了很多元素,但大部分都被DELETE标记,实际上元素很少
查找效率分析:
查找成功:
查找失败:
上例中初始哈希以13为模,因为d0=0,不难明白H0 = H(key)
也就是说探测序列中第一个元素就是初始哈希值,根据关键字与探测序列一一对应的关系显然总共有13条探测序列,按照均匀哈希假设,每个探测序列的取到概率为1/13,对应上图以此表示从0号槽开始,从1号槽开始, ... ,从12号槽开始,可以算出失败下的ASL如上。
Cons
线性探测法容易造成同义词、非同义词的Clustering(聚集、堆积)现象,
如下图,如果关键字k的初始探测位落入箭头所指任意槽,最终都会使聚集部分变长:
因此提出了一种另一种对增量序列di的取法:
平方探测法
注意平方探测法对表长m有一定限制:
伪随机序列法
正如其名,di是一个伪随机序列
再散列法
”Double Hashing“