哈希表删除复杂性

Hash table deletion complexity

本文关键字:复杂性 删除 哈希表      更新时间:2023-10-16

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

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

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

编辑:为了简单起见,让我们假设没有碰撞。

删除 {键, 值} 不能保证是常量时间性能(即不是 O(1))。

在文档中声称"为基本操作提供恒定时间性能,假设哈希函数在存储桶中正确分散元素"。

在发生碰撞时,恒定时间性能不高

为什么要压缩?

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

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

您通常希望使数组大于(例如,2 倍)大于插入的项目数。我认为我还没有看到很多回收空间的实现 - 除非明确调整大小,否则它们通常只会增长以使用更多空间。

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