单链表---合并两个链表

将两个升序 链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

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;
}
相关推荐
寒月小酒27 分钟前
第三章 索引构建(2-all -in-rag学习)
学习
天国梦34 分钟前
中学生居家英语听力训练深度解析:从核心痛点到AI赋能的全链路方案
人工智能·学习
2501_914245932 小时前
C语言设计模式详解:从理论到实践的完整指南
c语言·开发语言·设计模式
hengcaib4 小时前
防封号电销外包公司怎么选合规线路与风控核查方法
笔记
2501_914245934 小时前
C语言与硬件交互:从GPIO到中断的嵌入式编程实践
c语言·单片机·交互
胡渠洋5 小时前
postman学习
学习·测试工具·postman
炸膛坦客5 小时前
单片机/C/C++八股:(二十四)编译文件( .bin 和 .hex ,包括 .elf 和 .axf )
c语言·c++·单片机
兰令水6 小时前
hot100【acm版】【2026.7.14打卡-java版本】
java·数据结构·算法·leetcode·面试
Amazing_Cacao6 小时前
CFCA精品可可产区风土解析(美洲):无情打破风味堆叠假象,建立时间轴上的层次动态阅读系统
学习
cpp_25016 小时前
P10098 [ROIR 2023] 地铁建设 (Day 2)
数据结构·c++·算法·贪心·二分答案·洛谷题解