对链表进行归并排序
原题目链接 排序链表
本题目要求时间复杂度为O(n
logn
)因此不难想到使用归并排序,而对与链表的归并排序来说,比较核心的算法就是进行断链和重组
采用的算法如下:
//断链表
ListNode *disconnent(ListNode *p,int num){
for(int i=0;i<num-1 && p;i++){
p=p->next;
}
ListNode *res=nullptr;
if(p){
res=p->next;
p->next=nullptr;
}
return res;
}
//归并链表
ListNode *Merge(ListNode *p,ListNode *q){
ListNode *_head=new ListNode;
ListNode *cur=_head;
while(p && q){
if(p->val<=q->val){
cur->next=p;
p=p->next;
}
else{
cur->next=q;
q=q->next;
}
cur=cur->next;
}
if(p) cur->next=p;
else cur->next=q;
return _head->next;
}
整个题目算法如下:
class Solution {
public:
ListNode* sortList(ListNode* head) {
ListNode *_head=new ListNode;
_head->next=head;
int count=length(head);
ListNode *pre,*cur1,*cur2,*next;
for(int i=1;i<count;i*=2){
pre=_head;
cur1=pre->next;
next=cur1;
while(next){
cur2=disconnent(cur1,i);
next=disconnent(cur2,i);
pre->next=Merge(cur1,cur2);
pre=find_end(pre);
cur1=next;
}
}
return _head->next;
}
//获取链表的长度
int length(ListNode *head){
int count=0;
while(head){
count++;
head=head->next;
}
return count;
}
//断链表
ListNode *disconnent(ListNode *p,int num){
for(int i=0;i<num-1 && p;i++){
p=p->next;
}
ListNode *res=nullptr;
if(p){
res=p->next;
p->next=nullptr;
}
return res;
}
//归并链表
ListNode *Merge(ListNode *p,ListNode *q){
ListNode *_head=new ListNode;
ListNode *cur=_head;
while(p && q){
if(p->val<=q->val){
cur->next=p;
p=p->next;
}
else{
cur->next=q;
q=q->next;
}
cur=cur->next;
}
if(p) cur->next=p;
else cur->next=q;
return _head->next;
}
//查找当前最后节点
ListNode *find_end(ListNode *p){
while(p->next){
p=p->next;
}
return p;
}
//测试打印输出
void print(ListNode *head){
while(head){
cout<<head->val<<" ";
head=head->next;
}
cout<<endl;
}
};