/** * Sort a linked list in O(n log n) time using constant space complexity. * * Tags: Linkedlist, Sort */ class SortList { public static void main(String[] args) { } /** * Get list length and do merge sort */ public ListNode sortList(ListNode head) { if (head == null || head.next == null) return head; ListNode tail = head; int len = 0; while (tail != null) { tail = tail.next; len++; } ListNode dummy = new ListNode(Integer.MIN_VALUE); dummy.next = head; head = mergeSort(dummy, head, len); return head; } /** * Cut into two halves * Sort left half first, move to right half's pre head and sort right * Merge two halves * Insert node in latter part if its smaller than current node */ public ListNode mergeSort(ListNode preHead, ListNode head, int len) { if (head == null || len <= 1) return head; int left = len / 2; int right = len - left; // sort left head = mergeSort(preHead, head, left); // sort right ListNode pMid = head; for (int i = 0; i < left - 1; i++) pMid = pMid.next; mergeSort(pMid, pMid.next, right); // merge ListNode pre1 = preHead; ListNode p1 = head; ListNode pre2 = pMid; ListNode p2 = pMid.next; if (p1.val > p2.val) head = p2; // switch head while (left > 0 && right > 0) { // merge second half to first half if (p1.val > p2.val) { pre2.next = p2.next; // insert p2 before p1 p2.next = p1; pre1.next = p2; // set to next pre1 = p2; p2 = pre2.next; right--; } else { // set to next pre1 = p1; p1 = p1.next; left--; } } return head; } class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; } } }