开放地址法(Open Addressing)是一种解决哈希冲突的技术。在这种方法中,当发生冲突时,算法会在哈希表中查找下一个可用的空位,而不是使用链表等额外的数据结构来存储冲突的元素。
以下是开放地址法的一些常见类型及示例:
1. 线性探测(Linear Probing)
在发生冲突时,算法会检查下一个位置,依次向后查找直到找到空位。
示例:
假设有一个哈希表大小为 10,哈希函数为 h(key) = key % 10
。
- 插入 12:
h(12) = 2
→ 插入位置 2 - 插入 22:
h(22) = 2
→ 位置 2 已被占用,检查位置 3 → 插入位置 3 - 插入 32:
h(32) = 2
→ 位置 2 和 3 已被占用,检查位置 4 → 插入位置 4
哈希表状态:
json
Copy
[ ] [ ] [12] [22] [32] [ ] [ ] [ ] [ ] [ ]
2. 二次探测(Quadratic Probing)
在发生冲突时,算法根据平方的增量查找空位。
示例:
同样的哈希表和哈希函数:
- 插入 12:
h(12) = 2
→ 插入位置 2 - 插入 22:
h(22) = 2
→ 位置 2 已被占用,检查位置 3 (2 + 1^2) → 插入位置 3 - 插入 32:
h(32) = 2
→ 位置 2 和 3 已被占用,检查位置 6 (2 + 2^2) → 插入位置 6
哈希表状态:
json
Copy
[ ] [ ] [12] [22] [ ] [ ] [32] [ ] [ ] [ ]
3. 双重哈希(Double Hashing)
使用第二个哈希函数来计算增量,避免聚集。
示例:
仍然使用相同的哈希表和第一个哈希函数,第二个哈希函数为 h2(key) = 7 - (key % 7)
。
-
插入 12:
h(12) = 2
→ 插入位置 2 -
插入 22:
h(22) = 2
→ 位置 2 已被占用,使用第二个哈希函数:h2(22) = 7 - (22 % 7) = 3
,所以检查位置 5 (2 + 1*3) → 插入位置 5 -
插入 32:
h(32) = 2
→ 位置 2 和 5 已被占用,使用第二个哈希函数:h2(32) = 7 - (32 % 7) = 1
,所以检查位置 3 (2 + 2-
→ 位置 3 已被占用,检查位置 4 (2 + 3
-
→ 插入位置 4
-
哈希表状态:
json
Copy
[ ] [ ] [12] [22] [32] [ ] [ ] [ ] [ ] [ ]
这些例子展示了开放地址法的基本概念和操作方式。每种方法的选择会影响哈希表的性能和效率
PS: 之前的文章中关于open addressing:
Java 低延迟: Trove (Part 1) : juejin.cn/post/723766…