以O(n log n)的复杂度对链表排序,首先想到的就是归并。
非容器链表的归并和数组的归并还是有不同,链表可以不用创建临时储存空间,直接创建个引用然后把两条链表的节点按顺序穿起来即可。
讲一个链表一分为二的方法是用两个指针一个快一个慢,这样快的到终点慢的差不多到中间了。
ListNode merge(ListNode l1, ListNode l2){
if(l1==null) return l2;
if(l2==null) return l1;
ListNode start;
if(l1.val<l2.val){
start = l1;
l1=l1.next;
}else{
start = l2;
l2=l2.next;
}
ListNode p=start;
while(l1!=null&&l2!=null){
if(l1.val<l2.val){
p.next=l1;
p=p.next;
l1=l1.next;
}else{
p.next=l2;
p=p.next;
l2=l2.next;
}
}
if(l1!=null){
p.next=l1;
}
if(l2!=null){
p.next=l2;
}
return start;
}
public ListNode sortList(ListNode head) {
if(head==null) return null;
if(head.next==null) return head;
ListNode head1 = head;
ListNode head2 = head;
while(head2.next!=null&&head2.next.next!=null){
head1=head1.next;
head2=head2.next.next;
}
head2=head1.next;
head1.next=null;
head1=head;
head1=sortList(head1);
head2=sortList(head2);
return merge(head1,head2);
}