【蓝桥杯入门不入土】变幻莫测的链表

news2024/11/14 6:55:23

文章目录

  • 一:链表的类型
    • 单链表
    • 双链表
    • 循环链表
  • 二:链表的存储方式
  • 三:链表的定义
    • 删除节点
    • 添加节点
  • 四:实战练习
    • 1.设计链表
    • 2. 移除链表元素
    • 最后说一句

一:链表的类型

单链表

什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。

链表的入口节点称为链表的头结点也就是head。

如图所示: 链表1
在这里插入图片描述

双链表

单链表中的指针域只能指向节点的下一个节点。

双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。

双链表 既可以向前查询也可以向后查询。

如图所示: 链表2

循环链表

循环链表,顾名思义,就是链表首尾相连。

循环链表可以用来解决约瑟夫环问题。

链表4

二:链表的存储方式

了解完链表的类型,再来说一说链表在内存中的存储方式。

数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。

链表是通过指针域的指针链接在内存中各个节点。

所以链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。

如图所示:

链表3

这个链表起始节点为2, 终止节点为7, 各个节点分布在内存的不同地址空间上,通过指针串联在一起。

在这里插入图片描述

三:链表的定义

public class ListNode {
    // 结点的值
    int val;

    // 下一个结点
    ListNode next;

    // 节点的构造函数(无参)
    public ListNode() {
    }

    // 节点的构造函数(有一个参数)
    public ListNode(int val) {
        this.val = val;
    }

    // 节点的构造函数(有两个参数)
    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

删除节点

删除D节点,如图所示:

链表-删除节点

只要将C节点的next指针 指向E节点就可以了。

添加节点

如图所示:

链表-添加节点

可以看出链表的增添和删除都是O(1)操作,也不会影响到其他节点。

但是要注意,要是删除第五个节点,需要从头节点查找到第四个节点通过next指针进行删除操作,查找的时间复杂度是O(n)。

四:实战练习

1.设计链表

力扣链接

设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。

在链表类中实现这些功能:

get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。

addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。

addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。

addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果

index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。

deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

示例:

MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3
linkedList.get(1); //返回2
linkedList.deleteAtIndex(1); //现在链表是1-> 3
linkedList.get(1); //返回3

在这里插入图片描述

//单链表
class ListNode {
    int val;
    ListNode next;
    ListNode(){}
    ListNode(int val) {
        this.val=val;
    }
}
class MyLinkedList {
    //size存储链表元素的个数
    int size;
    //虚拟头结点
    ListNode head;

    //初始化链表
    public MyLinkedList() {
        size = 0;
        head = new ListNode(0);
    }

    //获取第index个节点的数值,注意index是从0开始的,第0个节点就是头结点
    public int get(int index) {
        //如果index非法,返回-1
        if (index < 0 || index >= size) {
            return -1;
        }
        ListNode currentNode = head;
        //包含一个虚拟头节点,所以查找第 index+1 个节点
        for (int i = 0; i <= index; i++) {
            currentNode = currentNode.next;
        }
        return currentNode.val;
    }

    //在链表最前面插入一个节点,等价于在第0个元素前添加
    public void addAtHead(int val) {
        addAtIndex(0, val);
    }

    //在链表的最后插入一个节点,等价于在(末尾+1)个元素前添加
    public void addAtTail(int val) {
        addAtIndex(size, val);
    }

    // 在第 index 个节点之前插入一个新节点,例如index为0,那么新插入的节点为链表的新头节点。
    // 如果 index 等于链表的长度,则说明是新插入的节点为链表的尾结点
    // 如果 index 大于链表的长度,则返回空
    public void addAtIndex(int index, int val) {
        if (index > size) {
            return;
        }
        if (index < 0) {
            index = 0;
        }
        size++;
        //找到要插入节点的前驱
        ListNode pred = head;
        for (int i = 0; i < index; i++) {
            pred = pred.next;
        }
        ListNode toAdd = new ListNode(val);
        toAdd.next = pred.next;
        pred.next = toAdd;
    }

