在刷leetcode时,遇到一道列表排序问题,要求使用nlogn的时间效率解决,这就需要使用合并排序了。
将链表递归拆分成两段(双指针),再将拆分出来的列表两两有序合并起来,形成有序的链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) { //从中间拆分链表
ListNode* t=new ListNode(0);
t->next=head;
ListNode* slow=t;
ListNode* fast=t;
if(head==NULL || head->next==NULL)
return head;
while(fast && fast->next){
slow=slow->next;
fast=fast->next->next;
}
ListNode *l2=slow->next;
slow->next=NULL;
return merge(sortList(head),sortList(l2));
}
ListNode* merge(ListNode* l1,ListNode* l2){ //合并两链表串
ListNode* dummy=new ListNode(0);
ListNode* pre=dummy;
while(l1 && l2){
int a=l1->val;
int b=l2->val;
if(a<b){
ListNode* node=new ListNode(a);
node->next=pre->next;
pre->next = node;
pre=node;
ListNode * tmp=l1;
l1=l1->next;
delete(tmp); //一定要删除原节点 避免内存耗尽
}else{
ListNode* node=new ListNode(b);
node->next=pre->next;
pre->next = node;
pre=node;
ListNode * tmp=l2;
l2=l2->next;
delete(tmp);
}
}
if(l1)
pre->next=l1;
if(l2)
pre->next=l2;
return dummy->next;
}
};