Could you please help me debug this code to swap two node of double link list? I am not able to figure out what i am doing wrong :(
here is the code:
Your logic will not work,
node2 is the first element in the doubly linked listnode1 and node2 are adjacent.Please fine the updated logic given below.
dll* swap_node(dll *head , dll *node1 , dll *node2)
{
dll* previous_to_node1 = NULL;
dll* next_to_node1 = NULL;
dll* previous_to_node2 = NULL;
dll* next_to_node2 = NULL;
if ((node1 == NULL) || (node2 == NULL))
return 0;
previous_to_node1 = node1->previous;
next_to_node1 = node1->next;
previous_to_node2 = node2->previous;
next_to_node2 = node2->next;
if (previous_to_node1 != NULL) previous_to_node1->next = node2;
if (next_to_node1 != NULL) next_to_node1->previous = node2;
if (pevious_to_node2 != NULL) previous_to_node2->next = node1;
if (next_to_node2 != NULL) next_to_node2->previous = node1;
node1->next=next_to_node2;
node1->previous=previous_to_node2;
node2->next=next_to_node1;
node2->previous=previous_to_node1;
if (previous_to_node1 == NULL)
{
return node2;
}
else if(previous_to_node2 == NULL)
{
return node1;
}
return head;
}
Suppose node1->next == node2 && node2->prev == node1. Now let's trace:
if(node1->next!=NULL)
{
node1->next->prev=node2;
}
Now node2->prev points to node2 itself!
if(node2->prev!=NULL)
{
node2->prev->next=node1;
}
Now node2->next points to node1, which is ok for now.
Recall that node1->next still points to node2, and node2->next points to node1.
tmp=node1->next; // == node2
node1->next=node2->next; // == node1 (!)
node2->next=tmp; // == node2
So we have node1->next pointing to node1, and node2->next to node2. Clearly wrong.
Recall that node2->prev points to node2, although node1->prev is correct.
tmp=node1->prev; // correct
node1->prev=node2->prev; // == node2
node2->prev=tmp; // correct
So node1->prev points to node2, which is correct.
But node1->next and node2->next are still wrong!
How to solve this? It's not a one-liner to solve, as there are a couple special cases.
Maybe detect the special case I described and have separate code for it (and don't forget about that other special case).
Writing that code is left as an exercise to the reader ;)