Reputation: 2753
Let's assume we have a java.util.LinkedList containing a few hundreds of elements. One possibility to insert a new element E after the an existing element K would be:
list.add(list.indexOf(K) + 1, E);
As far as I understand this method has an O(k2) behavior where k denotes the position of element K. First indexOf() runs through the list until it finds K and afterwards add has to do the same work again until it reaches position k + 1. But the entries which have to be modified could in easily be determined after the first step. I think it wouldn't be that much work to create a method addAfter(K, E) with O(k) behavior.
Is there a way to improve the performance in a scenario like this one besides switching to java.util.ArrayList?
Thank you in advance.
Upvotes: 0
Views: 545
Reputation: 3078
This sample of code is to make k operations:
LinkedList<Integer> list = new LinkedList<Integer>();
for(int i=0;i<100;i++){
list.add(i);
}
Integer insert = 1001;
Integer before = 50;
for (ListIterator<Integer> iterator = list.listIterator(); iterator.hasNext();) {
Integer next = iterator.next();
if(next.equals(before)){
iterator.add(insert);
break;
}
}
Upvotes: 1
Reputation: 718758
As far as I understand this method has an O(k2) behavior where k denotes the position of element K. First indexOf() runs through the list until it finds K and afterwards add has to do the same work again until it reaches position k + 1.
Actually, the cost of list.add(list.indexOf(K) + 1, E)
is O(k)
if list
is a LinkedList
.
The list.indexOf(K)
call involves k
link traversals and k
comparisons.
The list.add(k + 1, E)
call involves k + 1
link traversals.
Add them up - 3 k + 1
operations; i.e. O(k)
.
However, you are right. It would be possible to create an alternative version of LinkedList
with an addAfter
or addBefore
method. These methods would also be O(k)
but they should be faster. Unfortunately, LinkedList
is not implemented in a way that would allow you to simply add these methods (and implement them optimally). The internals of LinkedList
are declared as private, so you would need to start over.
And incidentally list.add(list.indexOf(K) + 1, E)
on an ArrayList
will be O(N)
where N
is the list length. The indexOf
step takes k
comparisons, and the add
step involves moving N - k
elements. Ergo N
operations and O(N)
Upvotes: 2
Reputation: 15486
You wrong with your assumption, that it is O(k^2), its just O(2k) which is O(k) (Btw here must be not k=index of element, but size of list, but that doesnt matter for the problem). But you are right it takes twice as long and is inefficent. The only way I can think of is to use ListIterator
and find/insert yourself (which is intended to do exactly this kind of manipulations).
Upvotes: 4