合并两个有序链表
题目要求:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
还是先讲讲解题的思路:这题我主要使用了尾插法,就是创建一个新的链表的头,然后每次都取出两个链表中最小的那一个结点然后接在新的链表的后面,直到链表的结束,虽然思路只有这么多,但是这题要注意的细节还是挺多的,我会在代码的注释里解释
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
//先判断一下l1和l2是否为空,若为空直接返回另一个链表
if(l1 == NULL)
return l2;
if(l2 == NULL)
return l1;
//定义两个指针作为新的链表的头和尾,定义尾主要是因为新链表的head不能动所以让tail指针带动整个链表的移动
Node* head = NULL;
Node* tail = NULL;
//判断头指针应该是两个链表的头指针中最小的一个
if(l1->val < l2->val)
{
head = tail = l1;
l1 = l1->next;
}
else
{
head = tail = l2;
l2 = l2->next;
}
//开始遍历整个链表,比对l1和l2然后选出最小的结点,接在新链表的后面
while(l1 && l2)
{
if(l1->val < l2->val)
{
tail->next = l1;
l1 = l1->next;
tail = tail->next;
}
else
{
tail->next = l2;
l2 = l2->next;
tail = tail->next;
}
}
//最后有一条链表已经为空,但是还有一条链表不为空,要将不为空的链表再次接在新链表的后面
if(l1)
tail->next = l1;
else
tail->next = l2;
return head;
}
哨兵结点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
//先判断一下l1和l2是否为空,若为空直接返回另一个链表
if(l1 == NULL)
return l2;
if(l2 == NULL)
return l1;
//定义两个指针作为新的链表的头和尾,定义尾主要是因为新链表的head不能动所以让tail指针带动整个链表的移动
Node* head = NULL;
Node* tail = NULL;
//创建一个哨兵结点,该结点不存放任何数据只是方便尾插
tail = head = (Node*)malloc(sizeof(Node));
//开始遍历整个链表,比对l1和l2然后选出最小的结点,接在新链表的后面
while(l1 && l2)
{
if(l1->val < l2->val)
{
tail->next = l1;
l1 = l1->next;
tail = tail->next;
}
else
{
tail->next = l2;
l2 = l2->next;
tail = tail->next;
}
}
//最后有一条链表已经为空,但是还有一条链表不为空,要将不为空的链表再次接在新链表的后面
if(l1)
tail->next = l1;
else
tail->next = l2;
Node* realhead = head->next;
return realhead;
}
哨兵结点就是一个空节点,该结点其实不存犯任何数据,只是方便尾插,这样就不用找两个链表中那个头最小了