目录
下一篇:排序的定义
一、定义
示例:
当取余进行到1时,1已经存了一个元素了
当不同的关键字通过散列函数映射到同一个值,则他们为“同义词”,确定的位置已经存放了其他元素,则这种情况为“冲突”
二、处理冲突的方法
1、拉链法(java中的HashSet等)
使用拉链法最后结果,插入时放在链头链尾都一样
查找时通过取余运算找到散列函数确定的位置遍历链表就找到了
例如:注意查找长度概念
该表的平均查找长度
说明:第一层有6个,第二层有4个,第三场和第4层都是1个。∑层数*该层元素个数最后除以元素总数12得出
通过另一个计算ASL的方法可以看出
查找失败的ASL
对于一个大小是0-12共13个元素的哈希表
每个被映射的概率都是1/13
则
优化
装填因子
三、设计散列函数
常见的散列函数
1、除留余数法
为什么用质数?因为可以让哈希分布更加均匀
例如:下面的例子在元素都是偶数的情况(例如车牌号大多是双数)下对7取模和对8取模的不同,大概就是公因子越少,取余出来的共同特征就更少
散列函数应该结合实际的关键字分布特征来考虑,不要教条化,答题时也是如此,根据实际画出来的表判断哪个更好
2、直接定址法
3、数字分析法
4、平方取中法
可以看出1210的平方计算过程中绿色方框部分是与1210相关的
可以用在
也可以为了绝对避免冲突,即直接定址法
思想:
5、开放定址法
(1)线性探测法
该例子中元素1放置时发生1次冲突,进行重新计算算出得2发现2的位置是空的于是放在2上,其他元素以此类推
最后结果为:
小细节:
即直接计算哈希值能够放的了的是0-12,发生冲突后可能能放的了的是0-15
线性探测法的查找操作
例如查找上表中的27,同样线性探测
可以看出同义词14和1与27是同义词(对13取模都是1),68是非同义词,所以同义词与非同义词都被检测了
再找一个不存在的例如21
发现线性查找到第一个空位置就表示查找失败
注:空位置的对比也算是一次比较,与拉链法不同,拉链法的空位置是指针不算一次对比
不难发现,如果提升空位置的数量则查找失败的长度将被减少,例如:
哈希表删除一个元素
例如删除1,如果我们直接删除就会发现一个问题
这时我们查找27会发现27明明有但是前面有个空位置会判定为失败
解决:
可以发现开放定址法的一个弊端
找79有8次冲突要对比9次
计算ASL成功(将所有关键字都计算比较次数):
查找失败的ASL(哈希函数第一次只可能映射到0-12)
为什么效率这么低?
(2)解决聚集问题:平方探测法
注:84是6-9=-3再+27对27取模得出84放在24的位置
同样查找的时候也是根据di的规则来
一个坑:
(3)伪随机序列法
di是一个随机序列
(4)再散列法(使用多个散列函数)
小结: