链表的排序,非常适合利用归并排序来实现,采用递归的方式比较容易理解。
寻找一个链表的中间节点,采用快慢指针的方式。
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getMiddleNode (ListNode h1){
if(h1 == null || h1.next == null) return h1;
ListNode dummy = new ListNode(0);
ListNode fast = dummy;
ListNode low = dummy;
dummy.next = h1;
while(low != null && fast!=null && fast.next != null){
low = low.next;
fast = fast.next;
if(fast ==null)break;
fast = fast.next;
}
ListNode middle = low.next;
low.next = null;
return middle;
}
public ListNode mergeTwoSortedList(ListNode h1, ListNode h2){
if(h1 == null) return h2;
if(h2 == null )return h1;
ListNode dummy = new ListNode(-1);
ListNode p = dummy;
while(h1 != null && h2 != null){
if(h1.val <= h2.val){
p.next = h1;
h1 = h1.next;
p = p.next;
}
else{
p.next = h2;
h2 = h2.next;
p = p.next;
}
if(h1 == null){
while(h2 != null){
p.next = h2;
h2 = h2.next;
p = p.next;
}
}
if(h2 == null){
while(h1 != null){
p.next = h1;
h1 = h1.next;
p = p.next;
}
}
}
return dummy.next;
}
public ListNode sortList(ListNode head) {
if(head == null || head.next == null) return head;
ListNode mid = getMiddleNode(head);
return mergeTwoSortedList(sortList(head), sortList(mid));
}
}