复习了一下归并排序,通过快指针和慢指针的方法找到中间结点。但要注意,由于归并排序的思想是从中间将数列分为两段,那么在采用链表时,需要找到中间位置的前一个结点。这个一定要注意,愣是改了一上午才找到stack outflow的原因。合并两个有序的链表我选择的是递归算法,很简单,在这里就不作解释了。
<pre name="code" class="cpp">class Solution {
public:
//归并排序
ListNode *Merge(ListNode *l1,ListNode *l2)
{
ListNode *l=NULL;
if(!l1)
return l2;
else if(!l2)
return l1;
if(l1->val<l2->val)
{
l=l1;
l->next=Merge(l1->next,l2);
}
else{
l=l2;
l->next=Merge(l1,l2->next);
}
//l->next=NULL;
return l;
}
ListNode *sortList(ListNode *head) {
if(!head||!head->next)//如果为空或只有一个结点,直接返回
return head;
else{//如果有一个以上结点,采用中间值分解成两个链表的方法递归调用
//ListNode *p;
ListNode *mid,*p,*q,*pre;//pre指向中间节点的前一个节点。p为慢指针,q为快指针,q走到结尾结束
//if(head!=rail){
p=head;
q=head;
pre=head;
mid=NULL;
//q=q->next;
while(q&&q->next)
{
if(p!=head)
pre=pre->next;
p=p->next;
q=q->next->next;
}
mid=p;
//q=mid->next;
pre->next=NULL;
head=sortList(head);
mid=sortList(mid);
return Merge(head,mid);
// }
}
}
};