    //删除第index个节点
    public void deleteAtIndex(int index) {
        if (index < 0 || index >= size) {
            return;
        }
        size--;
        if (index == 0) {
            head = head.next;
	    return;
        }
        ListNode pred = head;
        for (int i = 0; i < index ; i++) {
            pred = pred.next;
        }
        pred.next = pred.next.next;
    }
}

2. 移除链表元素

力扣链接

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。

示例 1:

输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

示例 2:

输入:head = [], val = 1
输出:[]

也可以用迭代的方法删除链表中所有节点值等于特定值的节点。

用temp表示当前节点。如果temp的下一个节点不为空且下一个节点的节点值等于给定的val,则需要删除下一个节点。删除下一个节点可以通过以下做法实现:
temp.nect = temp.neat.next
如果temp的下一个节点的节点值不等于给定的val,则保留下一个节点,将temp移动到下一个节点即可。

当temp的下一个节点为空时,链表遍历结束,此时所有节点值等于val的节点都被删除。

具体实现方面,由于链表的头节点head有可能需要被删除,因此创建哑节点dummgHead,令dummgHead.next = head,初始化 temp = dummyHead,然后遍历链表进行删除操作。最终返回dummyHead.next 即为删除操作后的头节点。

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummyHead = new ListNode(0);
        dummyHead.next = head;
        ListNode temp = dummyHead;
        while (temp.next != null) {
            if (temp.next.val == val) {
                temp.next = temp.next.next;
            } else {
                temp = temp.next;
            }
        }
        return dummyHead.next;
    }
}

最后说一句

感谢大家的阅读,文章通过网络资源与自己的学习过程整理出来,希望能帮助到大家。

才疏学浅,难免会有纰漏,如果你发现了错误的地方,可以提出来,我会对其加以修改。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最经典的黑客技术入门知识大全

第一节、什么是黑客 以我的理解&#xff0c;“黑客”大体上应该分为“正”、“邪”两类&#xff0c;正派黑客依靠自己掌握的知识帮助系统管理员找出系统中的漏洞并加以完善&#xff0c;而邪派黑客则是通过各种黑客技能对系统进行攻击、入侵或者做其他一些有害于网络的事情&…

LCR数字电桥软件下载安装教程

软件&#xff1a;LCR数字电桥软件NS-LCR 语言&#xff1a;简体中文 环境&#xff1a;NI-VISA 安装环境&#xff1a;Win10以上版本&#xff08;特殊需求请后台私信联系客服&#xff09; 硬件要求&#xff1a;CPU2GHz 内存4G(或更高&#xff09;硬盘500G(或更高&#xff09; …

ProcDump+Mimikatz绕过杀毒软件抓密码

抓密码的奇淫技巧背景1、原理2、实操演示背景 如果主机上装了杀毒软件&#xff0c;开了防火墙&#xff0c;例如&#xff1a;360、火绒之类的话。Mimikatz就会被检测为病毒&#xff0c;无法使用&#xff0c;而想要对Mimikatz进行二次开发或者免杀难度会比较大&#xff0c;那有办…

边缘计算开源项目解读——kubeedge mappers实现

0 背景 本文重点解读kubeedge项目中的mapper模块。该模块位于kubeedge的edgecore的南向边缘侧&#xff0c;主要对接入kubeedge的终端设备&#xff0c;进行协议的适配和转换&#xff0c;使其可以和边缘设备通信&#xff0c;转换后的协议是我们前面描述的mqtt协议&#xff0c;当然…

玩转ThreadLocal

前言 ThreadLocal想必都不陌生&#xff0c;当多线程访问同一个共享变量时&#xff0c;就容易出现并发问题&#xff0c;为了保证线程安全&#xff0c;我们需要对共享变量进行同步加锁&#xff0c;但这又带来了性能消耗以及使用者的负担&#xff0c;那么有没有可能当我们创建一个…

只知道删除单张表的数据?不知道删除多张表的数据?

一些废话 可能在某某一天&#xff0c;你在表删除表数据的时候&#xff0c;不想一张表一张表的去删除&#xff0c;想把两个表的数据同时删除&#xff1b;然后你就会去搜索&#xff0c;然后你就很有很有很有很有可能会看到 me 的这篇优质&#xff08;呸&#xff01;&#xff01;…

HOT100--(5)最长回文子串

点击查看题目详情 中心扩散法 思路&#xff1a; 遍历字符串&#xff0c;以每个字符为中心点向两边扩散&#xff0c;如果遇到不一样的就跳出循环。以此类推&#xff0c;最后截取最大回文串返回。 细节 字符个数不一定都是奇数。当个数是偶数的是时候&#xff0c;我们可以“忽…

学习红客技术必备,手把手教你成为“安防第一人”

互联网时代已悄悄来临&#xff0c;作为新时代的人们&#xff0c;我们日常生活、工作、学习方面都需要借助互联网来完成&#xff0c;这样&#xff0c;又产生一种新的问题&#xff0c;那就是网络安全的问题&#xff0c;有时我们拼命加班好不容易完成的东西&#xff0c;在一夜之间…

优化Linux系统性能的必杀技:调整进程优先级!学会使用nice命令,让你的系统飞一般的顺畅!

