【问题标题】:Why is iterating over a hashmap O(c/n)?为什么要遍历哈希图 O(c/n)?
【发布时间】:2013-03-26 20:16:46
【问题描述】:

有很多链接告诉我哈希图的大 O 是:

get   O(1)
add   O(1)
contains O(1)
next item O(c / n)    c = table capacity (number of buckets) n = size

get/add/contains 为什么是 O(1) 有点明显,但我想知道为什么迭代是 O(c/n)。

当我在做的时候,我很想知道为什么大 O 是 ConcurrentHashmap、TreeMap 等的。

谁有好的链接?

【问题讨论】:

  • O(c/n) 的来源是什么?我从来没有见过这样的BigO。迭代(遍历整个集合)总是 O(n)。
  • 链接的论文没有说迭代是O(h/n)。它说“下一个条目”O(h/n)。迭代是“下一个条目”对于每个 n.
  • @pst 我将编辑问题。对不起。但是谁能解释为什么?

标签: performance hashmap


【解决方案1】:

链接的论文没有说迭代是O(c/n)。它说“下一个条目”是O(c/n)。迭代是每个 n 的“下一个条目”。

首先,请注意 c (capacity) > n (entries) 是一个不变量 - 而 c 是 n 的某个函数 - 所以 O(c/n) > O(1/n)。 (注意:根据评论,我并不完全确定我对 HashMap 实现中使用链式解决冲突的不变量的断言。)

所以这实际上说明的是,在标准 HashMap 中,在执行“下一个条目”时查看的一些存储桶是 并且必须被跳过。因此,对于“下一个条目”,边界“超过”O(1/n)。不过,在阅读此边界时要小心,因为它并不意味着迭代速度更快,n 越多,它只是根据 n 条目的总数来描述“下一个条目”的边界。 p>

由于迭代实际上只是所有 n 的“下一个条目”,因此对于 HashMap 的迭代:

O(1/n * n) -> O(n)
O(c/n * n) -> c*O(n) -> ~O(n)

(由于cn 的函数,它可能在不同的情况下将其作为常数提取出来会有点误导;因此是曲线。)

【讨论】:

  • 首先,“下一个条目”是什么意思,为什么是容量>条目。如果您有 6 个存储桶和 18 个条目,则 c
  • 只是想深入挖掘一下“下一个条目” - 但它没有被订购。那么,如果使用 order,这是否意味着获得下一个有序的元素?我同意迭代是 O(N)。还是对“下一个条目”感到困惑?
  • @MoreThanFive “下一个条目”并不意味着订单。从“第一个条目”开始并重复调用“下一个条目”最终将到达“最后一个条目”,同时仅返回哈希映射中的条目,而不会重复一个条目。
  • 好吧,如果是这样的话,我看不出它不是 c*O(n) 的任何原因,因为它实际上是 c 链表,这意味着 O(n)。所以我会接受你的回答。
猜你喜欢
  • 1970-01-01
  • 2014-06-01
  • 1970-01-01
  • 2011-04-25
  • 2013-11-25
  • 2016-04-12
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多