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

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

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;
}
相关推荐
nap-joker14 分钟前
【多模态解耦】DecAlign:用于解耦多模态表示学习的分层跨模态对齐
学习·多模态融合·最优传输·多模态表征学习·特征解耦·音频+图像+文本·原型引导
无敌昊哥战神15 分钟前
【LeetCode 257】二叉树的所有路径(回溯法/深度优先遍历)- Python/C/C++详细题解
c语言·c++·python·leetcode·深度优先
551只玄猫29 分钟前
【数据库原理 实验报告1】创建和管理数据库
数据库·sql·学习·mysql·课程设计·实验报告·数据库原理
㓗冽31 分钟前
8皇后·改-进阶题16
数据结构
x_xbx1 小时前
LeetCode:148. 排序链表
算法·leetcode·链表
IDZSY04301 小时前
AI社交平台进阶指南:如何用AI社交提升工作学习效率
人工智能·学习
happymaker06261 小时前
web前端学习日记——DAY05(定位、浮动、视频音频播放)
前端·学习·音视频
xuhaoyu_cpp_java1 小时前
过滤器与监听器学习
java·经验分享·笔记·学习
LegendNoTitle2 小时前
计算机三级等级考试 网络技术 选择题考点详细梳理
服务器·前端·经验分享·笔记·php
炽烈小老头2 小时前
【 每天学习一点算法 2026/03/23】数组中的第K个最大元素
学习·算法·排序算法