LeetCode-Sort List-链表排序-归并排序+链表调整
https://oj.leetcode.com/problems/sort-list/
实现相当麻烦的一道题。主要思想是从中间分开,然后就地的归并排序两段子链表。
比较麻烦的地方有三处:
1)注意子链表排序后,首尾都发生了变化,所以在排序后需要返回新的首尾。
2) Merge函数内部也需要调整外面首尾的指针,并返回新的首尾指针。
3)Merge函数的两个边界情况是只有两个结点。
总之这道题想在短时间内写对非常困难。能一次写出bug-free更是困难。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
typedef pair<ListNode *,ListNode *> scpair;
class Solution {
public:
int n,m;
scpair Merge(ListNode *hh,ListNode *ee,ListNode *h1,ListNode *t1){
ListNode *p=h1;
ListNode *lp=hh;
ListNode *q=t1->next;
scpair res=scpair(h1,t1);
if (h1==t1){
while(q!=ee){
if (p->val<=q->val) break;
if (lp!=NULL) lp->next=q;
p->next=q->next;
q->next=p;
if (lp==hh) res.first=q;
lp=q;
q=p->next;
}
p=res.first;
while(p!=ee){
res.second=p;
p=p->next;
}
return res;
}
res.first=h1;
while(q!=ee && p!=ee && p!=q){
if (p->val<q->val){
lp=p;
p=p->next;
}
else{
t1->next=q->next;
q->next=p;
if (lp!=NULL) lp->next=q;
if (lp==hh) res.first=q;
lp=q;
q=t1->next;
}
}
p=res.first;
while(p!=ee){
res.second=p;
p=p->next;
}
return res;
}
scpair MSort(ListNode *hh,ListNode *ee,ListNode *h,ListNode *t,int num){
if (h==t){return scpair(h,t);}
ListNode *h1=h;
ListNode *t1=h;
int count=1;
while(count<num/2){
t1=t1->next;
count++;
}
ListNode *h2=t1->next;
ListNode *t2=t;
scpair l=MSort(hh,h2,h1,t1,count);
scpair r=MSort(l.second,ee,h2,t2,num-count);
scpair res=Merge(hh,ee,l.first,l.second);
return res;
}
ListNode *sortList(ListNode *head) {
if (head==NULL){return NULL;}
ListNode *p=head;
ListNode *q=p;
n=1;
while (p->next!=NULL){
q=p;
p=p->next;
n++;
}
if (p==q){return head;}
scpair res=MSort(NULL,NULL,head,p,n);
return res.first;
}
};
浙公网安备 33010602011771号