哈希表的时间复杂度

Posted

技术标签:

【中文标题】哈希表的时间复杂度【英文标题】:Time complexity of Hash table 【发布时间】:2011-04-26 08:10:15 【问题描述】:

我对感到困惑,许多文章称它们是“摊销 O(1)”而不是真正的 O(1) 顺序,这在实际应用中意味着什么。哈希表中操作的平均时间复杂度是多少,在实际实现中不是理论上的,为什么这些操作不是真的 O(1)?

【问题讨论】:

这是相关的,虽然不是完全相同的问题:***.com/questions/2369467/… 这有助于回答插入问题,但没有解释任何其他操作,我最感兴趣的是关于在哈希表中查找的时间复杂度的解释 在哈希函数的一些假设下,对于大多数哈希表实现来说,查找是真正的 O(1) 时间。事实上,在一些有界桶深度的实现中,它在设计上是恒定的。 【参考方案1】:

不可能提前知道您的哈希函数会发生多少次冲突,以及需要调整大小等情况。这会给哈希表的性能增加一个不可预测的元素,使其不是真正的 O(1)。然而,几乎所有的哈希表实现在大量的、绝大多数的插入上都提供了 O(1)。这与数组插入相同——它是 O(1),除非你需要调整大小,在这种情况下它是 O(n),加上碰撞不确定性。

实际上,哈希冲突非常少见,您需要担心这些细节的唯一情况是您的特定代码必须在非常紧迫的时间窗口内运行。对于几乎每个用例,哈希表都是 O(1)。比 O(1) 插入更令人印象深刻的是 O(1) 查找。

【讨论】:

好吧,O(1) 查找也适用于数组【参考方案2】:

对于哈希表的某些用途,不可能提前创建“正确”大小的哈希表,因为不知道在表的生命周期内需要同时保存多少个元素。如果要保持快速访问,则需要随着元素数量的增加不时调整表格的大小。相对于表中已有元素的数量,这种调整大小需要线性时间,并且通常在插入时完成,当元素数量超过阈值时。

这些调整大小操作很少进行,以至于插入的摊销成本仍然保持不变(通过遵循表大小的几何级数,例如每次调整大小时将大小加倍)。但是不时插入一次需要 O(n) 时间,因为它会触发调整大小。

实际上,除非您正在构建硬实时应用程序,否则这不是问题。

【讨论】:

不仅要考虑大小,还要考虑哈希冲突。有不同的方法来处理它们,但无论你做什么,它都不会在 O(1) 时间内发生。在实践中,平均情况仍然接近 O(1),除非哈希表非常满 @Jords 我不知道“接近 O(1)”是什么意思。此外,我非常有信心,文献中发现的“摊销 O(1)”对应于散列函数的假设,其中桶深度保持在固定界限以下,因此是恒定时间。因为如果不调整大小的查找不是常数时间,摊销的查找也肯定不是常数时间。【参考方案3】:

将值插入到哈希表中需要平均情况下,O(1) 时间。哈希函数是 计算,从哈希表中选择bucked,然后插入item。在最坏的情况下, 所有元素都将散列到相同的值,这意味着整个桶列表必须是 遍历,或者在开放寻址的情况下,必须探测整个表,直到找到一个空点。 因此,在最坏的情况下,插入需要 O(n) 时间

参考:http://www.cs.unc.edu/~plaisted/comp550/Neyer%20paper.pdf(哈希表部分)

【讨论】:

好吧,如果它是“平均”,那么它应该写成 Θ(1) (Big-Theta)。 Big-O 是最坏的情况。

以上是关于哈希表的时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法--------哈希表

数据结构什么是哈希表?为什么哈希表的查询时间复杂度是O?

哈希表的简单理解

简单易懂数据结构之哈希表

数据结构---哈希表(散列表)

初级--03---二分复杂度哈希表和有序表