将两个升序 链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
cpp
struct ListNode
{
int val;
struct ListNode* next;
};
w
方法一---不使用哨兵位
我们创建一个新链表用于合并两个升序链表, 将两个链表中最小的结点依次尾插到新链表newlist中,当循环结束后,如果list1不为空说明list2为空使循环停止,那么我们将新链表尾插指针cur指向list1,反之指向list2:
cpp
while (list1 && list2)
{
if (list1->val < list2->val)
{
if (newlist == NULL)
{
newlist = cur = list1;
}
else
{
cur->next = list1;
cur = cur->next;
}
list1 = list1->next;
}
else
{
if (newlist == NULL)
{
newlist = cur = list2;
}
else
{
cur->next = list2;
cur = cur->next;
}
list2 = list2->next;
}
}
if (list1)
{
cur->next = list1;
}
if (list2)
{
cur->next = list2;
}
return newlist;
但是只有这个循环还不行,如果list1与list2开始就为NULL,那么最后cur->next会形成非法访问,因此在代码开始需要进行判断,list1为空则返回list2,list2为空返回list1。
cpp
if (list1 == NULL)
return list2;
if (list2 == NULL)
return list1;
整体代码如下:
cpp
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
struct ListNode* newlist, * cur;
newlist = cur = NULL;
if (list1 == NULL)
return list2;
if (list2 == NULL)
return list1;
while (list1 && list2)
{
if (list1->val < list2->val)
{
if (newlist == NULL)
{
newlist = cur = list1;
}
else
{
cur->next = list1;
cur = cur->next;
}
list1 = list1->next;
}
else
{
if (newlist == NULL)
{
newlist = cur = list2;
}
else
{
cur->next = list2;
cur = cur->next;
}
list2 = list2->next;
}
}
if (list1)
{
cur->next = list1;
}
if (list2)
{
cur->next = list2;
}
return newlist;
}
方法二---使用哨兵位
cpp
newlist = (struct ListNode*)malloc(sizeof(struct ListNode));
cur = newlist;
使用哨兵位的好处在于,循环内部不需要判断有效结点为空的情况,因为哨兵位不是有效结点,哨兵位的next指向第一个有效结点,因此不用担心有效结点为空导致非法访问。
cpp
while(list1&&list2)
{
if(list1->val < list2->val)
{
cur->next = list1;
cur=cur->next;
list1=list1->next;
}
else
{
cur->next = list2;
cur=cur->next;
list2=list2->next;
}
}
使用哨兵位的缺陷在于,开辟了额外的空间,在返回之前或者函数结束之前需要释放哨兵位空间并将指向哨兵位的指针置空。
cpp
struct ListNode* tmp = newlist->next;
free(newlist);
newlist = NULL;
return tmp;
那么总体代码如下:
cpp
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2)
{
struct ListNode* newlist ,*cur;
newlist = (struct ListNode*)malloc(sizeof(struct ListNode));
cur = newlist;
if(list1==NULL)
return list2;
if(list2==NULL)
return list1;
while(list1&&list2)
{
if(list1->val < list2->val)
{
cur->next = list1;
cur=cur->next;
list1=list1->next;
}
else
{
cur->next = list2;
cur=cur->next;
list2=list2->next;
}
}
if(list1)
{
cur->next = list1;
}
if(list2)
{
cur->next = list2;
}
struct ListNode* tmp = newlist->next;
free(newlist);
newlist = NULL;
return tmp;
}