Sort List 148
题目描述:
将一个链表排序
时间要求nlogn
空间要求常数时间
题目分析:
对于时间要求O(nlogn)
简单排序肯定不行了,对于满足时间要求的排序,堆排序 快速排序 归并排序 都是可以的
不过,堆排序要在链表中跳转比较大
对于快速排序,最坏情况下复杂度 O(n*n)
代码:
快排,TLE
1 void qsort(ListNode *first,ListNode *end,int len){ 2 if(len<=1)return ; 3 int t=(len-1)>>1; 4 5 ListNode *p=first; 6 for(int i=0;i<t;i++) 7 p=p->next; 8 9 swap(first->val,p->val); 10 11 ListNode *split=first; 12 for(p=first->next;p;p=p->next){ 13 if(first->val > p->val) { 14 split=split->next; 15 swap(split->val,p->val); 16 } 17 if(p==end)break; 18 } 19 swap(first->val,split->val); 20 21 if(split==first) 22 qsort(split->next,end,len-1); 23 else { 24 int cnt=1; 25 for(p=first;p->next!=split;p=p->next)cnt++; 26 qsort(first,p,cnt); 27 if(split!=end)qsort(split->next,end,len-cnt-1); 28 } 29 } 30 ListNode *sortList(ListNode *head){ 31 if(!head)return NULL; 32 33 ListNode *p=head; 34 int cnt=1; 35 for(;p->next;p=p->next)cnt++; 36 37 qsort(head,p,cnt); 38 return head; 39 }
归并排序:
1 ListNode *sortCore(ListNode *head){ 2 if(!head)return NULL; 3 if(head->next==NULL)return head; 4 5 int len=0;///将head分成尽量等长的两部分 6 ListNode *p=head; 7 while(p){ 8 len++; 9 p=p->next; 10 } 11 int mid=(len-1)>>1; 12 p=head; 13 for(int i=0;i<mid;i++)p=p->next; 14 ListNode *pb=p->next; 15 ListNode *pa=head; 16 p->next=NULL; 17 18 ///分治,计算部分 19 pa=sortCore(pa); 20 pb=sortCore(pb); 21 22 ///合并 23 ListNode ret(-1);///添加一个结点,便于操作 24 ret.next=NULL; 25 p=&ret; 26 while(pa && pb){ 27 if(pa->val < pb->val){ 28 p->next=pa; 29 pa=pa->next; 30 p=p->next; 31 } 32 else { 33 p->next=pb; 34 pb=pb->next; 35 p=p->next; 36 } 37 } 38 39 if(pa)p->next=pa; 40 if(pb)p->next=pb; 41 return ret.next; 42 } 43 44 ListNode *sortList(ListNode *head){ 45 return sortCore(head); 46 }