合并两个有序链表,是链表的经典题之一 ,这里给出一种经典解法
想法一
创建head和tail两个指针,从头比较两个链表,取小的尾插,注意一开始指针的初始化,接着就是不断利用tail指针,链接比较之中较小的节点,然后tail指针和list指针都往后移动一个节点
这是尾插list1的部分,小伙伴可以仿照着写尾插list2的部分哦~
当循环结束时,总有一个链表不为空,那就直接将其链接在tail所在节点的后面
最后,要注意如果有空链表的存在 ,即跳过循环时tail为NULL,则直接让head为另一个链表的头部,返回
同样,这是list1不为空时的判断, 小伙伴可以仿照着写尾插list2的部分哦~
完整代码如下:
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
struct ListNode* head = NULL;
struct ListNode* tail = NULL;
while (list1 && list2)
{
if (list1->val < list2->val)
{
if (tail)
{
tail->next = list1;
tail = tail->next;
}
else
{
head = tail = list1;
}
list1 = list1->next;
}
else
{
if (tail)
{
tail->next = list2;
tail = tail->next;
}
else
{
head = tail = list2;
}
list2 = list2->next;
}
}
if (list1)
{
if (!tail)
{
head = list1;
}
else
{
tail->next = list1;
}
}
if (list2)
{
if (!tail)
{
head = list2;
}
else
{
tail->next = list2;
}
}
return head;
}
想法二
这里可以创建哨兵位,可以避免head和tail指针初始化的讨论和判断
看看,判断流程简化了不少吧~
不过最后不能直接返回head,因为那是哨兵位,所以我们要删除哨兵位,将head指向头节点返回
完整代码如下:
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
if (!list1)
{
return list2;
}
if (!list2)
{
return list1;
}
struct ListNode* head = NULL;
struct ListNode* tail = NULL;
//哨兵位
head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
while (list1 && list2)
{
if (list1->val < list2->val)
{
tail->next = list1;
tail = tail->next;
list1 = list1->next;
}
else
{
tail->next = list2;
tail = tail->next;
list2 = list2->next;
}
}
if (list1)
{
tail->next = list1;
}
if (list2)
{
tail->next = list2;
}
struct ListNode* del = head;
head = head->next;
free(del);
return head;
}