题目链接:21.合并两个有序链表
题目描述:
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 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
均按 非递减顺序 排列
思路:可以参照之前的合并两个有序数组
ListNode* l1 = list1;
ListNode* l2 = list2;
ListNode *newHead,*newTail;
定义l1指向链表1,l2指向链表2,l1,l2在两个链表中遍历进行比较。
创建指向新链表首尾结点的指针newHead,newTail。
比较两个链表中结点值的大小,值小的结点尾插入新链表中,由于尾插需要判断当前链表是否为空,指向新链表头结点的指针需要改变,为了不让代码显得冗余,这里使用带头链表。
//哨兵位
newHead = newTail = (ListNode*)malloc(sizeof(ListNode));
newHead->next = NULL;
· 申请完空间后,将头结点的next指针置空,这样直接就能进行尾插,不需要再判断链表是否为空。
在循环中:
if (l1->val > l2->val)
{
newTail->next = l2;
l2 = l2->next;
newTail = newTail->next;
}
若l1所指向的结点值大于l2,那么l2所指向的结点尾插入新链表,并将l2移向下一个结点。
else
{
newTail->next = l1;
l1 = l1->next;
newTail = newTail->next;
}
若l2所指向的结点值大于l1,那么l1所指向的结点尾插入新链表,并将l1移向下一个结点。
当l1与l2中有一个指向空,即越界,跳出循环。
while(l2)
{
newTail->next = l2;
l2 = l2->next;
newTail = newTail->next;
}
当l1为空,将l2中剩余结点尾插入链表中。
while(l1)
{
newTail->next = l1;
l1 = l1->next;
newTail = newTail->next;
}
当l2为空,将l1中剩余结点尾插入链表中。
return newHead->next;
最后,由于带头链表哨兵位的存在,返回头结点的下一个结点即可。
完整代码:
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
ListNode* l1 = list1;
ListNode* l2 = list2;
ListNode *newHead,*newTail;
//哨兵位
newHead = newTail = (ListNode*)malloc(sizeof(ListNode));
newHead->next = NULL;
while(l1 && l2)
{
if (l1->val > l2->val)
{
newTail->next = l2;
l2 = l2->next;
newTail = newTail->next;
}
else
{
newTail->next = l1;
l1 = l1->next;
newTail = newTail->next;
}
}
//l1为空
while(l2)
{
newTail->next = l2;
l2 = l2->next;
newTail = newTail->next;
}
//l2为空
while(l1)
{
newTail->next = l1;
l1 = l1->next;
newTail = newTail->next;
}
return newHead->next;
}