debug help - swap 2 nodes of double link list

纵然是瞬间 提交于 2019-12-01 14:19:13

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 ;)

Your logic will not work,

  1. If node2 is the first element in the doubly linked list
  2. If node1 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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!