0

I tried to implement a circularly linked list and I had read that the complexity of removing the tail (which has a direct reference) is O(1). However I can't get rid of the tail reference without looping and resulting in a complexity of O(n) and so I was wondering if this is at all possible without looping?

    remove =   tail;
    prev        =   temp    =   tail.getNext();

    do
    {
        prev    =   temp;
        temp    =   temp.getNext();
    }
    while(!temp.getNext().equals(tail.getNext()));

    prev.setNext(temp.getNext());
    size--;
    return remove;

Note: prev, temp, removeare local and tail is the tail of the list and first instance of tail.getNext() is the head.

I had tried the below as well but it does not work as the node before tail still points to tail and the reference isn't removed. I know that I need make the tail's previous point to the head in order to remove the tail and the above code does this, but I'm just unsure how to do this and if it's possible without looping through the list..

    remove =   tail;
    tail=   lastNode.getNext();
    size--;
    return remove;
jn025
  • 2,755
  • 6
  • 38
  • 73
  • you need to loop to find prev node of tail node.. and then point prev node next reference to head node. To find prev of tail node you need to loop until you find next of next node is head node. – virendrao Apr 01 '15 at 05:12

1 Answers1

1

In a circularly linked list every node has a previous and next. There is the head pointer to the first node, and its previous is the tail node, whose next is the head node.

So

Node removeTail() {
     if (head == null) {
         return null;
     }

     Node tail = head.previous;
     Node newTail = tail.previous;
     newTail.next = head;
     head.previous = newTail;

     if (head == tail) {
         head = null;
     }
     --size;
     return tail; // If so desired.
}
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • but if its singular not double circular it wont have previous node i guess.. if its double circular and your answer is perfect i guess – virendrao Apr 01 '15 at 05:30
  • @virendrao right, I assumed double linkage automatically, But there is no way in java, even if you have a tail field in the List class, to get an O(1) removal. – Joop Eggen Apr 01 '15 at 05:37
  • agree.. yeah your answer is for double linkage if single linkage you need to loop till tail node – virendrao Apr 01 '15 at 05:39
  • Yeah mine is singly linked. Might try with a double linked implementation then. Would you say that the double linked is much more efficient than single and if this is the case would there be any situation to use a single over a double? – jn025 Apr 01 '15 at 05:45
  • 1
    @joe may be this help http://stackoverflow.com/questions/15563043/when-is-doubly-linked-list-more-efficient-than-singly-linked-list – virendrao Apr 01 '15 at 05:50
  • ***1*** The point is, that for a single linked list being circular has no real benefit. For a double linked list circular implies that you may take the shortest direction to the ith item. ***2*** A single linked list may fit a more restricted list usage better. Especially if concurrent modification comes into play. – Joop Eggen Apr 01 '15 at 07:18