题目描述
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
输入:l1 = [], l2 = []
输出:[]
输入:l1 = [], l2 = [0]
输出:[0]
解题思路
//定义链表结构体
struct ListNode
{
int data;//定义节点位置的值
ListNode* pNext;//定义节点的下一节点
};
//合并有序单链表
ListNode* MergeTList(ListNode* l1,ListNode* l2)
{
if(l1==NULL)
{
return l2;
}
if(l2==NULL)
{
return l1;
}
if(l1->data<l2->data)
{
l1->pNext=MergeTList(l1->pNext,l2);
return l1;
}
else
{
l2->pNext=MergeTList(l1,l2->pNext);
return l2;
}
}
//定义打印单链表
void print(ListNode* head)
{
while(head!=NULL){
cout<<head->data<<endl;
head=head->pNext;
}
}
//定义第一个单链表
ListNode* CreatList1(ListNode* head)
{
//头结点赋值为1
head->data=1;
//定义头结点下一个节点并赋值
ListNode* node1=new ListNode();
node1->data=2;
head->pNext=node1;
//定义下一个节点并赋值
ListNode* node2=new ListNode();
node2->data=4;
node1->pNext=node2;
return head;
}
//定义第二个单链表
ListNode* CreatList2(ListNode* head)
{
//头结点赋值为1
head->data=1;
//定义头结点下一个节点并赋值
ListNode* node1=new ListNode();
node1->data=1;
head->pNext=node1;
//定义下一个节点并赋值
ListNode* node2=new ListNode();
node2->data=4;
node1->pNext=node2;
return head;
}
int main()
{
//定义第一个单链表,确定头结点就能表示整条链表
ListNode* head1=new ListNode();
//定义第二个单链表,确定头结点就能表示整条链表
ListNode* head2=new ListNode();
//定义合并的单链表,确定头结点就能表示整条链表
ListNode* headAll=new ListNode();
cout<<"第一个链表"<<endl;
//获取第一个单链表
head1=CreatList1(head1);
//打印第一个单链表
print(head1);
cout<<"第二个链表"<<endl;
//获取第二个单链表
head2=CreatList2(head2);
//打印第二个单链表
print(head2);
cout<<"合并链表"<<endl;
//获取合并的单链表
headAll=MergeTList(head1,head2);
//打印合并的单链表
print(headAll);
return 0;
}
结果:
具体分析一下每个函数的作用:
1.定义链表结构体
这是我们创建链表的第一步,确定链表的节点和对应节点的值,我们就可以确定整条链表,因为确定了某个节点,其它节点都是由此节点生成的。
struct ListNode
{
int data;//定义节点位置的值
ListNode* pNext;//定义节点的下一节点
};
2.使用递归来合并有序链表
这是此部分的核心,具体的流程为:
1).先判断链表1是否为空,如果为空,那么合并的链表就是链表2,返回链表2的节点。
2).判断链表2是否为空,如果为空,那么合并的链表就是链表1,返回链表1的节点。
3).如果链表1的首节点值小于链表2的首节点值,那么将链表1的第一个值作为合并的链表的头结点,且下一个节点是将链表1的下一个节点继续和链表2的第一个节点比较。
4).如果链表2的首节点值小于链表1的首节点值,那么将链表2的第一个值作为合并的链表的头结点,且下一个节点是将链表1的首节点继续和链表2的下一个节点比较。
5).直到其中一个链表为空,跳出递归,返回另一个链表的头结点。
第一步和第二步是递归的出口,使用递归,必须要有出口条件。
ListNode* MergeTList(ListNode* l1,ListNode* l2)
{
if(l1==NULL)
{
return l2;
}
if(l2==NULL)
{
return l1;
}
if(l1->data<l2->data)
{
l1->pNext=MergeTList(l1->pNext,l2);
return l1;
}
else
{
l2->pNext=MergeTList(l1,l2->pNext);
return l2;
}
}
3.打印链表
打印链表主要是要找到链表的头结点,当头结点不为空时,输出头结点的值,头结点向后移动一位,继续判断,直到头结点全部打完,则链表打印完毕。
void print(ListNode* head)
{
while(head!=NULL){
cout<<head->data<<endl;
head=head->pNext;
}
}
4.创建链表
创建链表还是从头结点开始,往后延伸,确定头结点的值,定义头结点的下一结点以及对应的值,以次类推。
ListNode* CreatList1(ListNode* head)
{
//头结点赋值为1
head->data=1;
//定义头结点下一个节点并赋值
ListNode* node1=new ListNode();
node1->data=2;
head->pNext=node1;
//定义下一个节点并赋值
ListNode* node2=new ListNode();
node2->data=4;
node1->pNext=node2;
return head;
}