【问题标题】:Implementing Hash Table with binary search tree用二叉搜索树实现哈希表
【发布时间】:2017-11-23 03:01:57
【问题描述】:

这是《破解哈希表编码面试》中颇有争议的一句话。

哈希表的另一个常见实现(除了链表)是使用 BST 作为底层数据结构。

我知道以前有人问过这个问题……这太令人困惑了,因为每个人都给出了两个不同的答案。例如

Why implement a Hashtable with a Binary Search Tree?

这篇文章中投票率最高的答案是上面引用的声明是在谈论使用二叉搜索树的哈希表实现,没有底层数组。我了解到,由于插入的每个元素都有一个哈希值(一个整数),因此这些元素形成了一个总顺序(每一对都可以与 进行比较)。因此,我们可以简单地使用二叉搜索树来保存哈希表的元素。

另一方面,别人说

Hash table - implementing with Binary Search Tree

这本书说我们应该用二叉搜索树来处理冲突。所以有一个底层数组,当多个元素获得相同的哈希值并被放置在数组的同一个槽中时发生冲突时,这就是 BST 的用武之地。

所以数组中的每个槽都是一个指向 BST 的指针,它保存具有相同哈希值的元素。

我倾向于第二篇文章的论点,因为第一篇文章并没有真正解释哈希表的这种实现如何处理冲突。而且我认为它无法达到预期的 O(1) 插入/删除/查找时间。

但是对于第二篇文章,如果我们有多个元素获得相同的哈希值并放置在 BST 中,我不确定这些元素是如何排序的(如何相互比较?)

请帮我彻底解决这个问题!

【问题讨论】:

    标签: hash hashtable binary-search-tree


    【解决方案1】:

    第一篇文章并没有真正解释哈希表的这种实现如何处理冲突

    使用 BST,您可以使用不会产生重复键的散列函数,因此不会发生冲突。这里的优势不是速度,而是减少内存消耗,并有更好的最坏情况保证。如果您正在为关键的实时系统编写软件,您可能无法容忍 O(n) 调整哈希表的大小。

    如果我们有多个元素获得相同的哈希值并放在 BST 中,我不确定这些元素是如何排序的(如何相互比较?)

    用另一个函数重新散列。

    最后,这一切都取决于您的数据结构的用途(内存与速度更重要吗?摊销性能与最坏情况下的性能更重要吗?等等)

    【讨论】:

    • 关于第一个区块引用的 cmets... 不产生任何重复值的散列函数是完美的散列函数,对吗?如果我们为此实现使用 PHF 和 BST,有哪些缺点?它必须有一些缺点
    • 您能否解释一下为什么 BST + PHF 实现会导致 O(n) 调整大小的时间?
    • PHF + BST 的缺点是速度较慢,因为插入和搜索将是 O(log n) 相对于具有 O(1) 的基于数组的哈希表。在 C++ 中,std::map 使用带有 PHF 实现的 BST,而 std::unordered_map 使用数组,并且 std::map 几乎总是比 std::unordered_map 慢(除了 std::map 为空的情况)。 BST + PHF 没有 O(n) 调整大小,它是每个桶中的数组 + BST 来处理必须在 O(n) 内调整大小的冲突,通常当数组中的桶数达到 50% 时。跨度>
    猜你喜欢
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 2010-12-06
    • 2020-04-20
    • 2015-07-23
    • 1970-01-01
    相关资源
    最近更新 更多