【问题标题】:What is asymptotic complexity of List.Add?List.Add 的渐近复杂度是多少?
【发布时间】:2016-05-26 21:28:44
【问题描述】:

我发现List.Add() 的渐近复杂度存在很多争议。我怀疑它的来源是最坏的情况that causes underlying array to resize,逻辑上是O(n) 操作。但是,array grows twice in size 每次列表的空间不足。这使得n 元素所需的调整大小与log(n) 成正比。

这是否意味着在平均情况下Add 运算的渐近复杂度将为O(n/log(n))

List.Add() 的真正基准如下。但是,基准测试并不能真正表达这种操作 - 在任何与直线(对数刻度)的偏差变得可见之前,我们可能会耗尽内存。

【问题讨论】:

  • 当数组确实增长时,现有的 N/2 个元素会被移动。这就是为什么你认为它是 log N。但是新的尚未使用的容量呈指数增长。这抵消了效果。第一个元素被移动 log N 次。最后 N/2 个元素移动 0 或 1 次。

标签: c# algorithm asymptotic-complexity


【解决方案1】:

这意味着List.Add()amortized complexity 可以通过将调整大小操作相加然后乘以添加到列表中的总数来计算。

T(n) = (2 + 4 + 8 + ... + n/2 + n) / n

但请注意,总和是geometric series,我们可以做得比假设它是(总和)n*log(n) 更好:

T(n) < 2n/n = 2 -> T(n) is in O(1)

注意:这里我假设您的意思是 add() 作为附加。在任意位置插入元素需要O(n) 时间,您还必须考虑到这一点,这会将最终结果从O(1) 摊销复杂度更改为O(n) 摊销复杂度。

【讨论】:

  • 很好地解释了摊销的复杂性
  • 那么为了添加 n 个元素,list 会移动 2n 个元素,对吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
相关资源
最近更新 更多