This is from wikipedia: http://en.wikipedia.org/wiki/Arraylist under Performance.
ArrayList: constant time for remove(), add() at end of array, linear time to add(), remove() at beginning.
LinkedList: both of operations stated : constant time, indexing: linear.
1)Why the difference in arraylist processing time between the two operations?
2)Linkedlist is linear for indexing, constant for adding at the end, why?
1) Because to add/remove at the beginning it has to shift everything and reindex.
2) Because it maintains references to the head and tail (beginning & end). Indexing means traversing the list.
When you add to the end of an ArrayList, it will grow itself to have some room to spare. So if you have a ten-element ArrayList, adding at the end will cause it to internally allocate room for twenty elements, copy the ten you already had, and then add one. Then, when you add another element at the end, it just sticks that twelfth element into the space it already created.
This does not technically give it constant time insertion at the end, but it does give it amortized constant time insertion. That is to say, over a large number of operations, the cost approaches constant time; each time it grows, it doubles, so you'll have an ever-larger number of "free" constant-time inserts before you have to grow-and-copy again.
When you insert at the beginning, it can't do this and must always copy the whole list into a new location (linear time).
Removal from the end is always constant time because you just switch the last cell from being "filled" to "free space". You never need to copy the list.
As for your second question, a LinkedList keeps a pointer to the end of the list, so add and remove there just use that pointer and are thus constant time. There are no quick pointers into the middle of the list, so accessing an arbitrary element requires a linear-time traversal from start to (potentially) finish.
i) ArrayList -> You've got to push all the elements by one position in case of removal/addition in the beginning, hence linear time. At the end of array, you simply add or remove.
ii)LinkedList -> You have references of head and tail, hence you can add/remove anything there (in constant time).
Because removing at the end does not require moving the data. Adding may require copying to resize the storage array, but it's time is amortized.
Because adding at the end does not require walking the list, but indexing does.
Related
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.
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).
That entry seems like it's either
incorrect, or
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.
In java for Dynamic array (ArrayList) time complexity deletion of last element is o(1) in java it does not copy array
in java they will check weather the array index is end.
int numMoved = size - index - 1;
if (numMoved > 0)
//copy array element
Insertion and deletion are operations that we generally do not perform on arrays, because they have a fixed length by nature. You cannot increase or decrease the length of something which is fixed by its nature.
When people speak of "dynamic arrays" in Java they tend to mean using class ArrayList, which is backed by an array, and it provides the illusion of the ability to insert and remove elements.
But in order for some piece of software to provide the illusion of performing insertions and deletions on an array, each time (or almost each time, there are optimizations possible) it has to allocate a new array of the new desired length, and copy the old array into it, skipping the removed element or adding the inserted element as the case may be. That array copy is where the O(N) comes from.
And, due to the optimizations performed by ArrayList, the table that you posted is not accurate: it should rather say 'O(1) if the array has not shrunk by much, O(N) if the array has shrunk by so much that reallocation is deemed necessary'. But I guess that would have been too long to fit in the table cell.
As you have mentioned this could be confusing, if you add an element to a dynamic array, it change its size in a constant interval and will create a new array an copy elements to the new array as you may already know. And when it shrinks in size it will also shirk if needed.
For an example if interval is 4 when you add 1st, 2nd, 3rd, 4th element, everything will be okay, but when you add the 5th item dynamic array will grow into a 8 elements array and will copy the all elements to the new array.
It is the same when it is decreasing. If you remove one item from a 5 item array which has an interval of 4, dynamic array it will create a new 4 elements array and copy the elements.
Here is a good representation video tutorial,
Yes. When dynamic array does not have to shrink it is O(1) which it takes to remove the element but when it has to shrink its O(n), as you may already figured out.
when you find the big O notation you are defining the worst case, so it is O(n)
As far as I think
As it is a dynamic array so the computer system does not know as to what is the current length of this dynamic array so to find the length of this dynamic array it takes O(n) time and then takes O(1) time to delete the element at end.
Deleting an Item from Dynamic array(ArrayList in java) require to Search for the Item and than Delete.
If the element is at the end of list, than Search itself will result in n computation time. I hope this makes sense to you.
You can view source at http://www.docjar.com/html/api/java/util/ArrayList.java.html
I have to implement an algorithm that entry always inserted last and entry removed from first position.
i checked following link
Performing the fastest search - which collection should i use?
They say "ArrayList is stored in a continuous space in the memory. This allows the Operating System to use optimisations such as "when a byte in memory was accessed, most likely the next byte will be accessed soon". Because of this, ArrayList is faster than LinkedList in all"
but one case: when inserting/deleting the element at the beginning of the list (because all elements in the array have to be shifted). Adding/deleting at the end or in the middle, iterating over, accessing the element are all faster in case of ArrayList.
Here In my algorithm,always remove first element .So,always shifting happens.In that case i should not use arraylist??
It really depend on what more you wish to do with the structure.
If most of the time you are just adding at the end and removing from the start then any implementation of Deque would do. So ArrayDeque or LinkedList are probably your best candidates.
ArrayDeque is backed by an array and can therefore be accessed quickly by index with O(1) complexity but it has the downside that adding can be slower than LinkedList because sometimes the backing array needs to be resized.
LinkedList is just a linked-list so growing/shrinking it is consistently O(1) but accessing by index is not because to find the nth entry is O(n).
I need sequentially remove the middle element from sorted data. What would be the best way to do that? Since LinkedList operation takes n/2 time to remove the element, an arraylist would be faster. But an arraylist on the other hand then takes time to shift all the elements to the left, which isn't efficient either. Would other datastructures be of use maybe?
Removing the middle element is composed of two parts:
Finding the middle element
Deleting that element
ArrayList is O(1) at random access, so 1st step is fast for Array. While LinkedList is O(1) at deletion (given node), so 2nd step is easy for List.
What you want is best of both worlds.
IMO this is easily achievable if you write a custom (or extend existing) LinkedList. You'll need to have extra middle reference variable which will :
move to next upon insertion if the size becomes odd.
move to prev upon deletion if the size becomes odd.
You can also do even in both cases but they must be same (either even or odd).
Might a TreeSet fit the bill? If offers removal in O(log n) by key.
In page 290 of the book data structures and algorithms it is mentioned that complexity of remove(i) for arraylist is O(1). My first question is why not O(n)? It is also mentioned add(i,e) for linked list is O(n), so my second question is why not O(min(i,n-i))?
Finally, my 3rd question is the reason the complexity is mentioned as O(min(i,n-i)) is it due to being a doubly linked list, meaning we could either traverse from beginning (i) or end (n-i)?
The first one is debatable. When you remove the last element in an ArrayList, it's constant, but for a middle element, you need to shift all successor elements to the left. Java does that using System.arrayCopy(), a very fast native routine for copying arrays, but even that method is clearly O(n), not constant, so I'm inclined to agree with you. It's different for an insert, where the amortized cost of resizing arrays up to the required index is averaged out to a constant factor, so add() is O(1).
The second one could be implemented that way, but it isn't. Remove starts from the beginning only. I'm guessing the choice was made to reduce accidents by unsynchronized access.
Finally, in notations of Big-O complexity, less significant factors are discarded, so O(min(i,n-i)) is actually equivalent to O(n), even though the real world tells us that the former would certainly be an optimization.
I have been learning the tips of Java SE 7. I have read a statement about ArrayList:
Access is performed in constant time.
Insertion/deletion is performed in linear time.
I would like to know what is constant and linear time access?
constant time means there is a hard bound how much time each op will take to perform.
Linear time means the longer the ArrayList is (more object it contains) the longer time the op will take. The connection is linear, i.e. time(op) <= CONST * #elements
In complexity analysis, we refer it as big O notation and linear time is O(n), and constant time is O(1)
The reason for it is:
Access is plain array access, and it is done in constant time in RAM machine (such as out PCs).
Insertion/Deletion - if it is not in the last element, requires shifting all following elements: (Insertion requries shifting to the right, and deletion to the left) - thus you actually need a linear number of OPs to perform insertion/deletion (unless it is the last element)
The meanings are:
constant means that the time is always the same, it doesn't matter the length of the List.
[constant time is also called O(1) in Big-O notation]
linear means that the more the List grows, the longer is the time, but in a linear way, so for example to perform a linear operation on a list that contains 20 elements it will take two times the time needed for a list with 10 elements.
[linear time is also called O(n) in Big-O notation]
A precisation: when comparing algorithms is normally provided the worst case performance, so it means that the time needed is less or equal than linear.
In your case the implementation of the List is based on arrays (so the name ArrayList) like this:
The access time is constant because when the program knows where the first element of the list is and how big is every cell, it can directly get the n-th element using simple math like:
element_n_cell = element_1_cell + (cell_size * n)
Insertions and deletions are more time-expensive for two reasons:
When you insert or delete an element in a position, all the following elements need to be shifted.
An array can't be resized, so when you instantiate a new ArrayList, Java will create an array with a pre-defined length s, and it will use the same array as long as it fits. When you add the (s+1)-th element, the program needs to create a bigger array and copy all the elements in the new one.
Undestand Constant time access
java.util.ArrayList implements java.util.RandomAccess interface, which is a marker interface that signifies that you can directly access any element of this collection. This also implies that it takes the same amount of time (constant time) to access any element.
If we take java.util.LinkedList, it takes more time to access the last element than the first element.