LeetCode刷题(7)--合并两个有序链表(递归算法实现)

题目描述

将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例
输入: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;
}

合并两个有序链表的完整演示就到这里,这部分主要是使用递归算法,后面还会讲解其它算法的实现过程。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值