c - 调试帮助 - 交换双向链表的 2 个节点

标签 c data-structures linked-list

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

这是代码:

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->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仍然是错误的!

<小时/>

如何解决这个问题?这不是一句简单的话就能解决的,因为有一些特殊情况。

也许可以检测到我描述的特殊情况并为其提供单独的代码(并且不要忘记其他特殊情况)。

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

关于c - 调试帮助 - 交换双向链表的 2 个节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8306267/

相关文章:

c - 在 C 函数中删除链表节点不会传输到调用函数

c - 使用 gdb 进行调试时,如何打印整个链接结构列表中的所有特定属性?

c - MPI 库 - 在数组上保存值时出现问题

c# - 三角形存储为数组。每层的高度和长度?

arrays - 一次仅删除一个元素后,查找从父数组产生的已排序数组的数量

android - 使用链表保存对象 - API 10 错误

c - 将container_of宏应用于嵌入的char数组时报告警告

c++ - 如何在 C 中构造具有绝对整数值和等效 char 整数值的 char 数组?

java - 用于响应元素进入的数据结构?

c - 为什么这么多示例链表将 next 指针放在每个节点的末尾而不是开头?