【问题标题】:Benefits of queue using linkedlist vs queue using array for hash-table bucket?使用链表的队列与使用数组的哈希表存储桶的队列的好处?
【发布时间】:2017-05-07 21:14:39
【问题描述】:

我知道实现队列的两种方法,使用链表或使用数组。我应该使用哪一个来在哈希表中制作存储桶,当存储桶超过条目限制时,哈希表需要重新散列。我是否有可能获得 O(1) 入队和出队以及使用其他数据结构的索引?

使用数组我可以让存储桶大小达到更高的值,因为数组中的索引让我可以对键使用二进制搜索(按排序顺序插入)。考虑一下如果桶大小变为 1000,搜索变为 ln(1000) 与 1000 的好处。插入操作变为 O(n),但是查找比插入更常见。

使用链表我得到 O(1) 插入,删除但我也得到 O(n)。

我的问题是,我是否可以同时使用其他数据结构获得好处,或者使用这些数据结构的好处明显比其他更多?

【问题讨论】:

  • 我试图了解您为什么要使用队列作为哈希表存储桶。为什么不直接使用动态列表?
  • @JimMischel 你的权利,让我解释一下,编辑问题。

标签: data-structures linked-list hashmap queue


【解决方案1】:

我认为你问错了问题。与其担心如何处理存储桶中的大量项目,不如关注存储桶为何变得过满。

哈希表假设两件事:

  1. 您选择了一个散列函数,可以在存储桶之间提供良好的项目分布。
  2. 您不会让负载系数过高。一个好的哈希表实现将提供相当不错的性能,负载因子高达约 0.8,但超过此性能会急剧下降。我认为大多数实现都喜欢将负载因子保持在 0.7 以下。因此,如果哈希表中的项目数超过表容量的 70%,则应考虑增加容量。当负载因子超过某个阈值时,大多数哈希表实现会自动增加容量。

当您选择使用哈希表时,您有责任确保这两个条件都成立。如果您选择了较差的哈希函数或超过了设计的负载因子,性能将受到影响,并且再优化存储桶结构也无济于事。

您的存储桶列表结构的实现应该无关紧要,因为您的存储桶不应大到足以产生性能差异。一个简单的链表为您提供 O(1) 插入和 O(k) 查找(其中 k 是存储桶中的项目数)。但是 k 不应该超过 2 或 3,因此使用渐近更高效的数据结构是没有意义的。

无论您如何实现存储桶,当您超过哈希表的容量(或负载因子阈值,如果您的哈希表实现自动执行)时,您将不时支付 O(n) 调整大小的代价调整大小)。

【讨论】:

  • 所以如果存储桶变得太大或者大约 70% 已满,我应该重新整理表?我不应该在存储桶中使用另一个哈希表。
  • @AchyutRastogi:我从未见过检查存储桶中项目数量的实现。通常,我所看到的是一个系统,如果当前存储的项目数超过某个阈值(通常在容量的 70% 到 80% 之间),则表会被重新散列。
【解决方案2】:

当您为哈希表实现存储桶时,您应该使用链表,因为它们可以调整大小。您需要在哈希映射中的存储桶中执行的唯一操作是遍历和追加新项目,这两者都可以在每个元素的O(1) 中完成。当您使用数组时,您分配的内存不必要或太少,因为您无法调整它的大小。而且,你不应该使用队列,你最好使用普通的链表。

【讨论】:

    猜你喜欢
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    相关资源
    最近更新 更多