1、开放定址法
Hi = (H(key) + di) % mi = 1,2,3…,k (k <= m -1)
其中:H(key) 为哈希函数,m为哈希表长度,di为增量序列,可以有下列3中取法:
(1) di = 1,2,3,…,m-1,称为线性探测再散列;
(2) di = 1^2, -1^2, 2^2, -2^2, …,±k^2, (k <= m / 2)称为二次探测再散列;
(3) di = 伪随机数序列,称伪随机探测再散列。
例:
在长度为11的哈希表中已填有关键字分别为17, 60, 29的记录(哈希函数为H(key) = key % 11),现在有第四个记录,关键字为38 。
H(17) = 6
H(60) = 5
H(29) = 7
addr | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
60 | 17 | 29 |
1.1、采用线性探测再散列
H(38) = 5,冲突
H1 = (5 + 1) % 11 = 6 ,冲突
H2 = (5 + 2) % 11 = 7 ,冲突
H3 = (5 + 3) % 11 = 8 ,不冲突,则插入38关键字后,表为:
addr | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
60 | 17 | 29 | 38 |
1.2、采用二次探测再散列
H(38) = 5,冲突
H1 = (5 + 1) % 11 = 6 ,冲突
H1 = (5 - 1) % 11 = 4 ,不冲突,则插入38关键字后,表为:
addr | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
38 | 60 | 17 | 29 |
1.3、采用伪随机探测再散列
H(38) = 5,冲突
H1 = (5 + 随机数 9) % 11 = 3 ,不冲突,则插入38关键字后,表为:
addr | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
38 | 60 | 17 | 29 |
2、再哈希法
Hi = RHi (key) i = 1,2,3…,k
RHi 均是不同的哈希函数,即在同义词产生地址冲突时计算另一个哈希函数地址,直到冲突不再发生。这种方法不易产生‘聚集’,但增加了计算的时间。
3、链地址法
将所有关键字为同义词的记录存储在同一个线性链表中。假设某哈希函数产生的哈希地址在区间[0, m-1]上,则设立一个指针向量 Chain ChainHash[m] 其每个分量的初始状态都是空指针。凡哈希地址为i的记录都插入到头指针为Chain ChainHash[i]的链表中。在链表中年的插入位置可以在表头或者表尾,也可以在中间,以保持同义词在同一线性链表中按关键字有序。
例:已知一组关键字为:19,14,23,01,68,20,84,27,55,11,10,79
则按照哈希函数H(key) = key % 13 和链地址法处理冲突构造所得的哈希表如下所示。
4、建立公共溢出区
假设哈希函数的值域为[0,m-1],则设向量HashTable[0…m-1]为基本表,每个分量存放一个记录,另设向量OverTable[0…v]为溢出表。将发生冲突的记录填入溢出表