快慢指针拆半,递归归并排序,O(n log n) 时间 O(log n) 递归空间。
OJ: leetcodecn
题目 ID: sort-list
难度:普及+/提高
标签:链表排序归并排序cpppython
日期: 2026-07-28 22:05
题意
对链表排序,要求 O(n log n) 时间、O(1) 额外空间。
思路
数组排序 O(n) 辅助空间。归并排序满足要求:快慢指针找中点分割,递归排序两半,合并两个有序链表。递归深度 O(log n)。
代码
cpp
/**
* Author by Rainboy
*/
// main.cpp:快慢指针拆半,递归归并 O(n log n) O(log n)。
#include <bits/stdc++.h>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
ListNode *sortList(ListNode *head) {
if (!head || !head->next)
return head;
auto slow = head, fast = head->next;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
auto mid = slow->next;
slow->next = nullptr;
auto l = sortList(head), r = sortList(mid);
ListNode dummy(0), *cur = &dummy;
while (l && r) {
if (l->val < r->val) {
cur->next = l;
l = l->next;
} else {
cur->next = r;
r = r->next;
}
cur = cur->next;
}
cur->next = l ? l : r;
return dummy.next;
}
};
ListNode *build(istream &in, int n) {
if (!n)
return nullptr;
auto head = new ListNode(0), cur = head;
for (int i = 0, v; i < n; i++) {
in >> v;
cur->next = new ListNode(v);
cur = cur->next;
}
return head->next;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
auto head = build(cin, n);
head = Solution().sortList(head);
for (auto p = head; p; p = p->next)
cout << p->val << ' ';
return 0;
}python
#!/usr/bin/env python3
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def sortList(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
slow, fast = head, head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
mid = slow.next
slow.next = None
l = self.sortList(head)
r = self.sortList(mid)
dummy = cur = ListNode(0)
while l and r:
if l.val < r.val:
cur.next = l
l = l.next
else:
cur.next = r
r = r.next
cur = cur.next
cur.next = l or r
return dummy.next
def build(arr):
dummy = cur = ListNode(0)
for v in arr:
cur.next = ListNode(v)
cur = cur.next
return dummy.next
def main() -> None:
n = int(input())
a = list(map(int, input().split()))
head = build(a)
head = Solution().sortList(head)
while head:
print(head.val, end=" ")
head = head.next
if __name__ == "__main__":
main()复杂度
- 时间复杂度:O(n log n)。
- 空间复杂度:O(log n) 递归栈。
总结
链表归并排序是"寻中-递归-合并"三步曲,核心是利用链表 O(1) 拆分和 O(n) 合并的特性。