题目:将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
关于链表:
一个链表是由有限个节点组成的。
链表分为数据域指针域。
- 数据域:存储数据;
- 指针域:是一个指针变量,存储下一个节点的地址,使本来不连续的空间通过该指针链接到一起。(数组与链表的在此处的区别:数组内存连续,可以用指针++找下一个,但是链表是用指针域找另一个结点。 )
指针域的p指针,指针变量里存的是下一个节点的地址。指针最开始是空的状态(指向NULL防止野指针),只有后边有东西的时候再赋值追加。
链表拼接:链表一定要有个头结点,如果不知道头结点,就找不到了,所以得先把头结点创建好;链表要有尾结点,不然就是第一个节点一直加新节点,不是上一个和下一个了 。
关于题目:规定不能一边遍历一边创建新链表,要用已有节点进行拼接。这个题目返回一个链表指针ListNode*,就是返回的是头结点。
思路:直接比较L1的val和L2的val,拼接。
步骤:
- 选择头结点:比较L1和L2的头结点的val,谁小谁是新链表的头结点,相等随便设定一个作为头结点。
- 比较L1,L2的val值大小:那个链表的值小,头结点的next指向谁,再次比较,依次连接。
- 判断是否有剩余结点:进行比较的时候,出现一个链表长短不一的问题。所以用尾指针,在判断是否有剩余节点(L1为空或L2为空)之后,尾指针直接与多的剩余链表进行拼接。
注意:开始就要判断链表是否为空的问题,以及不要忽略尾指针后移的问题。
代码如下:
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
//选取头结点
if(l1 == nullptr) return l2;
if(l2 == nullptr) return l1;
ListNode* HEAD = nullptr;//设置头结点
if(l1->val > l2->val)
{
HEAD = l2;
l2 = l2->next;
}
else
{
HEAD = l1;
l1 = l1->next;
}
ListNode* Tail = HEAD;//设置尾结点
while(l1 && l2)//比较LI,L1中两个节点谁大
{
if(l1->val > l2->val)
{
Tail->next = l2;//拼接
l2 = l2->next;//往后移动l2
}
else
{
Tail->next = l1;
l1 = l1->next;//往后移动l1
}
Tail = Tail->next;//尾指针也得往后移动
}//这个循环会走到直到L1为空或L2为空
//判断是否有剩余结点,有剩余拼接一个
if(l1) Tail->next = l1;
if(l2) Tail->next = l2;
return HEAD;//返回头结点
}
};