简体   繁体   English

动态数组的时间复杂度

[英]Time Complexity of Dynamic Arrays

I am a bit confused about time complexity of Dynamic Arrays.我对动态数组的时间复杂度有点困惑。 In this article here it states that the time complexity of insertion and deletion of Dynamic Array is O(n). In this article here它指出动态数组的插入和删除的时间复杂度是O(n)。 I wanted to know why that is the case for insertion and deletion of dynamic array.我想知道为什么插入和删除动态数组会出现这种情况。

My understanding of why the insertion of Dynamic Array might be O(n) is because once an element is inserted the other elements need to be moved back and that is O(n).我对为什么插入动态数组可能是 O(n) 的理解是因为一旦插入一个元素,其他元素就需要移回,也就是 O(n)。 However I read somewhere else the reason for this is because in case you run out of space then extra space is reallocated the previous items copied and pasted into the new memory location.I wanted to know which reasoning is correct.但是我在其他地方读到,这是因为如果你用完了空间,那么额外的空间会被重新分配,之前的项目被复制并粘贴到新的内存位置。我想知道哪个推理是正确的。 Also my reasoning for an array having a time complexity of O(n) for deletion is that once an element is deleted other elements are moved forth to cover the deleted items space.However again the article gives another answer and states that since searching is O(n) in Dynamic array thus deleting is O(n) in dynamic array since an element is searched before its deleted.另外,我对删除时间复杂度为 O(n) 的数组的推理是,一旦删除了一个元素,其他元素就会向前移动以覆盖已删除的项目空间。然而,文章再次给出了另一个答案,并指出由于搜索是 O (n) 在动态数组中因此删除是 O(n) 在动态数组中,因为在删除元素之前搜索元素。 I would appreciate it if someone could clarify this confusion.如果有人能澄清这种混淆,我将不胜感激。 Thanks.谢谢。

My understanding of why the insertion of Dynamic Array might be O(n) is because once an element is inserted the other elements need to be moved back 我对为什么插入动态数组可能是O(n)的理解是因为一旦插入了一个元素,其他元素就需要被移回

Correct. 正确。

Also my reasoning for an array having a time complexity of O(n) for deletion is that once an element is deleted other elements are moved forth to cover the deleted items space. 另外,我对于具有用于删除的O(n)的时间复杂度的阵列的推理是,一旦删除了元素,则移出其他元素以覆盖删除的项目空间。

Correct. 正确。

However I read somewhere else the reason for this is because in case you run out of space then extra space is reallocated the previous items copied and pasted into the new memory location. 但是我在其他地方读到了这个的原因是因为如果你的空间不足,那么额外的空间会重新分配以前的项目被复制并粘贴到新的内存位置。

I think you're confusing something here. 我觉得你在这里混淆了一些东西。 Maybe you are thinking about what happens if you insert at the end and the array overflows. 也许你正在考虑如果你在最后插入并且数组溢出会发生什么。 In that case you also have to copy the whole array to a new, larger location. 在这种情况下,您必须将整个阵列复制到一个新的更大的位置。 But the cost for this can be charged to the insertions at the end that must have happened for this situation to occur. 但是,这种情况的成本可以通过最终的插入来收取,这种情况必然发生在这种情况下。 So insertion at the end is "amortized O(1)" . 因此,最后插入“摊销O(1)”

The exact same reasoning works for deletion. 完全相同的推理适用于删除。

To summarize: Insertion/deletion at position k of an array has amortized complexity O(n - k) . 总结:在阵列的位置k处的插入/删除具有分摊的复杂度 O(n-k) In particular, insertion/deletion at an arbitrary position is O(n) and insertion/deletion at the end is O(1). 特别地,在任意位置的插入/删除是O(n),并且最后的插入/删除是O(1)。

However again the article gives another answer and states that since searching is O(n) in Dynamic array thus deleting is O(n) in dynamic array since an element is searched before its deleted 然而,文章再次给出了另一个答案,并指出由于在动态数组中搜索是O(n)因此在动态数组中删除是O(n),因为在删除之前搜索了一个元素

Searching has nothing to due with insertion/deletion. 搜索与插入/删除无关。 When considering insertion/deletion cost, you usually assume that you already know the position where you want to insert/delete. 在考虑插入/删除成本时,通常假设您已经知道要插入/删除的位置。

Suppose you have a dynamic array that doubles its size every time it needs to expand.假设您有一个动态数组,每次需要扩展时它的大小都会加倍。 Suppose you start with an array of size 1 and add 1 element.假设您从一个大小为 1 的数组开始并添加 1 个元素。 I will represent the act of writing a datum into the array with an x:我将用 x 表示将数据写入数组的行为:

x

Now let's add a second element, forcing the array to expand and the previous 1 item to be copied:现在让我们添加第二个元素,强制扩展数组并复制前一项:

  x
x x

The array now has size 2. I add another element, forcing resizing to 4 and copying of 2 elements: xxxxxx该数组现在的大小为 2。我添加了另一个元素,强制将大小调整为 4 并复制了 2 个元素:xxxxxx

I add a fourth and then a 5th element, which forces resizing again to 8:我添加了第四个元素,然后是第五个元素,这再次强制将大小调整为 8:

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

Now let me rewrite that last "tower" to spread its height across two columns.现在让我重写最后一个“塔”,将其高度分布在两列中。 This represents a kind of amortized cost .这代表一种摊余成本

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

The next time we need to resize is when we insert the 9th item.下一次我们需要调整大小是在我们插入第 9 个项目时。 This time, I will represent the effort already with amortization of the copying of 8 items over the previous 8 insertions.这一次,我将代表之前 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

In general, each doubling-and-copying operation will come on the insertion after the completion of a successive power of 2, and the number of items copied will be that power of 2, which is half the number of insertions since the last doublying-and-copying.一般来说,每个加倍和复制操作将在完成连续的 2 次方后插入,复制的项目数将是 2 的次方,这是自上次加倍以来插入次数的一半 -和复制。 So this means that, amortized, the average of each insertion operation requires the insertion and two copies, or a total of 3, which makes the cost 3n which is in O(n).所以这意味着,摊销后,平均每个插入操作需要插入和两个副本,或者总共 3 个,这使得成本为 3n,在 O(n) 中。 The key point is amortization.关键是摊销。 The cost of inserting n elements into a dynamic array (that doubles its size on expansion) is bursty , but, on average , in O(n).n 个元素插入动态数组(在扩展时将其大小加倍)的成本是突发的,但平均而言,在 O(n) 中。 You could think of each insertion as "paying the cost" or the "tax" of the future copies that might have to be performed when the array expands.您可以将每次插入视为在数组扩展时可能必须执行的未来副本的“支付成本”或“税”。

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

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