【数据结构】单链表OJ题(一)

在这里插入图片描述
🔥博客主页 小羊失眠啦.
🎥系列专栏《C语言》 《数据结构》 《Linux》《Cpolar》
❤️感谢大家点赞👍收藏⭐评论✍️


在这里插入图片描述

文章目录

  • 前言
  • 一、移除链表元素
  • 二、寻找链表中间结点
  • 三、输出链表倒数第k个结点
  • 四、反转单链表
  • 五、合并两个有序链表

前言

在上一期中我们介绍了单链表,也对单链表的实现进行具体的了解,接下来我们开始单链表的练习,对单链表更深层的理解,让小伙伴们灵活的使用单链表,话不多说,开造~


一、移除链表元素

在这里插入图片描述

💭方法一:

我们使用两个指针遍历数组,遇到与 val 相同的结点时,就删除这个节点。我们在思考问题时要想全面,当要删除头节点时,常规方法就无法实现,对于删除头节点要做单独处理。

常规删除

在这里插入图片描述

头节点删除

在这里插入图片描述

思路:(1)首先给出判断cur是否是空的,不是空的之后,判断是否有val,有的话就判断是否在头部,是的话一种情况,不是的话,又是一种情况。(2)第一种情况,题意所给出的情况;第二种情况,中间连续个value(前两种可以合并);第三种情况,一开始就出现6或者连续个6;第四种情况:空的

struct ListNode* removeElements(struct ListNode* head, int val)
{
    if (head == NULL)
        return head;
    struct ListNode* prev = NULL, * cur = head;
    while (cur)
    {
        struct ListNode* Next = cur->next;
        if (cur->val == val)
        {
            if (prev == NULL)
            {
                head = Next;
                cur = Next;
            }
            else
            {
                prev->next = Next;
                free(cur);
                cur = Next;
            }
        }
        else
        {
            prev = cur;
            cur = Next;
        }
    }
    return head;
}

💭方法二:

我们通过遍历,把节点的数据域不等于val的节点尾接到新的链表中。我们要考虑第一个节点是不是要删除的。最后一个节点的指针域置空要放在循环结束后,判断tail是否为空指针。

img

truct ListNode* removeElements(struct ListNode* head, int val) {
    struct ListNode* newnode=NULL;
    struct ListNode* cur=head,*tail=newnode;
    while(cur)
    {
        if(cur->val!=val)
        {
            if(tail==NULL)
            {
                newnode=cur;
                tail=newnode;
            }
            else
            {
                tail->next=cur;
                tail=tail->next;
            }
            cur=cur->next;
        }
        else
        {
            struct ListNode* del=cur;
            cur=cur->next;
            free(del);
        }
    }
    if(tail)
    {
        tail->next=NULL;
    }
    return newnode;
}

二、寻找链表中间结点

在这里插入图片描述

我们可以定义两个指针,快指针一次走两步,慢指针一次走一步,当快指针走到结尾时,慢指针正好走了一半,这样我们就可以找到中间节点。

img

struct ListNode* middleNode(struct ListNode* head) 
{
    struct ListNode* slow=head,*fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
    }
    return slow;
}

三、输出链表倒数第k个结点

在这里插入图片描述

我们可以参考上一题的方法,同样定义快慢指针,先让快指针走k步,然后再同时走,走到fast为空指针就找了倒数第k个节点。有可能链表没有k个节点,所以我们要加入判断。

img

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    struct ListNode* slow=pListHead,*fast=pListHead;
    while(k--)
    {
        if(fast==NULL)
        {
            return NULL;
        }
        fast=fast->next;
    }
    while(fast)
    {
        slow=slow->next;
        fast=fast->next;
    }
    return slow;
}

四、反转单链表

在这里插入图片描述

💭方法一:

我们定义三个指针n1,n2,n3,来改变节点链接的顺序。将头节点变为尾节点,当n2为空指针时,n1就为链表的头节点,只需返回n1就可以。两个指针倒方向,一个指针保持下一个。

struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* n1=NULL,*n2=head,*n3=NULL;
    if(head==NULL)
        return head;
    while(n2)
    {
        n3=n2->next;
        n2->next=n1;
        n1=n2;
        n2=n3;
    }
    return n1;
}

💭方法二:

将链表的节点一个一个拿下来,进行头插。这里要注意赋值的顺序。

img

struct ListNode* reverseList(struct ListNode* head)
{
    struct ListNode* cur=head;
    struct ListNode* newnode=NULL;
    while(cur)
    {
        //保存节点
        struct ListNode* next=cur->next;
 
        //头插
        cur->next=newnode;
        newnode=cur;
        cur=next;
    }
    return newnode;
}

