3

I know that we can iterate over the list in the reverse order as follows:

List<Object> lst;
ListIterator<Object> i = lst.listIterator(lst.size());

But is it efficient if lst is a LinkedList? I mean when we obtain the ListIterator pointing to the end of the list, does the implementation iterate over the list from the begging to the list.size() position (takes O(n) time, where n is a size of the list)?

If it does, is there a way to avoid it?

St.Antario
  • 26,175
  • 41
  • 130
  • 318

5 Answers5

1

The documentation states that LinkedList is a "Doubly-linked list implementation of the List and Deque interfaces". So every element in the list has references to both the next AND the previous elements. So, the iterator should be as quick in the reverse order as it is in the natural order.

Eric Leibenguth
  • 4,167
  • 3
  • 24
  • 51
1

The javadoc states that LinkedList is a doubly-linked list, so I would expect descendingIterator(), which return an iterator pointing to the tail of the list, to be O(1). Note that descendingIterator is from the Deque interface.

Now it is difficult to say whether the statement lst.listIterator(lst.size()) is also O(1), because it is not documented if listIterator method optimize the fact that the next element from lst.size() is the tail.

UmNyobe
  • 22,539
  • 9
  • 61
  • 90
1

It doesn't iterate over the list to produce the iterator.

The best place to look for solutions to these is the Source Code.

  if (index < (size >> 1)) {
          next = header.next;
          for (nextIndex=0; nextIndex<index; nextIndex++)
              next = next.next;
      } else {
          next = header;
          for (nextIndex=size; nextIndex>index; nextIndex--)
              next = next.previous;
      }

As you can see, it will try to reach the index using the shortest path either from the first node or last node.

Codebender
  • 14,221
  • 7
  • 48
  • 85
1

LinkedList also implements Deque interface.

So if you implement it as

Deque list = new LinkedList();

Or if you additionally need the list methods

LinkedList list = new LinkedList();

You can use

list.descendingIterator();
Denis Lukenich
  • 3,084
  • 1
  • 20
  • 38
1

Your code will not work, the index lst.size() is out of bounds, maybe you meant lst.size()-1. But still it is not a reverse iterator, it is a forward iterator that instead of beginning at 0 will begin at the element you specify. In this case you will read only the last element then reach the end.

LinkedList implements interface Deque which provides Deque.descendingIterator. In this case both instancing the iterator and moving to the next (previous) element are O(1) operations. In the first case it's because the Deque implementation keeps a reference to both the beginning and the end of the queue, in the second because LinkedList is a doubly-linked list, in which every element keeps a reference to both its successor and his predecessor.

Shepard
  • 801
  • 3
  • 9
  • 17
  • Now I see, you instanced it like that to iterate through previous(). In this case yes it works. But to be sure about complexity I'd go with Deque.reverseIterator(), even if at the end they should do the same operations. – Shepard Jul 13 '15 at 08:25
  • `IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())` – UmNyobe Jul 13 '15 at 08:25