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;
	}
};

  

posted @ 2014-10-06 15:59  zombies  阅读(168)  评论(0编辑  收藏  举报