五、合并两个有序链表

在这里插入图片描述

思路:每次取小的节点尾插到新的节点

注意:其中一个为空的情况要注意

💭代码一:(不带头)

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) 
{
    if(list1==NULL)
        return list2;
    if(list2==NULL)
        return list1;
    struct ListNode* head=NULL;
    struct ListNode* tail=NULL;
    while(list1&&list2)
    {
        if((list1->val) < (list2->val))
        {
            if(tail==NULL)
            {
                head=list1;
                tail=list1;
            }
            else
            {
                tail->next=list1;
                tail=list1;
            }
            list1=list1->next;
        }
        else
        {
            if(tail==NULL)
            {
                head=list2;
                tail=list2;
            }
            else
            {
                tail->next=list2;
                tail=list2;
            }
            list2=list2->next;
        }
    }
    if(list1)
        tail->next=list1;
    if(list2)
        tail->next=list2;
    return head;
}

有头单链表:head->next指的是第一个节点的地址(带头,相当于开头多了一个节点,但是节点里面的val不确定,next指向下一个节点); 无头单链表:head指的是第一个节点的地址; OJ题默认不带头

💭代码二:(带头)

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    struct ListNode* head = (struct ListNode*)malloc(sizeof(struct ListNode));//创建一个头
    struct ListNode* tail = head;
    head->next = NULL;//就是含有值的节点的第一个
    while (list1 && list2)
    {
        struct ListNode* next1 = list1->next;
        struct ListNode* next2 = list2->next;
        if ((list1->val) < (list2->val))
        {
            tail->next = list1;
            tail = list1;
            list1 = next1;
        }
        else
        {
            tail->next = list2;
            tail = list2;
            list2 = next2;
        }
    }

    if (list1 != NULL)
    {
        tail->next = list1;

    }
    if (list2 != NULL)
    {
        tail->next = list2;
    }
    struct ListNode* list = head->next;
    free(head);
    return list;
}

思路:每次取小的节点尾插到新的节点

注意:mallloc的一个地址,到最后要进行释放。

本次的内容到这里就结束啦。希望大家阅读完可以有所收获,同时也感谢各位铁汁们的支持。文章有任何问题可以在评论区留言,小羊一定认真修改,写出更好的文章~~

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/122493.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Web】在前端中CSS的语法

CSS规则是由两个主要的部分构成&#xff1a;选择器、以及一条或多条声明。 选择器通常是需要改变的HTML元素。 每条声明由一个属性和一个值组成。 属性&#xff08;Property&#xff09;是需要设置的样式属性&#xff08;Style attribute&#xff09;。每一个属性有一个值。…

Vue3+vite+cesium环境搭建

引言 目前有不少vue3cesium的配置教学&#xff0c;存在以下两个问题&#xff1a; &#xff08;1&#xff09;vue3cli方式&#xff0c;随着项目的迭代&#xff0c;npm run serve 启动调试很慢&#xff1b; &#xff08;2&#xff09;vue3vite 确实能将调试启动提升不少的&…

万宾科技智能井盖监测仪器助力建设数字化城市

市政公共设施建设在近几年来发展迅速&#xff0c;市政设备的更新换代&#xff0c;资产管理等也成为其中的重要一项。在市政设施建设过程中&#xff0c;井盖也是不可忽视的&#xff0c;一方面&#xff0c;根据传统的管理井盖模式来讲&#xff0c;缺乏有效的远程监控管理方法和手…

zookeeper:启动原理

主类&#xff1a; QuorumPeerMain, 其中调用了main对象的initializeAndRun方法&#xff0c; 首先定义了QuorumPeerConfig对象&#xff0c;然后调用了parse方法&#xff0c;parse方法代码如下&#xff1a; 其中调用的parseProperties方法的代码如下&#xff1a; 可以看到&am…

Docker实战

一、Docker安装 以下均以CentOS 7为例 1、安装Docker yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin 2、启动和校验 # 启动Docker systemctl start docker# 停止Docker systemctl stop docker# 重启 systemctl resta…

【GEE】7、利用GEE进行遥感影像分类【随机森林分类】

1简介 在本模块中&#xff0c;我们将讨论以下概念&#xff1a; 监督和非监督图像分类之间的区别。Google Earth Engine 提供的各种分类算法的定义和应用。如何使用 randomForest 设置和运行分类&#xff0c;以 aspen 存在和不存在作为示例数据集。 2背景 图像分类 人类自然倾向…

kubernetes集群编排(7)

