链表问题:合并与拼接链表时出现执行异常
问题分析与解决
你的代码出现异常的核心原因是:mergeLL函数直接修改了原链表节点的next指针,彻底破坏了first和second原链表的结构,后续操作使用被破坏的链表指针时,就会出现循环输出或结构混乱的问题。
具体问题拆解
先执行
mergeLL再执行concatenation导致无限输出mergeLL在合并过程中,会将原链表节点的next指针反复置为NULL并重新链接到fourth链表中。例如:- 一开始会把
first或second的头节点next设为NULL,打断原链表 - 循环中每次取原链表节点后,都会将该节点的
next设为NULL,再接到fourth上
这导致first和second不再是独立的完整链表,它们的节点已经被拆分融入fourth。此时执行concatenation(second, first),会将两个已被破坏且存在交叉引用的链表拼接,最终形成循环链表,Display函数遍历会无限循环。
- 一开始会把
先执行
concatenation再执行mergeLL导致无法打印concatenation会将first链表直接拼接到second的末尾,此时second和first已经是同一个链表的连续部分。再执行mergeLL(first, second)时,相当于对同一个链表的两个重叠部分进行合并,操作过程中会反复修改节点指针,最终导致链表结构彻底混乱,无法正常遍历打印。
解决方案:实现不破坏原链表的合并函数
修改mergeLL函数,通过创建新节点复制数据的方式实现合并,完全保留原链表的结构,这样后续操作可以正常使用first和second。
修改后的mergeLL代码:
void mergeLL(struct Node *p, struct Node *q) { struct Node *last = NULL; fourth = NULL; // 初始化合并后的链表头 // 合并两个有序链表,创建新节点复制数据 while (p && q) { struct Node *t = (struct Node *)malloc(sizeof(struct Node)); t->next = NULL; if (p->data < q->data) { t->data = p->data; p = p->next; } else { t->data = q->data; q = q->next; } if (fourth == NULL) { fourth = t; last = t; } else { last->next = t; last = t; } } // 处理第一个链表剩余节点 while (p) { struct Node *t = (struct Node *)malloc(sizeof(struct Node)); t->data = p->data; t->next = NULL; last->next = t; last = t; p = p->next; } // 处理第二个链表剩余节点 while (q) { struct Node *t = (struct Node *)malloc(sizeof(struct Node)); t->data = q->data; t->next = NULL; last->next = t; last = t; q = q->next; } }
验证效果
修改后:
- 先执行
mergeLL,first和second仍保持原有序结构,fourth是全新的合并链表 - 再执行
concatenation(second, first),可以正常将first拼接到second末尾,得到完整的拼接链表,Display能正常输出无循环
内容的提问来源于stack exchange,提问作者user271914
相关产品推荐
相关产品推荐

