持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情。
大家好,我是芒果,一名非科班的在校大学生。对C/C++、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流
作者简介:
- CSDN C/C++领域新星创作者blog.csdn.net/chuxinchang…
- 掘金LV3用户 juejin.cn/user/138142…
- 阿里云社区专家博主,星级博主,技术博主 developer.aliyun.com/profile/exp…
- 华为云云享专家 bbs.huaweicloud.com/community/m…
题目要求
方法1:使用头指针
思路:
-
假设两个链表分别为l1和l2,l1和l2都是有序的
-
因为要 排成升序,把l1和l2指向的结点的较小的尾插到新链表
-
由于是尾插到新链表:为了方便,可以定义两个指针,一个新链表的头,一个指向新链表的尾
-
这里使用的是头指针的写法:
- 首先:我们应该提前把l1和l2中的较小结点,尾插下来当头结点,更新尾指针
- 然后l1和l2继续向后比较,找到把小的尾插下去,然后更新尾指针
-
因为总有一个链表先遍历完(走到空),把另一个没有遍历完的链表直接链接到尾指针后面即可(因为:l1和l2都是有序的)
-
然后返回新链表的头指针即可
注意: 如果其中一个链表一开始就是空,就返回另一个链表
图解
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
{
//l1为空链表就返回l2
if(l1 == NULL)
{
return l2;
}
//l2为空链表就返回l1
if(l2 == NULL)
{
return l1;
}
//使用头指针
//定义头尾指针
struct ListNode* head = NULL,*tail = NULL;
//先从l1和l2选一个小的下来作为头,排升序
if(l1->val < l2->val)
{
//头尾指针都要更新
head = l1;
tail = l1;
//l1更小,l1继续往后走
l1 = l1->next;
}
else
{
//头尾指针都要更新
head = l2;
tail = l2;
//l1小,l2继续往后走
l2 = l2->next;
}
//遍历比较 -如果有一个链表走完(空指针)就跳出循环
while(l1 && l2)
{
if(l1->val > l2->val )
{
tail ->next = l2;//尾指针链接小的结点
tail = l2;//更新尾结点
l2 = l2->next;//小的结点的链表向后走
}
else{
tail ->next = l1;//尾指针链接小的结点
tail = l1;//更新尾结点
l1 = l1->next;//小的结点的链表向后走
}
}
//有一个结束了-未知是哪个先结束->两个都判断
//下面的两个if判断,只进入一个
if(l1)
{
tail->next = l1;//尾指针链接没有比较完的链表
}
else{
tail->next = l2;//尾指针链接没有比较完的链表
}
return head;//返回新链表的头指针
}
方法2:使用哨兵位
思路:和上面方法1基本一致
-
假设两个链表分别为l1和l2,l1和l2都是有序的
-
使用了哨兵位,所以不需要先选一个下来当头结点
-
由于是尾插到新链表:为了方便,可以定义两个指针,一个新链表的头,一个指向新链表的尾
-
这里使用的是哨兵位的写法:
- 注意:哨兵位的next才是第一个结点,哨兵位不存储有效数据
- l1和l2从头开始向后比较,找到把小的尾插下去,然后更新尾指针
-
因为总有一个链表先遍历完(走到空),把另一个没有遍历完的链表直接链接到尾指针后面即可(因为:l1和l2都是有序的)
-
然后返回新链表的头指针即可,返回的是head->next才是第一个结点
注意:最后哨兵位结点要释放掉
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(l1 == NULL)
{
return l2;
}
if(l2 == NULL)
{
return l1;
}
//使用哨兵位
struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* tail = head;
//遍历比较 -如果有一个走完就跳出循环
while(l1 && l2)
{
if(l1->val > l2->val )
{
tail->next =l2 ;
tail = tail->next;
l2 = l2->next;
}
else{
tail->next = l1;
tail = tail->next;
l1 = l1->next;
}
}
//有一个结束了
if(l1)
{
tail->next = l1;
}
else{
tail->next = l2;
}
//保存第一个结点,防止释放掉哨兵位之后找不到
struct ListNode* tmp = head->next;
//哨兵位结点要释放掉,然后置空
free(head);
head = NULL;
return tmp;
}
\