leetcode:#148. 排序链表
采用Java实现。
熟悉合并两个有序链表,断链操作,dummyHead
class Solution {
public ListNode sortList(ListNode head) {
ListNode dummyHead = new ListNode();
dummyHead.next = head;
int length = calculateListLength(dummyHead);
for (int size = 1; size < length; size = size * 2) {
ListNode current = dummyHead.next;
ListNode tail = dummyHead;
while (current != null) {
ListNode left = current;
ListNode right = cut(current, size);
current = cut(right, size); // 将 right 断链,用来 归并
tail.next = merge(left, right); //接链
while (tail.next != null) { // 将tail移到末尾,方便下次 接链
tail = tail.next;
}
}
}
return dummyHead.next;
}
private ListNode merge(ListNode left, ListNode right) {
if (left == null) {
return right;
}
if (right == null) {
return left;
}
ListNode mergedDummyHead = new ListNode();
ListNode mergedListTail = mergedDummyHead;
while (left != null && right != null) {
if (left.val <= right.val) {
mergedListTail.next = left;
mergedListTail = left;
left = left.next;
} else {
mergedListTail.next = right;
mergedListTail = right;
right = right.next;
}
}
mergedListTail.next = left != null ? left : right;
return mergedDummyHead.next;
}
private ListNode cut(ListNode current, int size) {
while (size > 1 && current != null) {
current = current.next;
size --;
}
if (current == null) {
return null;
}
ListNode right = current.next;
current.next = null; // 断链
return right;
}
private int calculateListLength(ListNode dummyHead) {
int length = 0;
ListNode p = dummyHead;
while (p.next != null) {
length ++;
p = p.next;
}
return length;
}
}