【问题标题】:Hash table deletion complexity哈希表删除复杂度
【发布时间】:2016-02-23 04:52:45
【问题描述】:

哈希表中删除的复杂度是多少?它可以根据它的实施方式而有所不同。如果它被实现为一个连续的数组,那么我们是否在删除时压缩数组(这使得它不是 O(1))?

如果是基于双向链表的,O(1) 删除是可能的,但在这种情况下我们如何将哈希键映射到链表节点?如果它是基于树的,那么它是可以理解的 O(logN)。

但是 C++ unordered_map 中的删除和 Java 中 HashMap 的旧实现声称是 O(1)。有人可以在这里填补实施空白吗?

编辑:为简单起见,我们假设没有冲突。

【问题讨论】:

  • Java的HashMap在哪里声称有O(1)的删除时间?
  • 假设没有冲突,您应该清楚删除(以及插入)是O(1) 操作。关于重新安排底层结构,即使发生这种情况,也可能不会在每次操作后发生。
  • shmosel:编辑了问题。我试图了解在没有冲突时实现 O(1) 的实现。
  • 哈希表实现如何不使用数组作为底层结构?

标签: java c++ algorithm data-structures time-complexity


【解决方案1】:

不保证移除 {Key, Value} 是恒定的时间性能(即不是 O(1))。

在documentation 中声称“为基本操作提供恒定时间性能,假设哈希函数将元素正确地分散在桶中”。

如果发生碰撞,不保证恒定时间性能

【讨论】:

    【解决方案2】:

    为什么要压缩?

    您的哈希表从 M 个空桶开始。如果您问存储桶 0 中有什么,它会告诉您“什么都没有”。你插入一些东西,最后说 N 个满桶和 M-N 个空桶。

    对象 O 恰好散列到存储桶 12。要插入它,请将其放入存储桶 12。如果删除 O,只需将存储桶 12 替换为空值,与开始时相同。如果你问 12 号桶里有什么,它会告诉你“什么都没有”。

    您通常希望数组比插入的项目数更大(例如,2 倍)。我认为我根本没有见过很多回收空间的实现——它们通常只会增长到使用更多,除非明确调整大小。

    你也可以有一个组合(LinkedHashMap?),你可以有效地使用一个双向链表来更快地遍历元素,但也需要支付上面的哈希映射的开销,在这种情况下,存储桶将包含一个指向链表节点。

    【讨论】:

    • 是的。这就说得通了。谢谢詹姆斯。我们真的不需要回收空间。
    猜你喜欢
    • 2020-11-19
    • 2012-03-02
    • 1970-01-01
    • 2011-04-26
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 2016-11-03
    • 2013-03-14
    相关资源
    最近更新 更多