Sort a linked list in O(n log n) time using constant space complexity.
思路:把链表截成前后两段,对两段链表分别排序,最后再进行合并。
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
fast = slow.next;//fast成为链表的后半段
slow.next = null;//head成为链表的前半段
fast = sortList(fast);
head = sortList(head);
/**前后半段链表排序后,再进行合并,等于合并两个有序的链表*/
return merge(fast, head);
}
private ListNode merge(ListNode fast, ListNode head) {
ListNode result = new ListNode(-1), cur = result;
while (fast != null && head != null) {
if (fast.val < head.val) {
cur.next = fast;
fast = fast.next;
} else {
cur.next = head;
head = head.next;
}
cur = cur.next;
}
cur.next = fast == null ? head : fast;
return result.next;
}
合并两个有序链表的方法,也可以采用递归,具体实现如下:
private ListNode merge2(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
if (l1.val<=l2.val) {
l1.next= merge(l1.next,l2);
return l1;
}else {
l2.next=merge(l1,l2.next);
return l2;
}
}
对于链表排序,为什么归并优于快排,请看这里:Why is mergesort better for linked lists?