代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
//空链表处理
if(!list1)
return list2;
else if(!list2)
return list1;
//创建两个指针,分别遍历list1和list2
ListNode* l1 = list1;
ListNode* l2 = list2;
//创建新的链表,newHead用来保存新链表的头节点,newTail用来遍历新链表
ListNode* newHead,*newTail;
newHead = newTail = NULL;
//循环比大小放入新链表中
//只要l1,l2有一个指向空就跳出循环
while(l1 && l2)
{
//如果l1比l2中的val值小或者相等
if(l1->val <= l2->val)
{
//将l1中的值插入到新链表中
//处理新链表为空和新链表不为空两种情况
if(newTail == NULL)
{
newHead = newTail = l1;
}
else
{
newTail->next = l1;
newTail = newTail->next;
}
l1 = l1->next;
}
else
{
if(newTail == NULL)
{
newHead = newTail = l2;
}
else
{
newTail->next = l2;
newTail = newTail->next;
}
l2 = l2->next;
}
}
//处理L1先指向空指针以及L2先指向空指针两种情况
if(l1)
{
newTail->next = l1;
}
if(l2)
{
newTail->next = l2;
}
return newHead;
}
提交结果:
我们可以看到,当我们一个指针走向空的时候我们要将另一个指针指向的剩下的所有数据插入到新链表中,如果剩下的数据多,那么就应该使用循环啊,为什么这里是if语句呢?
当一个指针已经指向空的时候,我们只需要将另一个指针指向的节点插入到新的链表中就可以了,那么因为另一个指针指向的节点的next指针指向下一个节点,下一个节点的next指针指向下下一个节点,一次类推,直到空,所有我们只需将一个节点插入到新的链表中,其它一连串都会过来。
优化的话也可以封装一个函数。 因为链表分为空链表和非空链表两种情况,导致代码非常冗余,所有我们直接创建一个非空链表会比较方便,直接尾插就可以了
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
//空链表处理
if(!list1)
return list2;
else if(!list2)
return list1;
//创建两个指针,分别遍历list1和list2
ListNode* l1 = list1;
ListNode* l2 = list2;
ListNode* newHead,*newTail;
//newHead和newTail不是空链表,因为动态申请内存空间了
newHead = newTail = (ListNode*)malloc(sizeof(ListNode));
if(newHead == NULL)
{
//动态内存申请的空间要判断返回值这只是代码规范,只有在没有内存的时候malloc的
//返回值才为空,没有内存基本上不会有的可能,所以这里不判断也是可以的
perror("malloc err!\n");
exit(1);
}
//循环比大小放入新链表中
//只要l1,l2有一个指向空就跳出循环
while(l1 && l2)
{
//如果l1比l2中的val值小或者相等
if(l1->val <= l2->val)
{
//不用判断链表是否为空,直接尾插
newTail->next = l1;
newTail = newTail->next;
l1 = l1->next;
}
else
{
newTail->next = l2;
newTail = newTail->next;
l2 = l2->next;
}
}
//处理L1先指向空指针以及L2先指向空指针两种情况
if(l1)
{
newTail->next = l1;
}
if(l2)
{
newTail->next = l2;
}
//保存有效节点的第一个节点
ListNode* ret = newHead->next;
//释放动态开辟的空间
free(newHead);
//置为空指针,避免成为野指针
newHead = NULL;
//返回有效节点
return ret;
}
这里有效的减少了代码的冗余,malloc申请的节点称为哨兵位。
提交结果: