首先明确,我们希望散列地址均匀得分布在地址空间。
但是冲突还是会发生,咋办?
两个思路:开放定址,和链地址
开放定址法:
线性探测法:
发生了i次冲突,就将下一次试探的地址增加di
hi(key) = (h(key)+di)mod TableSize
让我想起来大学半夜抢选修课,假设手速不够没选上足球(一),我会先在列表足球(一)上下看看,有没有足球(二)或者其他什么好的体育课
冲突容易聚集
平方探测法:
hi(key) = (h(key)±
)mod TableSize
二次聚集会比一次聚集轻,但还是会发生
数学上可以证明:TableSize是某个4k+3的素数时(k是正整数),平方探测法可以探测到整个散列表空间
双散列探测法:
hi(key) = (h(key) + i*h2(key))mod TableSize
可以弥补二次聚集
第二个散列函数h2(key)要是用不好,会暴雷!!!
再散列法:
扩大散列表,会出现停顿,如果用在救人的设备,那停顿可能就会要命
链地址:
分离链接法
冲突的关键词是同义词的数据对象通过结点链接存在同一个单链表里,HashMap也是这么用的吧
做实验啦!
{47,7,29,11,16,92,22,8,3,50,37,89,94,21}这14个关键字序列
使用h(key)=key mod 11 的散列方法
用分离链接法处理冲突