目录 k8s认证授权 pod绑定sa 认证 授权 k8s认证授权 pod绑定sa [rootk8s2 ~]# kubectl create sa admin //在当前 Kubernetes 集群中创建一个名为 "admin" 的新服务账户[rootk8s2 secret]# vim pod3.yaml apiVersion: v1 kind: Pod metadata:name: mypod spec…

Leetcode—剑指OfferII LCR 044.在每个树行中找最大值【中等】

2023每日刷题&#xff08;二十三&#xff09; Leetcode—LCR 044.在每个树行中找最大值 DFS实现代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ /*** Note: The returned …

单应用多语言切换(语言国际化)

目录 编写语言管理类 编写Activity 的父类 DEMO 实验界面--首页Activity DEMO 实验界面--设置语言Activity Demo 语言资源文件 参考连接 编写语言管理类 package com.example.languageapplicationimport android.content.Context import android.content.ContextWrapper i…

Oracle Primavera Unifier 23.10 新特征

根据官方的说法&#xff0c;Unifier 23.7 ~ 23.9 更多为对功能bug的修复&#xff0c;以下将对23.10进行重点介绍 Cost Sheets Cost Sheets Support Conditional Formatting Conditional formatting of table data is now supported in cost sheets with features such as ce…

Excel下拉填充时,如何使得数字不递增?

问题描述&#xff1a;Excel下拉填充时&#xff0c;如何使得数字不递增&#xff1f; 解决办法&#xff1a;先下拉填充数据之后&#xff0c;看到最后一个单元格的右下角有个填充设置的符号&#xff0c;右键选择复制单元格即可。其中这里的填充序列就是递增数字的操作。

高性能网络编程 - 关于单台服务器并发TCP连接数理论值的讨论

文章目录 概述操作系统的限制因素文件句柄限制1. 进程限制2. 全局限制 端口号范围限制 概述 单台服务器可以支持的并发TCP连接数取决于多个因素&#xff0c;包括硬件性能、操作系统限制、网络带宽和应用程序设计。以下是一些影响并发TCP连接数的因素&#xff1a; 服务器硬件性…

split() 函数实现多条件转为数据为数组类型

使用 split() 函数并传递正则表达式 /[,;.-]/ 作为分隔符来将字符串按照逗号、分号和破折号进行拆分&#xff0c;并将结果赋值给 splitArray 数组。下面是一个示例代码&#xff1a; 在上面的示例中&#xff0c;我们使用 split() 函数将 inputString 字符串按照逗号、分号和破折…

低代码平台,业务开发的“银弹”

目录 一、为什么需要低代码平台 二、低代码平台的搭建能力 三、低代码其他能力 四、写在最后 随着互联网和信息技术的快速发展&#xff0c;各行各业都在积极拥抱数字化转型。在这个过程中&#xff0c;软件开发成为企业实现数字化转型的关键环节。然而&#xff0c;传统的软件开发…

IP协议,

文章目录 IP协议IP相当于OSI参考模型的第3层网络层与数据链路层的关系IP基础知识IP地址属于网络层地址路由控制数据链路的抽象化IP属于面向无连接型IP地址的基础知识IP地址的定义路由控制IPv6 IP协议 IP相当于OSI参考模型的第3层 IP&#xff08;IPv4、IPv6&#xff09;相当于…

70 内网安全-域横向内网漫游Socks代理隧道技术

目录 必要基础知识点:1.内外网简单知识2.内网1和内网2通信问题3.正向反向协议通信连接问题4.内网穿透代理隧道技术说明 演示案例:内网穿透Ngrok测试演示-两个内网通讯上线内网穿透Frp自建跳板测试-两个内网通讯上线CFS三层内网漫游安全测试演练-某CTF线下2019 涉及资源: 主要说…

el-table实现单选框+隐藏多选框+回显

0 效果 1 单选框 2 隐藏多选框 3 回显 回显数据要在el-table中添加两个属性

快速排序【2023年最新】

快速排序思想总结&#xff1a; 内附快排模版&#xff0c;可开袋即食。 学了一套快速排序的模版&#xff0c;接下来我说一下我的理解。 这套模板的思路是这样的&#xff0c;随机找到一个点&#xff0c;可以是数组中的左边界也可以是右边界&#xff0c;或者是数组中任何一个元…

Power Apps-“编辑“窗体组件

插入一个“编辑”窗体 连接数据源 在该组件的Item函数中编辑筛选符合条件的唯一记录 LookUp(表名,列名值) LookUp参考文档&#xff1a;Filter、Search 和 LookUp 函数&#xff08;包含视频&#xff09; - Power Platform | Microsoft Learn 数据表里的数据就一一对应出现在了组…