用NlgN的时间对链表进行排序,对空间没有要求。空间ON,在合并两个有序表的时候要用一个新的链表保存结果
这个复杂度有归并排序和快排,但是快排要求从两头扫描,链表做不到
归并排序:
两个两个一组排,之后再四个四个一组排,最后是两个有序表合并,递归
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* merge(ListNode* l1,ListNode* l2){ //一趟的排序,合并两个有序表,必须要用一个新的链表来保存!!
if(l1==NULL) return l2;
if(l2==NULL) return l1;
ListNode* p=l1;
ListNode* q=l2;
ListNode* head=NULL;
ListNode* tail=NULL;
if(p->val <= q->val){
head=p;
tail=p;
p=p->next;
tail->next=NULL;
}
else{
head=q;
tail=q;
q=q->next;
tail->next=NULL;
}
while(p&&q){
if(p->val <= q->val){
tail->next=p;
p=p->next;
tail=tail->next;
tail->next=NULL;
}
else{
tail->next=q;
q=q->next;
tail=tail->next;
tail->next=NULL;
}
}
if(p) tail->next=p;
else tail->next=q;
return head;
}
ListNode* sortList(ListNode* head) {
if(head==NULL||head->next==NULL) return head;
ListNode* fast=head;
ListNode* slow=head;
while(fast->next&&fast->next->next){ //找中点,注意这里的fast->next&&fast->next->next得到的slow是前半段的,如果用fast&&fast->next会RE
fast=fast->next->next;
slow=slow->next;
}
ListNode* mid=slow->next;
slow->next=NULL;
ListNode* l1=sortList(head); //这三行是递归的重点!!!
ListNode* l2=sortList(mid);
ListNode* ans=merge(l1,l2);
return ans;
}
};