Reputation: 483
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
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
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
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
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):
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:
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:
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
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
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
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.
Hope you get it.
Thanks
Upvotes: 2
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