https://oj.leetcode.com/problems/sort-list/
實現至關麻煩的一道題。主要思想是從中間分開,而後就地的歸併排序兩段子鏈表。函數
比較麻煩的地方有三處:指針
1)注意子鏈表排序後,首尾都發生了變化,因此在排序後須要返回新的首尾。code
2) Merge函數內部也須要調整外面首尾的指針,並返回新的首尾指針。blog
3)Merge函數的兩個邊界狀況是隻有兩個結點。排序
總之這道題想在短期內寫對很是困難。能一次寫出bug-free更是困難。leetcode
/** * 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; } };