文章目录前言一. nice命令介绍1.1 nice的介绍1.2 cpu资源的调度1.3 nice是控制内核吗&#xff1f;二. 语法格式及常用选项三. 参考案例3.1 将ls命令的优先级调整为最高3.2 将 find 命令的优先级调整为最低3.3 如何查看nice值四. nice和renice的区别总结前言 大家好&#xff0c…

Zookeeper的安装

目录 Zookeeper的安装 1、环境准备 2、上传 3、解压文件到opt/zookeeper目下 4、安装完后进入zookeeper&#xff0c;找到conf目录 5、复制zoo_sample.cfg 6、编辑zoo.cfg 7、复制一份会话&#xff0c;进入zookeeper安装目录&#xff0c;创建一个文件夹zkdata&#xff0…

Linux·DMA 与零拷贝技术

DMA 与零拷贝技术注意事项&#xff1a;除了 Direct I/O&#xff0c;与磁盘相关的文件读写操作都有使用到 page cache 技术。1. 数据的四次拷贝与四次上下文切换很多应用程序在面临客户端请求时&#xff0c;可以等价为进行如下的系统调用&#xff1a;File.read(file, buf, len);…

NOC2021年测试卷3

1. 角色初始位置坐标是(0,0),执行下面程序后,角色会出现在什么位置上?( ) A. x坐标为10,y坐标为50B. x坐标为40,y坐标为50C. x坐标为50,y坐标为40D. x坐标为30,y坐标为502. 执行下面程序后,按一次→键,兔子会?() A. 向右移动10步B. 向左移动10步C. 向上移动…

入职外包三个月,我提桶跑路了

有一种打工人的羡慕&#xff0c;叫做“大厂”。 真是年少不知大厂香&#xff0c;错把青春插稻秧。 但是&#xff0c;在深圳有一群比大厂员工更庞大的群体&#xff0c;他们顶着大厂的“名”&#xff0c;做着大厂的工作&#xff0c;还可以享受大厂的伙食&#xff0c;却没有大厂…

基于龙芯+国产FPGA 的VPX以太网交换板设计(一)

“棱镜门”的曝光&#xff0c;暴露出我国的信息安全存在极大的安全隐患&#xff0c;作为信息传输 载体的网络设备&#xff0c;其国产化需求迫切&#xff0c;国产处理器、国产可编程逻辑器件、以太网交 换芯片等具有良好的应用前景&#xff0c;另一方面&#xff0c;宽带数据业务…

Java 对象深拷贝

需求 写一个java对象深拷贝工具&#xff0c;用以对象深拷贝。 分析 在 Java 中&#xff0c;变量间值的传递分为两种。对于 int,char,string,等基本数据类型进行值传递时&#xff0c;使用值传递。即原变量 a 的值与新变量 b 的值相等&#xff0c;且 a 与 b 拥有不同的内存地址…

HTML认知

HTML认知 文章目录HTML认知语法规范注释标签组成和关系标签的关系标签学习排版系列标签**标题标签****段落标签**换行标签水平线标签文本格式化标签媒体标签图片标签src 目标图片的路径alt 替换文本title 图片的标题width 宽度 / height 高度路径绝对路径相对路径&#xff08;常…

win10搭建android monkeyrunner自动化测试环境

本文记录一下monkeyrunner环境搭建遇到的各种坑&#xff0c;以免以后再次踩坑。首先要提一下巨坑&#xff0c;务必要安装java 8&#xff08;本文记录于2023.3&#xff09;&#xff0c;安装其他版本java&#xff0c;运行monneyrunner会有很多问题&#xff0c;见第七节。 一、安…

Threejs 教程1

threejs核心概念场景、照相机、对象、光、渲染器等1.1.场景Scene 场景是所有物体的容器&#xff0c;对应着显示生活中的三维世界&#xff0c;所有的可视化对象级相关的动作均发生在场景中。1.2.照相机Camera照相机是三维世界中的观察者&#xff0c;类似与眼睛。为了观察这个世界…

5款软件压力测试工具分享

一、什么是软件压力测试? 软件压力测试是一种基本的质量保证行为&#xff0c;它是每个重要软件测试工作的一部分。软件压力测试的基本思路很简单&#xff1a;不是在常规条件下运行手动或自动测试&#xff0c;而是在计算机数量较少或系统资源匮乏的条件下运行测试。通常要进行…

达梦: DmAPService可以手动开启,但是不能开机自启

在部署生产环境安全版数据库发现&#xff0c;DmAPService服务不能开机自启&#xff0c;这样会导致服务器重启后&#xff0c;部署的定时备份任务不能够成功备份数据。 为了在服务器重启后&#xff0c;不影响定时任务自动备份数据库&#xff0c;现将解决这个问题的办法总结如下&a…