本文最后更新于 2025年5月20日 14:22
题目背景
给你链表的头结点 head
,请将其按 升序 排列并返回 排序后的链表 。
实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| class Solution { private: ListNode* findMiddle(ListNode* head) { ListNode* slow = head; ListNode* fast = head; ListNode* pre = head; while (fast != nullptr && fast->next != nullptr) { pre = slow; slow = slow->next; fast = fast->next->next; } pre->next = nullptr; return slow; }
ListNode* merge(ListNode* head1, ListNode* head2) { ListNode dummy; ListNode* cur = &dummy; while (head1 != nullptr && head2 != nullptr) { if (head1->val < head2->val) { cur->next = head1; head1 = head1->next; } else { cur->next = head2; head2 = head2->next; } cur = cur->next; } cur->next = head1 == nullptr ? head2 : head1; return dummy.next; } public: ListNode* sortList(ListNode* head) { if (head == nullptr || head->next == nullptr) { return head; } ListNode* mid = findMiddle(head); ListNode* head1 = sortList(head); ListNode* head2 = sortList(mid);
return merge(head1, head2); } };
|
复盘
对链表的排序可以拆分成以下的步骤:寻找链表中间节点、拆分链表、分别对链表进行排序、合并链表。整体实现思路不是很困难,但是 coding 过程中有一些点还是需要注意的:
- 寻找链表中间结点
- 需要定义
pre
指针用来存储 slow
更新之前的值, pre
指针是为了最后拆分链表时使用。
- 循环条件为
while (fast && fast->next)
,并不涉及 slow
指针。(因为 fast
走过的地方, slow
未来肯定也能走)
- 合并有序链表
- 定义辅助变量
dummy
和 cur
,在更新时更新的是 cur->next
而不是 cur
。
- 最后是将还未遍历到的部分拼接到
cur->next
上而不是 cur
上。