Sort a linked list in O(n log n) time using constant space complexity.
链表排序,O(n log n) time就考虑快排,归并排序,堆排,三者的空间复杂度分别为O(1), O(N),O(N),其实在链表里面的归并排序空间只要O(1)。
归并排序就是先切分为一半一半,一直切到只有一个节点,在一步步merge,用递归做:
public class Solution {
public ListNode sortList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode mid = getMid(head);
ListNode part1 = sortList(head);
ListNode part2 = sortList(mid);
ListNode rst = merge(part1, part2);
return rst;
}
private ListNode merge(ListNode p1, ListNode p2) {
ListNode dummy = new ListNode(0), tmp = dummy;
while(p1 != null && p2 != null) {
if(p1.val > p2.val) {
tmp.next = p2;
p2 = p2.next;
} else {
tmp.next = p1;
p1 = p1.next;
}
tmp = tmp.next;
}
if(p1 != null) tmp.next = p1;
if(p2 != null) tmp.next = p2;
return dummy.next;
}
public ListNode getMid(ListNode head) {
ListNode fast = head, slow = head;
while(fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
ListNode tmp = slow.next;
slow.next = null;
return tmp;
}
}
用快排也不是不可以,不过paritition要换一种方式,详见
http://www.cnblogs.com/TenosDoIt/p/3666585.html
http://www.cnblogs.com/TenosDoIt/p/3665038.html
Sort a linked list using insertion sort.
A graphical example of insertion sort. The partial sorted list (black) initially contains only the first element in the list.
With each iteration one element (red) is removed from the input data and inserted in-place into the sorted list
Algorithm of Insertion Sort:
- Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list.
- At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there.
- It repeats until no input elements remain.
插入排序是从后往前找合适的插入位置,如果要在链表上从后往前的话,只能让指针反向指
也就是大的数在链表的前面,指针指向左边
public ListNode insertionSortList(ListNode head) {
if( head == null ){
return head;
}
ListNode helper = new ListNode(0); //new starter of the sorted list
ListNode cur = head; //the node will be inserted
ListNode pre = helper; //insert node between pre and pre.next
ListNode next = null; //the next node will be inserted
//not the end of input list
while( cur != null ){
next = cur.next;
//find the right place to insert
while( pre.next != null && pre.next.val < cur.val ){
pre = pre.next;
}
//insert between pre and pre.next
cur.next = pre.next;
pre.next = cur;
pre = helper;
cur = next;
}
return helper.next;
}