【问题标题】:Hash Table v/s Trees哈希表与树
【发布时间】:2012-04-05 17:49:40
【问题描述】:

哈希表总是比树快吗?尽管哈希表具有 O(1) 的搜索复杂性,但假设如果由于设计不良的哈希函数发生大量冲突,并且如果我们使用链式结构(例如平衡树)处理冲突,那么搜索的最坏情况运行时间将是 O(log n )。因此,即使在最坏的情况下,我是否可以得出大数据集或小数据集的结论,哈希表总是比树快?另外,如果我有足够的内存并且我不想进行范围搜索,我可以一直使用哈希表吗?

【问题讨论】:

  • 我不是专家,但我会说这是情境性的。许多散列函数很昂贵,对于某些访问模式,树是好的。
  • “总是”是一个包罗万象的大词。您是否有机会编辑此问题以将其简化为更具体的内容,例如特定场景(仅)?否则它几乎肯定会因为不具建设性而被关闭。
  • 这里很多人都提到最坏的情况是 O(N)。如果使用平衡树结构而不是链表来处理冲突,怎么可能是 O(n)。在像 AVL 这样的平衡树中搜索的最坏情况是 O(log n)
  • @avinashshah 您可以通过使用其他一些溢出数据结构来减少最坏情况的搜索情况,但您不会免费获得O(lg n) 搜索。它是以O(lg n) 插入为代价的,因为您现在正在插入一棵树或类似的树,在最坏的情况下它包含所有元素。在几乎所有的应用程序中,权衡是不值得的。

标签: algorithm data-structures hash tree hashtable


【解决方案1】:

哈希表总是比树快吗?

不,不是总是。这取决于很多因素,例如集合的大小、散列函数以及某些散列表的实现——还有删除操作的数量。

哈希表是O(1) 每个操作平均 - 但情况并非总是如此。在最坏的情况下,它们可能是O(n)

目前我能想到的一些喜欢树的原因:

  1. 订购很重要。 [哈希表不维护顺序,BST按定义排序]
  2. Latency 是一个问题 - 您不能忍受可能发生的 O(n)。 [这可能对实时系统至关重要]
  3. 其他数据可能与您的散列函数“相似”,并且许多元素散列到相同位置 [冲突] 并非不可能。 [这有时可以通过使用不同的哈希函数来解决]
  4. 对于相对较小的集合 - 哈希表的 O(1) 之间的隐藏常数很多时候比树的高得多 - 对于小型集合,使用树可能更快。

但是 - 如果数据量很大,则延迟不是问题,并且不太可能发生冲突 - 哈希表在渐近上比使用树更好。

【讨论】:

  • 通常情况下,由于缓存一致性(无论是来自主内存还是磁盘),精心打包的树可以胜过哈希表。在这种情况下,您拥有多少数据并不重要——根据您使用字典结构的方式,哈希表可能不是您的最佳选择。
  • 什么哈希表?打开寻址哈希表或“桶”哈希表?有或没有增量调整?还是基于线性散列?有这么多 散列表的实现!你的回答对他们中的一些人来说是错误的,所以请准确。
  • @MatthieuM.:这些是几乎所有哈希表的传统缺点,即使使用开放寻址或将简单数组链接为“桶”也是如此。排序是缺点,因为散列不能保证保持顺序。由于最坏的情况,延迟是一个问题(如果您由于某些限制而不能遭受任何O(n) 操作 - 这是一个问题),类似的哈希值并不是真正的缺点,因为它可以通过选择不同的哈希函数轻松解决,如果我没记错的话,大小问题通常是由于哈希函数开销造成的。你具体有什么问题?
  • @amit:不,它们不是(除了订购......显然)。例如,延迟在这里定义不明确。我可以保证使用哈希表进行 O(1) 插入(使用增量调整大小),而对于 BST,我将定期进行重新平衡操作,因此最坏的情况是 O(log N)。然而,O(1) 查找是不可能保证的;但是我可以通过使用 BST 作为存储桶结构来获得 O(log N)。 小型集合同样可以从开放寻址哈希表中受益:每个节点的开销更小,单块分配 => 比 BST 更好的 CPU 缓存行为!所以......并非所有 cmets 都同样适用于所有实现。
  • @MatthieuM.:好的,我明白你的意思了。确实,没有灵丹妙药,是的 - 有一些变通方法可以解决“传统” DS 的一些问题(例如 BST 作为存储桶),实际上没有一个同样适用于所有人,但这些是一些应该解决的问题在为您的套装选择 DS 时考虑。
【解决方案2】:

如果由于哈希函数设计不当导致发生大量冲突,并且如果我们使用链式结构(例如平衡树)处理冲突,那么搜索的最坏情况运行时间将是 O(n) (不是 O(log n))。因此,即使在最坏的情况下,您也无法得出大数据集或小数据集的结论,哈希表总是比树快。

【讨论】:

    【解决方案3】:

    使用哈希表,并以适当的维度对其进行初始化。例如,如果你只使用一半的空间,那么碰撞就很少了。

    【讨论】:

      【解决方案4】:

      在最坏的情况下,您将在 hast-tables 中花费 O(n) 时间。 但是这比现在太阳爆炸写的可能性小数十亿,所以当使用一个好的哈希函数时,你可以放心地假设它在 O(1) 中工作,除非太阳爆炸。
      另一方面,哈希表和树的性能可能因实现、语言和月相而异,所以这个问题的唯一好的答案是“尝试两者,思考并选择更好”。

      【讨论】:

        猜你喜欢
        • 2011-11-10
        • 2010-10-23
        • 2011-05-06
        • 2023-03-31
        • 2019-05-17
        • 2016-10-03
        • 2010-11-30
        • 2011-06-18
        • 2010-10-25
        相关资源
        最近更新 更多