【数据结构OJ题】合并两个有序链表

原题链接:https://leetcode.cn/problems/merge-two-sorted-lists/description/

目录

[1. 题目描述](#1. 题目描述)

[2. 思路分析](#2. 思路分析)

[3. 代码实现](#3. 代码实现)


1. 题目描述

2. 思路分析

可以先创建一个空链表,然后依次****从两个有序链表选取最小的 进行尾插操作。(有点类似双指针的操作~)

我们可以用不带哨兵位带哨兵位两种方法实现:

不带哨兵位

如果两个链表有一个为空,直接返回另一个链表即可。

如果两个链表都是非空的,我们就创建一个结构体指针head 和一个结构体指针tail,都初始化为空指针NULL,之后分别用来指向新链表的头和尾。

同时遍历两个链表,当有一个链表遍历完时停止。这里使用while(list1&&list2)进行循环

当空链表插入第一个结点(也就是tail==NULL)时需要单独考虑,让头指针head和尾指针next都指向此时值较小的那个结点即可。

其他情况,正常尾插即可,就是让tail->next指向值较小的结点。之后让tail指向当前插入的结点(也就是让tail往后走一步),然后让相对应的list1或者list2往后走一步即可。

因为有可能while循环结束时,还有链表的结点没有被插入到新链表 。所以我们要用if语句 判断,将剩余的结点直接插入到新链表

最后我们返回头指针head即可。

带哨兵位

带哨兵位最大的好处是方便尾插不用单独考虑在新链表插入第一个结点时的情况了,因为带哨兵位让每一个结点地位都一样了

这里相比不带哨兵位多的一些操作就是要先用malloc()函数申请一个结点作为哨兵位,让head和tail一开始都直接指向这个结点。

当完成合并操作后,让头指针head往后走一步,指向哨兵位后面一个结点

然后使用free()释放掉哨兵位

最后返回head即可。

3. 代码实现

不带哨兵位

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    if(list1==NULL)
        return list2;
    if(list2==NULL)
        return list1;
    struct ListNode *head=NULL,*tail=NULL;
    while(list1&&list2)
    {
        if(list1->val<=list2->val)
        {
            if(tail==NULL)
            {
                head=tail=list1;
            }
            else
            {
                tail->next=list1;
                tail=tail->next;
            }
            list1=list1->next;
        }
        else
        {
            if(tail==NULL)
            {
                head=tail=list2;
            }
            else
            {
                tail->next=list2;
                tail=tail->next;
            }
            list2=list2->next;
        }
    }
    if(list1)
        tail->next=list1;
    if(list2)
        tail->next=list2;
    return head;
}

带哨兵位

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
    if(list1==NULL)
        return list2;
    if(list2==NULL)
        return list1;
    struct ListNode *head=NULL,*tail=NULL;
    //带一个哨兵位,方便尾插
    head=tail=(struct ListNode*)malloc(sizeof(struct  ListNode));
    while(list1&&list2)
    {
        if(list1->val<=list2->val)
        {
            tail->next=list1;
            tail=tail->next;
            list1=list1->next;
        }
        else
        {
            tail->next=list2;
            tail=tail->next;
            list2=list2->next;
        }
    }
    if(list1)
        tail->next=list1;
    if(list2)
        tail->next=list2;

    struct ListNode *del=head;
    head=head->next;
    free(del);
    return head;
}
相关推荐
醉城夜风~3 分钟前
[数据结构]堆详解
开发语言·数据结构
苏言の狗9 分钟前
小R的并集大小期望计算 | 蛮力
数据结构·算法
BineHello15 分钟前
MPC用优化求解器 - 解决无人机轨迹跟踪
算法·矩阵·自动驾驶·动态规划·无人机
橘颂TA16 分钟前
每日一练之链表的回文结构
数据结构·链表
誓约酱17 分钟前
(每日一题) 力扣 14 最长公共前缀
算法·leetcode·职场和发展
刃神太酷啦20 分钟前
数据结构(蓝桥杯常考点)
数据结构·c++·蓝桥杯c++组
南玖yy36 分钟前
C语言柔性数组深度解析:动态内存管理的艺术
c语言·开发语言·柔性数组
冠位观测者1 小时前
【Leetcode 每日一题 - 补卡】2070. 每一个查询的最大美丽值
数据结构·算法·leetcode
誓约酱1 小时前
(每日一题) 力扣 860 柠檬水找零
linux·c语言·c++·算法·leetcode·职场和发展
地平线开发者1 小时前
手把手基于 MINI 数据集带你做一次板端精度评估
算法·自动驾驶