25.合并两个有序链表

2019-07-31  本文已影响0人  HamletSunS

思路:
基础题目,设置3个指针,2个分别指向2个有序链表,第3个用来拼接最后的合并链表(保存好要返回的头结点)。没什么好说的。
应用:
链表排序。对链表进行归并排序的时候,本题的算法相当于是归并排序中的merge操作。

拓展:链表排序
难点:

  1. 找链表中点
  2. merge操作的实现

逐个攻破:

TreeNode* merge(TreeNode *a,TreeNode *b){
//定义终止条件  
if(a==nullptr)
      return b;
if(b==nullptr)
      return a;
//开始递归过程
if(a->val<=b->val){
a->next=merge(a->next,b);
reutrn a;
}  
else{
b->next=merge(a,b->next);
return b;
}
}

循环实现merge

TreeNode *merge(TreeNode *a,TreeNode *b){
//judge illegal
if(a==nullptr)
return b;
if(b==nullptr)
return a;
TreeNode *c,*head;
if(a->val<=b->val){
 c=a;
a=a->next;
}
else{
c=b;
b=b->next;
}
head=c;
while(a&&b){
if(a->val<=b->val){
c->next=a;
a=a->next;
}
else{
c->next=b;
b=b->next;
}
c=c->next;
}
c->next=nullptr;
if(a!=nullptr)
c->next=a;
if(b!=nullptr)
c->next=b;
return head;
}

可见循环的代码比递归的代码要冗余许多,但是执行效率会更高,两种实现方式都不是很难,其实就是简单的逻辑判断,判断一下是a链表的值还是b链表的值大,分别处理即可

逻辑代码(不推荐封装成函数,因为我们需要split和slow两个节点,封装成函数如果用cpp的话还是挺麻烦的)
find the middle point in a linkedList

vector<TreeNode *>findMP(TreeNode *head){
//judge illeagal
if(head==nullptr)
return nullptr;
TreeNode *slow=head,*fast=head,*split=head;
while(fast&&fast->next){
fast=fast->next->next;
split=slow;//mark the slow->prior
slow=slow->next;
}
return {split,slow} //[head,split],[slow,nullptr]
}

整体实现:  
目前我们已经实现了找到链表中点和merge操作,那么我们就可以用归并排序进行链表排序了。  
```cpp
TreeNode *sortList(TreeNode *head){
 //judge illeagal
if(head==nullptr||head->next==nullptr)
return head;
//find the middle point  

vector<TreeNode> split=findMP(head);
split[0]->next=nullptr;
head=sortList(head);
split[1]=sortList(split[1]);
merge(split[1]);

}

循环实现:(待补充)

上一篇下一篇

猜你喜欢

热点阅读