繁体   English   中英

动态数组的时间复杂度

[英]Time Complexity of Dynamic Arrays

我对动态数组的时间复杂度有点困惑。 In this article here它指出动态数组的插入和删除的时间复杂度是O(n)。 我想知道为什么插入和删除动态数组会出现这种情况。

我对为什么插入动态数组可能是 O(n) 的理解是因为一旦插入一个元素,其他元素就需要移回,也就是 O(n)。 但是我在其他地方读到,这是因为如果你用完了空间,那么额外的空间会被重新分配,之前的项目被复制并粘贴到新的内存位置。我想知道哪个推理是正确的。 另外,我对删除时间复杂度为 O(n) 的数组的推理是,一旦删除了一个元素,其他元素就会向前移动以覆盖已删除的项目空间。然而,文章再次给出了另一个答案,并指出由于搜索是 O (n) 在动态数组中因此删除是 O(n) 在动态数组中,因为在删除元素之前搜索元素。 如果有人能澄清这种混淆,我将不胜感激。 谢谢。

我对为什么插入动态数组可能是O(n)的理解是因为一旦插入了一个元素,其他元素就需要被移回

正确。

另外,我对于具有用于删除的O(n)的时间复杂度的阵列的推理是,一旦删除了元素,则移出其他元素以覆盖删除的项目空间。

正确。

但是我在其他地方读到了这个的原因是因为如果你的空间不足,那么额外的空间会重新分配以前的项目被复制并粘贴到新的内存位置。

我觉得你在这里混淆了一些东西。 也许你正在考虑如果你在最后插入并且数组溢出会发生什么。 在这种情况下,您必须将整个阵列复制到一个新的更大的位置。 但是,这种情况的成本可以通过最终的插入来收取,这种情况必然发生在这种情况下。 因此,最后插入“摊销O(1)”

完全相同的推理适用于删除。

总结:在阵列的位置k处的插入/删除具有分摊的复杂度 O(n-k) 特别地,在任意位置的插入/删除是O(n),并且最后的插入/删除是O(1)。

然而,文章再次给出了另一个答案,并指出由于在动态数组中搜索是O(n)因此在动态数组中删除是O(n),因为在删除之前搜索了一个元素

搜索与插入/删除无关。 在考虑插入/删除成本时,通常假设您已经知道要插入/删除的位置。

假设您有一个动态数组,每次需要扩展时它的大小都会加倍。 假设您从一个大小为 1 的数组开始并添加 1 个元素。 我将用 x 表示将数据写入数组的行为:

x

现在让我们添加第二个元素,强制扩展数组并复制前一项:

  x
x x

该数组现在的大小为 2。我添加了另一个元素,强制将大小调整为 4 并复制了 2 个元素:xxxxxx

我添加了第四个元素,然后是第五个元素,这再次强制将大小调整为 8:

        x
        x
    x   x
  x x   x
x x x x x

现在让我重写最后一个“塔”,将其高度分布在两列中。 这代表一种摊余成本

    x x x
  x x x x
x x x x x

下一次我们需要调整大小是在我们插入第 9 个项目时。 这一次,我将代表之前 8 次插入中复制 8 项的摊销工作。

    x x x x x x x
  x x x x x x x x
x x x x x x x x x

一般来说,每个加倍和复制操作将在完成连续的 2 次方后插入,复制的项目数将是 2 的次方,这是自上次加倍以来插入次数的一半 -和复制。 所以这意味着,摊销后,平均每个插入操作需要插入和两个副本,或者总共 3 个,这使得成本为 3n,在 O(n) 中。 关键是摊销。 n 个元素插入动态数组(在扩展时将其大小加倍)的成本是突发的,但平均而言,在 O(n) 中。 您可以将每次插入视为在数组扩展时可能必须执行的未来副本的“支付成本”或“税”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM