开放地址法(Open Addressing)

104 阅读2分钟

开放地址法(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

    1. → 位置 3 已被占用,检查位置 4 (2 + 3

    2. → 插入位置 4

哈希表状态:

json

Copy

[ ] [ ] [12] [22] [32] [ ] [ ] [ ] [ ] [ ]

这些例子展示了开放地址法的基本概念和操作方式。每种方法的选择会影响哈希表的性能和效率

PS: 之前的文章中关于open addressing:

Java 低延迟: Trove (Part 1) : juejin.cn/post/723766…