链表归并排序异常:排序后丢失首个节点的技术求助
链表归并排序丢失首节点的修复方案
嘿,我来帮你搞定这个问题!你提到用归并排序给链表排序后丢失了首个节点,看你贴的mergeSort函数逻辑是没问题的——递归拆分、合并的思路完全正确,问题大概率出在你没写完的merge函数里,另外也得确认下middleElement函数的实现是否有坑。
先排查最可能的问题:merge函数的错误
我猜你的merge函数大概率没处理好收尾逻辑,或者返回值错了。这里给你一个正确的实现,对比下你自己的代码找差异:
public Node merge(Node left, Node right) { // 用一个空的哨兵节点简化合并逻辑,不用额外处理头节点的特殊情况 Node temp = new Node(); Node current = temp; // 循环比较左右链表的节点,按从小到大的顺序拼接 while (left != null && right != null) { // 假设你的Node类有一个data字段用来存储排序依据的值 if (left.data <= right.data) { current.next = left; left = left.next; } else { current.next = right; right = right.next; } current = current.next; } // 把左右链表中剩余的节点直接接上(只会有一边有剩余) if (left != null) { current.next = left; } if (right != null) { current.next = right; } // 重点!返回哨兵节点的下一个节点,这才是合并后的真实头节点 return temp.next; }
你可能犯的错误:
- 最后返回了
temp(哨兵节点本身)而不是temp.next:这样会把空的哨兵节点当成头节点,看起来像是丢失了原本的首节点; - 没有处理循环结束后剩余的节点:如果其中一边链表还有未比较的节点,没接上的话就会丢失这部分节点,包括可能的首节点;
- 循环里的节点赋值逻辑错误,比如把
current.next指向了错误的节点。
再确认middleElement函数的实现
如果merge函数没问题,那就要检查找中间节点的函数是否正确。错误的中间节点定位会导致拆分链表时丢节点,比如用快慢指针时的初始位置不对:
public Node middleElement(Node head) { if (head == null || head.next == null) { return head; } // 慢指针从head出发,快指针从head.next出发,这样拆分后前半部分长度不会小于后半部分 Node slow = head; Node fast = head.next; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } return slow; }
如果你的middleElement用的是fast = head作为初始值,那对于偶数长度的链表,中间节点会偏后,拆分时可能会导致某个子链表丢失节点。
最后验证一下
把修正后的merge和middleElement函数替换进去,再测试排序逻辑,应该就能解决丢失首节点的问题啦!
内容的提问来源于stack exchange,提问作者Tuấn Anh Đào
相关产品推荐
相关产品推荐

