哈希冲突(Hash Collision)指的是对应不同的输入值产生了相同的哈希值从而引起的冲突。常用解决哈希冲突的方法有以下几种。
开放定址法(Open Addressing)
也叫再散列(Rehashing)方法,其基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不冲突的哈希地址pi ,将相应元素存入其中。这种方法有一个通用的再散列函数形式:
p
i
=
(
H
(
k
e
y
)
+
f
(
i
)
)
(
m
o
d
m
)
,
i
=
1
,
2
,
…
,
n
pi=(H(key)+f(i))(mod \ m), i=1,2,…,n
pi=(H(key)+f(i))(mod m),i=1,2,…,n
其中H(key)为哈希函数,m 为表长,
f
(
i
)
f(i)
f(i)$称为增量序列。
增量序列的取值方式不同,相应的再散列方式也不同。主要有以下三种:
- 线性探测(Linear Probing)
即 f ( i ) = i f(i)=i f(i)=i,冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表 - 二次探测
即 f ( i ) = c 1 i + c 2 i 2 ( c 2 ≠ 0 ) f(i)=c_1i+c_2i^2(c_2 \neq 0) f(i)=c1i+c2i2(c2=0) - 随机探测
即 f ( i ) f(i) f(i)由伪随机数生成 - 双哈希
独立链表法(Separate chaining)
独立链表法也叫拉链法,把哈希表是一个桶数组,独立链表法每个桶中存放着一个单链表的头结点或者列表。此时哈希表操作的时间是找到存储桶的时间(常量)加上列表操作的时间。在大多数实现中,如果哈希函数运行正常,则存储桶将只有很少的元素。
当发生冲突时,如下图的John Smith和Sandra Dee,就在发生冲突的位置新开一个链表节点重新存储。