warpstar
warpstar

Reputation: 483

Reversing a Doubly Linked List

This method right below reverses a doubly linked list with n elements. I dont understand how this really works. I have added comments, please correct me if I am wrong. I am not sure how the traversing process works.

 public void reverseDLL( ) {
   Node temp=head; //swap head and tail
   head=tail; // head now points to tail
   tail=temp; //tail points to head
    //traverse the list swapping prev and next fields of each node
  Node p=head; //create a node and point to head

  while(p!=null) //while p does not equal null
    { //swap prev and next of current node
      temp=p.next; // p.next does that not equal null? confusing.
      p.next=p.prev; //this line makes sense since you have to reverse the link
      p.prev=temp; //having trouble visualizing this.
      p=p.next;//advance current node which makes sense
    }
 }

Upvotes: 6

Views: 38906

Answers (8)

i.AsifNoor
i.AsifNoor

Reputation: 587

My version without recursion that I wrote in Java Idea behind: Reach the end of list first, mark this node as new head, then start moving backwards direction by flipping connections/Links (next, prev) till you have left no more node.

 Node Reverse(Node head) {
        //If List is empty or having one node
        if (head == null || head.next == null) return head;

        //Else
        Node current = head;

        //First move to the end of list
        while (current.next != null) {
            current = current.next;
        }
        //Shift head at tail of list
        head = current;

        //Let the magic begin
        while (current != null) {
                Node prev = current.prev;
                current.prev = current.next;
                current.next = prev;
                current = prev;
        }


        return head;
    }

I hope it helps.

Upvotes: 0

M Sach
M Sach

Reputation: 34424

It can be started from head node also for simplicity, otherwise the algorithm remains the same:

Node currentNode=head;

while(currentNode!=null){
    Node temp = currentNode.next;
    currentNode.next=currentNode.prev;
    currentNode.prev=temp;
    currentNode=currentNode.prev;
}

Upvotes: 1

RuntimeException
RuntimeException

Reputation: 1643

With a Header Doubly Linked List, following is what I understand. Does this help? Is this correct?

The loop may be broken out when current is one node behind tail, but for simplicity, let it reach the tail. Also, the usual checks for 0 or 1 sized list come before running the loop.

H   1   2   3   4   5   //current pointer at head
*

H   5   1   2   3   4   //bring current tail to the next of current pointer. Update current tail.
*

H   5   1   2   3   4   //advance current pointer to next
    *

H   5   4   1   2   3   //bring current tail to the next of current pointer. Update current tail.
    *

H   5   4   1   2   3   //advance current pointer to next
        *

H   5   4   3   1   2   // and so on.. 
        *

H   5   4   3   1   2
            *

H   5   4   3   2   1
            *

H   5   4   3   2   1
                *

H   5   4   3   2   1
                *

H   5   4   3   2   1   //break out when current pointer is at the tail. 
                    *

Upvotes: 1

cklab
cklab

Reputation: 3771

Let's try stepping through the code a few lines at a time.

Node temp=head;
head=tail;
tail=temp;

Here we are just setting up some variables. We are swapping our head to point to the tail and the tail to the head.

Now we define our starting node. This is our new head that used to be the tail.

Node p=head; //create a node and point to head

while(p!=null)
{ 
    temp=p.next; 

At this point, this is what we are looking at (note: if this is the first iteration, next would point to null but that doesn't matter, just assume A is null for that case): enter image description here

So we have next pointing to A and prev pointing to B. We want these to be swapped. To do so, we go ahead and assign next to prev (which points to B) so now next and prev both point to B.

    p.next=p.prev; 

Great! We're half way there. Now we have:

Step 2

Now our last step is to have prev point to what next used to point to. How are we going to get to it? Luckily, we stored what next used to point to (in other words, A) in temp. So let's use that to assign prev.

    p.prev=temp; 

Alas, we have:

enter image description here

Now this node has been swapped, and we move on to the next.

    p=p.next;
}

Rinse and repeat.

All together:

Node p=head; //create a node and point to head

while(p!=null)
{ 
    temp=p.next; 
    p.next=p.prev; 
    p.prev=temp; 
    p=p.next;
}

Upvotes: 26

hardik
hardik

Reputation: 1

public void reverseList(){

    Entry<E> refEntry = header.previous;
    for(int i = 0; i < size-1; i++){
        Entry<E> first = header.next;
        first.next.previous = first.previous;
        first.previous.next = first.next;

        first.previous = refEntry;
        first.next = refEntry.next;
        refEntry.next.previous = first;
        refEntry.next = first;
    }
    refEntry.previous = header;
}

The algorithm basically maintains a pointer(refEntry) to the entry which is going to be the first element in the list after reversal.

The first element of the list is then removed in iterations and added after the refEntry.

Upvotes: 0

dansalmo
dansalmo

Reputation: 11686

The key to how this reversal works is see what a simple doubly linked list looks like before and after it is reversed. Once you see what needs to happen to reverse the list, the method will be easier to understand.

Suppose you had a Nodes like this with the first node at 0:

node       0    1    2    3    4
data       A    L    I    S    T
next       1    2    3    4   null
prev      null  0    1    2    3

Traversing the nodes above starting at 0 gives the output: ALIST

Leaving the data of each each node in place, you can reverse the list by swapping the prev and next node values for each node:

node       0    1    2    3    4
data       A    L    I    S    T
next      null  0    1    2    3
prev       1    2    3    4   null

Traversing the nodes above starting at 4 gives the output: TSILA

The code to do this is simple assuming you have a Node class as such:

public class Node {
    private char ch;
    private Node next;
    private Node prev;
}

public static Node reverse(Node trav) {
    Node swapped;
        while (trav != null) {
            swapped.next = trav.prev;
            swapped.prev = trav.next;
            trav = swap;
            trav = trav.prev;  // it was swapped so you need to follow prev
            }
        return trav  // return the new head node
}

Upvotes: 0

vijay
vijay

Reputation: 2034

Hope this helps you.

struct node* current = head;
struct node* next;
struct node* prev = NULL;



while (current != NULL)  //traverse the whole linked list 
{
   next  = current->next;  //temporarily store the next node
   current->next = prev;    //now assign the prev!node to next of current node
   prev = current;   //update the previous pointer
   current = next;  //update the current pointer

}

Look at this figure. enter image description here

Hope you get it.

Thanks

Upvotes: 2

sbkp
sbkp

Reputation: 91

It's just swapping the prev and next pointers in every element of the list. So your comment is correct. The new head's next pointer does start as null. And it gets copied to its prev pointer. As the head of the list its prev should of course be null.

Vj shah's answer does the same thing just with different code.

Upvotes: 1

Related Questions