【问题标题】:Hash Table with Chaining (Table Doubling)链式哈希表(表加倍)
【发布时间】:2015-12-31 03:34:36
【问题描述】:
  1. 当所有项目散列到同一个槽(一个巨大的 LinkedList)时,如何使用链接修复散列表?
  2. 带有链接的哈希表是否使用表加倍?如果是这样,什么时候将表格的大小加倍。

【问题讨论】:

  • 1.您无法阻止这种情况发生,但您可以通过使用加密哈希函数 (siphash) 使其不可利用。 2. 带有链接的哈希表通常使用 1 的负载因子,因此当哈希表完全填满时,您应该加倍。

标签: algorithm data-structures hashtable chaining


【解决方案1】:

在哈希表的每个位置,添加一个二级数​​据结构,例如二叉树或另一个哈希表。

例如,如果多个值被散列到第一个哈希表中的相同位置,那么将它们放入该位置的二叉树将使您在 O(lg n) 时间内搜索/插入它们,而不是 O (n) 使用链表的时间。

如果您想使用另一个哈希表,那么您需要对位于第一个哈希表中相同位置的值应用不同的哈希函数。在第二次散列之后,这些值将有望落在第二个散列表中的不同位置。

【讨论】:

    【解决方案2】:

    扩展 NikiC 的 cmets 的答案:

    对于您的第一个问题,不幸的是,在实现链式哈希表时,这是一种真正的可能性。假设你有一个好的散列函数——或者,更好的是,选择一个包含一些随机元素的散列函数——这是极不可能的。不幸的是,Bad People 有时会使用它来关闭 Web 服务器。不久前,一种称为“Hash DoS”的攻击被开发出来,通过这种攻击,有人会向 Web 服务器发出一堆专门的请求,这将导致所有内容都存储在链式哈希表的同一个槽中,从而带来巨大的性能下降并最终使一些网站下线。不过,好消息是,许多编程语言实现都已更新,因此它们的哈希表不会受到此类情况的影响。

    对于第二个问题,答案是“视情况而定”。当负载因子变得太高时(通常,负载因子在 1 和 2 之间很常见),链式哈希表的大多数优秀实现都会重新散列并增长。但是,有些实现没有。例如,我相信 Java 中的 ConcurrentHashMap 实现不会进行任何重新散列,因为当许多读写同时执行时这样做是不可行的。

    【讨论】:

      猜你喜欢
      • 2010-10-19
      • 2011-02-03
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      • 2015-07-05
      • 2020-09-03
      • 2012-12-31
      • 1970-01-01
      相关资源
      最近更新 更多