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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
public static ListNode sortList(ListNode head) {
// 计算链表长度
int n = 0;
ListNode cur = head;
while (cur != null) {
n++;
cur = cur.next;
}
ListNode l1, r1, l2, r2, next, lastTeamEnd;
// 步长从1开始,每次翻倍(1→2→4→...)
for (int step = 1; step < n; step <<= 1) {
l1 = head;
r1 = findEnd(l1, step);
l2 = r1.next;
r2 = findEnd(l2, step);
next = r2.next;
// 切断链表,确保l1-r1和l2-r2是独立的子链表
r1.next = null;
r2.next = null;
// 合并两个子链表
merge(l1, r1, l2, r2);
// 更新头节点(第一次合并后,头可能变)
head = start;
lastTeamEnd = end;
// 处理剩余的子链表
while (next != null) {
l1 = next;
r1 = findEnd(l1, step);
l2 = r1.next;
// 如果只剩一个子链表,直接连接
if (l2 == null) {
lastTeamEnd.next = l1;
break;
}
r2 = findEnd(l2, step);
next = r2.next;
r1.next = null;
r2.next = null;
merge(l1, r1, l2, r2);
// 连接上一组的尾和当前组的头
lastTeamEnd.next = start;
lastTeamEnd = end;
}
}
return head;
}
public static ListNode findEnd(ListNode s,int k){
while(s.next!=null&&--k!=0){
s=s.next;
}
return s;
}
public static ListNode start; // 合并后的头
public static ListNode end; // 合并后的尾
public static void merge(ListNode l1, ListNode r1, ListNode l2, ListNode r2) {
ListNode pre;
// 确定合并后的头节点
if (l1.val <= l2.val) {
start = l1;
pre = l1;
l1 = l1.next;
} else {
start = l2;
pre = l2;
l2 = l2.next;
}
// 循环比较,合并节点
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
pre.next = l1;
pre = l1;
l1 = l1.next;
} else {
pre.next = l2;
pre = l2;
l2 = l2.next;
}
}
// 处理剩余节点,确定合并后的尾
if (l1 != null) {
pre.next = l1;
end = r1; // l1有剩余,尾是r1
} else {
pre.next = l2;
end = r2; // l2有剩余,尾是r2
}
}
|