Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is deletion of an item at end of Dynamic array O(n) time complexity?

I am currently reading my textbook and I am totally confused why a dynamic array would require O(n) time to delete an item at the end. I understand that deleting an item from any other index is O(n) because you have to copy all the data and move them to fill in the gap, but if it’s at the end don’t we simply just decrement the count and set the index to like 0 or null? I included a picture from my book. It’s weird cause it says indexing is O(1) so we must know where the item is so we don’t have to traverse the array like a linked list.enter image description here

like image 251
Belphegor Avatar asked Dec 27 '18 04:12

Belphegor


People also ask

What is the time complexity at the end in dynamic arrays?

Either O(1) or O(n)

What is the time complexity of removing an item from the end of an array?

If the element which needs to be deleted is present in arr[0], we need to shift all the elements from index 1 to size - 1 by position to the left. So it will take N - 1 iteration. For example, if the array has 100 elements the for loop will work for 99 times. Hence the time complexity will be O(N - 1).

What is the time complexity of adding an element into a dynamic array?

If the dynamic array moves itself so that the entire array is contiguous (and so lookup is constant time), growing and moving the array will still take time. In the worst case asymptotically, inserting a new element takes O ( n ) O(n) O(n).

Is removing from array constant time?

If array[i] is to be deleted, simply keep a new list "deletedIndices" and add "i" to it. Thus, deletion will take constant time and space.


2 Answers

First, let's look up what the books means with a "Dynamic Array":

Dynamic array (also called as growable array, resizable array, dynamic table, or array list) is a random access, variable-size list data structure that allows elements to be added or removed. [...]
Note: We will see the implementation for dynamic array in the Stacks, Queues and Hashing chapters.

From this we learn that array lists are examples of a "Dynamic Array" as the author of the book defines it.

But looking further, the book mentioned that:

As soon as that array becomes full, create the new array of size double than the original array. Similarly, reduce the array size to half if the elements in the array are less than half.

(emphasis added by me)

A Java ArrayList doesn't do this - it doesn't decrease in storage when elements are removed. But the author is talking about (or believes that ArrayList does) reduce the array size. In that case, from a worst-worst-case perspective, you could say that the complexity is O(n) because reducing the size involves copying n elements to the reduced array.

Conclusion:

Although it's not true for Java ArrayList implementations, when the author of this book talks about "dynamic arrays" that "reduce the array size" on deletion when necessary, then the worst-case complexity of a delete at the end of the array is indeed O(n).

like image 74
Erwin Bolwidt Avatar answered Sep 28 '22 02:09

Erwin Bolwidt


That entry seems like it's either

  1. incorrect, or
  2. true, but misleading.

You are absolutely right that you can just destroy the object at the final position in a dynamic array and then decrement the size to remove the last element. In many implementations of dynamic arrays, you'll sometimes need to perform resize operations to make sure that the size of the allocated array is within some constant factor of the number of elements. If that happens, then yes, you'll need to make a new array, copy over the old elements, and free the previous array, which does take time O(n). However, you can show that these resizes are sufficiently infrequent that the average cost of doing a remove from the end is O(1). (In a more technical sense, we say that the amortized cost of removing an element from the end is O(1)). That is, as long as you care only about the total cost of performing a series of operations rather than the cost of any individual operation, you would not be wrong to just pretend each operation costs you time O(1).

I'd say that you're most likely looking at a typo in the materials. Looking at their entry for appending to the end, which differentiates between the not-full and full cases, I think this is likely a copy/paste error. Following the table's lead, that should say something to the effect of "O(1) if the array is not 'too empty,' O(n) otherwise." But again, keep in mind that the amortized efficiency of each operation is O(1), meaning that these scary O(n) terms aren't actually likely to burn you in practice unless you are in a specialized environment where each operation needs to work really quickly.

like image 21
templatetypedef Avatar answered Sep 28 '22 02:09

templatetypedef