【问题标题】:debug help - swap 2 nodes of double link list调试帮助 - 交换双向链表的 2 个节点
【发布时间】:2011-11-29 05:25:12
【问题描述】:

你能帮我调试这段代码来交换双链表的两个节点吗?我无法弄清楚我做错了什么:(

代码如下:

dll* swap_node(dll *head , dll *node1 , dll *node2) {
   dll *tmp;
   int flag=0;

   if(node1->prev!=NULL) {
       node1->prev->next=node2;
   } else {
       flag=1;
   }
   if(node1->next!=NULL) {
       node1->next->prev=node2;
   }

   if(node2->prev!=NULL) {
       node2->prev->next=node1;
   }
   if(node2->next!=NULL) {
       node2->next->prev=node1;
   }

   tmp=node1->next;
   node1->next=node2->next;
   node2->next=tmp;

   tmp=node1->prev;
   node1->prev=node2->prev;
   node2->prev=tmp;

   if(flag==1) {
       head=node2;
   }
   return head;
}

提前致谢

【问题讨论】:

  • 如果node1和node相邻怎么办?即:node1->next == node2 && node2->prev == node1。在这种情况下,指针会发生什么?

标签: c data-structures linked-list


【解决方案1】:

假设node1->next == node2 && node2->prev == node1。现在让我们追踪:

if(node1->next!=NULL)
{
   node1->next->prev=node2;
} 

现在node2->prev 指向node2 本身!

if(node2->prev!=NULL)
{
    node2->prev->next=node1;
}

现在node2->next 指向node1,现在可以了。

回想一下node1->next 仍然指向node2,而node2->next 指向node1

tmp=node1->next;  // == node2
node1->next=node2->next; // == node1 (!)
node2->next=tmp;  // == node2

所以我们有node1->next 指向node1node2->next 指向node2。明显错了。

回想一下,node2->prev 指向node2,尽管node1->prev 是正确的。

tmp=node1->prev; // correct
node1->prev=node2->prev; // == node2
node2->prev=tmp; // correct

所以node1->prev 指向node2,这是正确的。

但是node1->nextnode2->next还是错了!


如何解决这个问题?这不是单线解决问题,因为有几个特殊情况。

也许会检测到我描述的特殊情况并有单独的代码(不要忘记其他特殊情况)。

编写该代码作为练习留给读者;)

【讨论】:

    【解决方案2】:

    你的逻辑不行,

    1. 如果node2是双向链表的第一个元素
    2. 如果node1node2 相邻。

    请细化下面给出的更新逻辑。

    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)) 返回0; previous_to_node1 = node1->上一个; next_to_node1 = node1->下一个; previous_to_node2 = node2->previous; next_to_node2 = node2->下一个; 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; 节点1->下一个=下一个节点2; node1->previous=previous_to_node2; 节点2->下一个=下一个节点1; node2->previous=previous_to_node1; 如果(previous_to_node1 == NULL) { 返回节点2; } 否则如果(previous_to_node2 == NULL) { 返回节点1; } 返回头; }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 2014-04-17
      相关资源
      最近更新 更多