C语言力扣第21题之合并两个有序链表。双指针法

博客围绕将两个升序链表合并为一个新升序链表展开,给出多个输入输出示例,介绍了通过设定哨兵节点和维护指针来合并链表的方法,最后博主表示自己的方法存在问题,寻求大佬指点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

示例 1:

输入:l1 = [1, 2, 4], l2 = [1, 3, 4]
输出:[1, 1, 2, 3, 4, 4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

两个链表的节点数目范围是[0, 50]
- 100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列

首先,我们设定一个哨兵节点 prehead ,这可以在最后让我们比较容易地返回合并后的链表。我们维护一个 prev 指针,我们需要做的是调整它的 next 指针。然后,我们重复以下过程,直到 l1 或者 l2 指向了 null :如果 l1 当前节点的值小于等于 l2 ,我们就把 l1 当前的节点接在 prev 节点的后面同时将 l1 指针往后移一位。否则,我们对 l2 做同样的操作。不管我们将哪一个元素接在了后面,我们都需要把 prev 向后移一位。

在循环终止的时候, l1 和 l2 至多有一个是非空的。由于输入的两个链表都是有序的,所以不管哪个链表是非空的,它包含的所有元素都比前面已经合并链表中的所有元素都要大。这意味着我们只需要简单地将非空链表接在合并链表的后面,并返回合并链表即可。

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
	struct ListNode *ret, *tmp; //创建一个哨兵结点(类似于射线的端点,只是不存值)和一个临时指针
	ret = malloc(sizeof(struct ListNode));//给哨兵结点分配空间,但他存的是  NULL
	tmp = ret;//先给临时指针赋初值(最开始指向哪里)
	while (list1 && list2) {//当连个链表中没有遍历完毕的,就继续循环遍历
		if (list2->val > list1->val) {//谁小谁在前,list1小 list1在前
			tmp->next = list1;//临时指针指向 list1 
			tmp = list1;//赋值
			list1 = list1->next;// list1 向后移1位
		}
		else//否则就反过来呗~ list2 小看 list2
		{
			tmp->next = list2;
			tmp = list2;
			list2 = list2->next;
		}
	}
	//下面的if else 语句承接第4行和第10行,剩下的直接拼接在后面就可以了
	//同时,这个也省下了“边界判断”(即:如果两个链表其中有一个是 空 怎么办?)。这里表示:直接接上不就好了
	if (list1)
		tmp->next = list1;
	else
		tmp->next = list2;
	return ret->next;//这里,ret是哨兵,里面存的是 NULL,返回咱们自己设的这个哨兵没意义,所以返回 next

}

下面这个方法存在问题,但本人并不知道错在哪,有没有大佬可以指点一下

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
	struct ListNode *head1 ;
	struct ListNode *head2 ;
	struct ListNode *head;
	head = (struct ListNode *)malloc(sizeof(struct ListNode));
	head1 = (struct ListNode *)malloc(sizeof(struct ListNode));
	head2 = (struct ListNode *)malloc(sizeof(struct ListNode));
	if (list1->val >= list2->val)
		head->next = list2;
	else
		head->next = list1;
	if (list1 == NULL)
		return list2;
	if (list2 == NULL)
		return list1;
	while (list1 != NULL && list2 != NULL)
	{
		head1->next = list1;
		head2->next = list2;
		if (list1->val >= list2->val)
		{
			head1->next = list2;
			list2 = list2->next;
			head2->next->next = list1;
		}
		else
		{
			list1 = list1->next;
		}
	}
	if (list1)
	{
		list1->next = list2;
	}
	return head->next;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D了一天bug忘了编译

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值