【问题标题】:When is an AVL tree better than a hash table?什么时候 AVL 树比哈希表更好?
【发布时间】:2012-02-08 23:48:14
【问题描述】:

更具体地说,如果使用 AVL 树而不是哈希表,是否可以更有效地执行任何操作?

【问题讨论】:

  • 这个问题有点模糊,无法详尽回答。它很大程度上取决于哈希表的实现,但是在树中的查找操作很可能比在哈希表中快得多。此外,保证在任何类型的树上查找具有公共前缀的多个键都比在哈希表(--> 处理器缓存)上快得多。由于高度限制和重新平衡,插入/删除操作很可能不会更有效,但是哈希表可能还需要执行不平凡的操作,直到重建整个哈希(-->实现?)。跨度>
  • 没有。除非您考虑哈希表无法支持的操作。就像保持秩序和支持重复键一样。不必这样做是使哈希表从根本上快速的原因。
  • 谢谢大家,这些点正是我想要的。抱歉,如果问题措辞不当。
  • @HansPassant:哈希表不是“基本快”,不是一般的。它们基本上具有 O(1) 复杂度(加上 O(N)),但这并不能保证它们在每种情况下都更快。特别是对于大型数据集,哈希表是两个保证的缓存未命中(更多具有开放寻址,超出一定负载)。另一方面,一棵树有合理的机会在缓存中拥有大部分(如果不是全部)节点,尤其是在查找相关键时,并且不需要最终比较。添加到 O(N) 时间以计算哈希。它真的取决于实现、数据集和访问模式。
  • “哈希表”是一个不完整的解决方案。预期键的“正确”散列函数是什么?如何处理哈希冲突?在最坏情况下的哈希冲突场景中使用了多少(或多少)可​​用存储? AVL 树总是可以实现 100% 的利用率。

标签: performance data-structures hashmap hashtable avl-tree


【解决方案1】:

我通常更喜欢 AVL 树而不是哈希表。我知道哈希表的预期时间 O(1) 复杂度胜过 AVL 树的保证时间 O(log n) 复杂度,但在实践中,常数因素使这两种数据结构通常具有竞争力,并且没有任何琐碎的担忧一些引起不良行为的意外数据。另外,我经常发现在程序的维护生命周期中的某个时候,在未预见到的情况下,哈希表的初始选择似乎是正确的,我需要按排序顺序的数据,所以我最终重写程序以使用AVL 树而不是哈希表;这样做足够多的时间,你就会发现你还不如从 AVL 树开始。

如果您的键是字符串,则三元搜索尝试为 AVL 树或哈希表提供了一个合理的替代方案。

【讨论】:

    【解决方案2】:

    当然,一个明显的区别是,对于 AVL 树(和其他平衡树),您可以拥有持久性:您可以在 O(log N) 中从树中插入/删除一个元素空间和时间,最终不仅得到新树,而且还保留了旧树。

    使用哈希表,您通常无法在少于 O(N) 的时间和空间内完成此操作。

    另一个重要的区别是键所需的操作:AVL 树需要在键之间进行 <= 比较,而哈希表需要 = 比较以及 hash 函数。

    【讨论】:

    • 这不是全部。存在许多具有对数复杂度的持久类哈希表结构的实现。例如。 en.wikipedia.org/wiki/Hash_array_mapped_trie 请注意,这是 clojure 和 scala 实现其默认 Map 类型的方式。
    • @OscarBoykin:确实,HAMT 可以看作是哈希表和二叉树的混合体。
    猜你喜欢
    • 2013-10-14
    • 2016-07-11
    • 2018-04-17
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 2012-02-26
    相关资源
    最近更新 更多