使用归并排序算法对链表进行排序,这种排序算法的时间复杂度为O(nlogn)。
归并排序:将两个或两个以上的有序数据序列合并成一个新的有序数据序列,它的基本思想是假设数组A有N个元素,那么可以看成数组A有N个有序的子序列组成,每个子序列的长度为1,然后在将两两合并,得到一个N/2个长度为2或1的有序子序列,再两两合并,如此重复,直到得到一个长度为N的有序序列为止。
public ListNode sortList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode left = head;
ListNode right = getMiddle(head); //调用取中算法,同时会把left切断
if(left.next != null){ //取中算法中,left有可能比right长,所以这里必须是left的长度为1
left = sortList(left); //对left进行递归
right = sortList(right); //对right进行递归
}
return merge(left, right); //合并,返回
}
public ListNode merge(ListNode left, ListNode right){ //合并
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while(left != null && right != null){
if(left.val <= right.val){
curr.next = left;
curr = curr.next;
left = left.next;
}
else{
curr.next = right;
curr = curr.next;
right = right.next;
}
}
if(left != null) //left不为空,而right已经为空
curr.next = left;
else if(right != null) //right不为空,而left已经为空
curr.next = right;
return dummy.next;
}
public ListNode getMiddle(ListNode head){ //寻找链表的中点,把原链表切断,并返回后半段链表
if(head == null || head.next == null)
return head;
ListNode middle = null;
ListNode fast = head;
ListNode slow = head;
while(fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
middle = slow.next;
slow.next = null;
return middle;
}