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

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

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;
}
相关推荐
LXS_35716 分钟前
Day 18 C++提高 之 STL常用容器(string、vector、deque)
开发语言·c++·笔记·学习方法·改行学it
蒸蒸yyyyzwd19 分钟前
网络编程——threadpool.h学习笔记
笔记·学习
浪子不回头41521 分钟前
SGLang学习笔记
人工智能·笔记·学习
deng-c-f1 小时前
Linux C/C++ 学习日记(53):原子操作(二):实现shared_ptr
开发语言·c++·学习
Cricyta Sevina2 小时前
Java IO 基础理论知识笔记
java·开发语言·笔记
旖旎夜光2 小时前
Linux(3)(下)
linux·学习
晨晖22 小时前
简单排序c语言版
c语言·开发语言
geneculture2 小时前
从智力仿真到认知协同:人机之间的价值对齐与共生框架
大数据·人工智能·学习·融智学的重要应用·信智序位
sbc-study3 小时前
comsol仿真例题学习-模块-水平集+相场法
学习·comsol·例题·水平集·相场法·电镀