【数据结构】链式存储:链表

news2024/11/15 11:20:29

目录

🥇一:初识链表

🎒二、链表的实现(单向不带头非循环)

📘1.创建节点类

📒2.创建链表

📗3.打印链表

📕4.查找是否包含关键字key是否在单链表当中

📙5.得到单链表的长度

📒6.任意位置插入,第一个数据节点为0号下标

📘7.删除第一次出现关键字为key的节点

📗8.删除所有值为key的节点

📕10.清空链表


🥇一:初识链表

📜链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。

 而链表分为单向或双向、带头或不带头、循环或非循环,组合起来就有8种链表结构。

接下来我们会学习:单向不带头非循环链表(笔试、面试都是这个结构)双向不带头非循环链表(集合类底层这样操作)

🎒二、链表的实现(单向不带头非循环

📘1.创建节点类

🌈节点由val域(数据域),以及next域(指针域)组成,对于next域,其是引用类型,存放下一个节点的地址。

class Node {
    public int val;//存储的数据
    public Node next;//存储下一个结点的地址

    //构造函数
    public Node(int val) {
        this.val = val;
    }
    
    public Node head;//代表当前链表的节点的引用
}

📒2.创建链表

1️⃣直接进行val的赋值以及对next的初始化

注意:不用对最后一个节点的next进行赋值,因为next是引用类型,不赋值则默认为null。

    //创建列表
    public void createLink() {
        Node node1 = new Node(10);
        Node node2 = new Node(15);
        Node node3 = new Node(8);
        Node node4 = new Node(9);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        head = node1;
    }

2️⃣头插法:头插法是指在链表的头节点的位置插入一个新节点,定义一个node表示该节点,然后就是对node的next进行赋值

    //头插法
    public void addFirst(int data){
            Node node = new Node(data);
            node.next = head;
            head = node;
    }

3️⃣尾插法:尾插法是指在链表的尾节点的位置插入一个新节点,定义一个node表示该节点,然后就是对原来最后一个节点的next进行赋值。需要注意的是,如果没有链表,即cur == null;此时第一个链表就等于插入的新节点,即head = node;

    //尾插法
    public void addLast(int data){
        Node node = new Node(data);
        Node cur = head;
        if(cur == null) {
            head = node;
            return;
        }
        while(cur.next != null) {
            cur = cur.next;
        }
        cur.next = node;
    }

📗3.打印链表

➡️为了使head一直存在且有意义,我们在display()函数中定义一个cur:Node cur = head;来替代head。

在遍历列表时要注意:

如果说把整个链表 遍历完成,那么就需要 head == null;如果说你遍历到链表的尾巴 head.next == null

    //遍历列表
    public void display() {
        //如果说 把整个链表 遍历完成 那么 就需要 head == null
        //如果说 你遍历到链表的尾巴 head.next == null
        Node cur = head;
        while(head != null) {
            System.out.print(head.val + " ");
            cur = cur.next;
        }
        System.out.println();
    }

📕4.查找是否包含关键字key是否在单链表当中

    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        Node cur = head;
        while(cur != null) {
            if (cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

📙5.得到单链表的长度

    //得到单链表的长度
    public int size(){
        int count = 0;
        Node cur = head;
        while(cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

📒6.任意位置插入,第一个数据节点为0号下标

1️⃣首先,在头部插入一个节点——头插法;2️⃣在最后一个位置插入——尾插法

3️⃣在中间位置插入,如图所示:

    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data) throws ListIndexOutOfExpectionn{
        checkIndex(index);
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        Node cur = findIndexSubOne(index);
        Node node = new Node(data);
        node.next = cur.next;
        cur.next = node;
    }

    /**
     * 找到 index-1 位置的节点的地址
     * @param index
     */
    private Node findIndexSubOne(int index) {
        Node cur = head;
        int count = 0;
        while(count != index-1) {
            cur = cur.next;
            count++;
        }
        return cur;
    }

    private void checkIndex(int index) {
        if(index < 0 || index > size()) {
            throw new ListIndexOutOfExpectionn("index位置不合法");
        }
    }

📘7.删除第一次出现关键字为key的节点

🔑当删除的节点为head的时候,此时head = head.next,即只有一个节点删除;

🔑当删除的节点不是head的时候,我们需要找到关键字key的前一个节点:1️⃣前一个节点为null,返回null,即一个节点都没有2️⃣cur.next == null 以后,说明到了最后一个节点3️⃣cur.next != null的时候,找前驱节点:cur.next.val == key

    //删除第一次出现关键字为key的节点
    public void remove(int key){
        if (head.val == key) {
            head = head.next;
            return;
        }
        Node cur = searchPrev(key);
        if (cur == null) {
            return;
        }
        Node del = cur.next;//需要删除的节点
        cur.next = del.next;//cur.next = cur.next.next同样的道理

    }

    /**
     * 找到关键字key的前一个节点
     * @param key
     */
    private Node searchPrev(int key) {
        if (head == null) {
            return null;//一个节点都没有
        }
        Node cur = head;
        while (cur.next != null) {//cur.next == null 以后,说明到了最后一个节点
            if (cur.next.val == key) {//cur将来是key的前驱节点
                return cur;
            }
            cur = cur.next;
        }
        return null;//没有你要删除的节点
    }

📗8.删除所有值为key的节点

    //删除所有值为key的节点
    public void removeAllKey(int key){
         if(head == null) {
             return;
         }
         Node prev = head;
         Node cur = head.next;
         while (cur != null) {
             if(cur.val == key) {
                 prev.next = cur.next;
                 cur = cur.next;
             }else {
                 prev = cur;
                 cur = cur.next;
             }
         }
         if(head.val == key) {
             head = head.next;
         }
    }

📕10.清空链表

    /**
     * 保证链表 当中,所有的节点都可以被回收
     */
    public void clear() {
        head = null;
    }

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

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

相关文章

Webpack核心概念

1. 核⼼概念 Entry Entry ⽤来指定 webpack 的打包⼊⼝。 依赖图的⼊⼝是 entry&#xff0c;对于⾮代码⽐如图⽚、字体依赖也会不断加⼊到依赖图中。 Entry 的⽤法&#xff1a; 1. 单⼊⼝&#xff1a;entry 是⼀个字符串&#xff1b; module.exports {entry: ./path/to/my…

若依框架-补充篇:Vuex全局状态管理Axios二次封装

在上一篇《若依框架&#xff1a;前端登录组件与图像验证码|用户登录逻辑》中的篇末&#xff0c;对Vuex全局状态管理、Axios二次封装部分介绍的较为粗略&#xff0c;因此就有了这个补充篇。 目录 Vuex全局状态管理 Vuex是什么&#xff1f; 如何理解“状态管理模式”&#xf…

【Java语法】之String类练习1

目录 1.字符串中的第一个唯一字符 2. 最后一个单词的长度 58. 最后一个单词的长度 3.验证回文串 4.字符串相加 5.小结&#xff1a; 1.字符串中的第一个唯一字符387. 字符串中的第一个唯一字符https://leetcode.cn/problems/first-unique-character-in-a-string/ 给定一个字符…

【免费开放源码】审批类小程序项目实战(活动申请详解)

第一节&#xff1a;什么构成了微信小程序、创建一个自己的小程序 第二节&#xff1a;微信开发者工具使用教程 第三节&#xff1a;深入了解并掌握小程序核心组件 第四节&#xff1a;初始化云函数和数据库 第五节&#xff1a;云数据库的增删改查 第六节&#xff1a;项目大纲以及制…

Mac下安装go

1.下载地址 ​​​​​​https://golang.google.cn/dl/ 2.安装Go 3.查看安装效果 go version go env 4.安装vscode和插件 4.1.安装vscode https://code.visualstudio.com/Download 4.2.安装GO插件 4.3.设置goproxy 执行命令&#xff1a;vim ~/.bash_profile export GO1…

数值分布的分散程度对迭代次数的影响

( A, B )---1*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有1个节点&#xff0c;AB各由7张二值化的图片组成&#xff0c;排列组合A和B的所有可能性&#xff0c;固定收敛误差为7e-4&#xff0c;统计收敛迭代次数 1 2 3 4 5 6 7 迭代次数 1b 1b 1b 1b 1b 1b 0 0*0*0…

PHP---文件上传

目录 一、文件上传的概念 二、文件上传的步骤 &#xff08;1&#xff09;表单的制作 三、$_FILES详解 &#xff08;1&#xff09;name &#xff08;2&#xff09;tmp_name &#xff08;3&#xff09;type &#xff08;4&#xff09;error &#xff08;5&#xff09;si…

YOLO v6:一个硬件友好的目标检测算法

本文来自公众号“AI大道理” YOLOv6 是美团视觉智能部研发的一款目标检测框架&#xff0c;致力于工业应用。 YOLOv6支持模型训练、推理及多平台部署等全链条的工业应用需求&#xff0c;并在网络结构、训练策略等算法层面进行了多项改进和优化&#xff0c;在 COCO 数据集上&…

一文轻松明白 Base64 编码原理

把图片丢进浏览器&#xff0c;打开sources能看到一长串字符串&#xff0c;这是图片的Base64编码。这一长串编码到底是怎么生成的呢&#xff1f; 我们接下来探索一下base64编码的原理 Base64 名称的由来 Base64编码要求把3个8位的字节&#xff08;3824&#xff09;转化为4个6…

C++代码编程学习(2):类和对象封装部分的两个案例-立方体与点圆位置

C类与对象 封装的学习 挺有趣的&#xff01; 一、前言 昨日有点事忙了些&#xff0c;今天把昨天学习的两个案例给整理一下&#xff0c;C确实比较原始基础&#xff0c;在学习过程中需要好好总结分析与记录。 二、效果展示 案例一&#xff1a;设计立方体 立方体的面积和体积 用…

阿里微服务质量保障系列(一):微服务知多少

年初买了一本集团巨佬联合出的书《阿里测试之道》&#xff0c;然后认真拜读了下&#xff0c;我相信看过的同学都会获益匪浅&#xff0c;此书分享了阿里在大促保障、移动App测试、大数据测试、AI系统测试、云计算测试、资损防控、物流类测试等领域的方法、技术和工具平台&#x…

十一、Properties、多线程

Properties集合 Properties作为Map集合的使用 介绍 是一个Map体系的集合类Properties可以保存到流中或从流中加载属性列表中的每个键及其对应的值都是一个字符串 基本使用 public static void main(String[] args) {Properties prop new Properties();//增prop.put("…

Pytorch c++ 部署报错解决方案

目录 1. Only the versions between 2017 and 2019 (inclusive) are supported! 2. Cannot find cuDNN library. Turning the option off C 部署的时候&#xff0c;demo 写完之后&#xff0c;提示如下错误 1. Only the versions between 2017 and 2019 (inclusive) are sup…

使用Kubernetes部署xxl-job-admin及xxl-job执行器服务

部署环境 xxl-job-2.4.0kubernetes-1.26 这里以xxl-job官方的2.4.0的代码为例子&#xff0c;在官方编写的Dockerfile基础上使用dockerkubernetes进行部署&#xff0c;xxl-job-admin和执行器的Dockerfile、application等配置文件并不是关键&#xff0c;所以这里示例安装以官方…

Linux系统初始化进程及文件(带命令)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.系统初始化进程及文件 1.init 进程 2.Systemd概述 3.SysVi…

【Java语言】— 循环结构 :for循环

循环结构&#xff1a;for循环 1.for循环 控制一段代码反复执行很多次。 for循环的格式如下&#xff1a; for (初始化语句;循环条件;迭代语句){循环体语句(重复执行的代码);}下面我们通过案例&#xff1a;输出3次HelloWorld感受一下。 //需求&#xff1a;输出3次HelloWorld…

OpenOCD 不同仿真器使用操作总结记录

针对不同的仿真器使用 OpenOCD 时候的设置操作总结 ...... 矜辰所致目录前言一、OpenOCD 环境搭建二、OpenOCD 基本测试三、Makefile 中仿真器配置3.1 ST-link3.2 Jlink3.2 CMSIS-DAP&#xff08;待更新&#xff09;结语前言 在使用 GCC 环境开发 ARM 系列芯片的时候&#x…

ArcGIS基础实验操作100例--实验35等高线生成DEM

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验35 等高线生成DEM 目录 一、实验背景 二、实验数据 三、实验步骤 方法一 &#xff…

4.5、静态路由配置及其可能产生的路由环路问题

静态路由配置是指用户或网络管理员使用路由器的相关命令给路由器人工配置路由表\color{red}人工配置路由表人工配置路由表。 这种人工配置方式简单、开销小。但不能及时适应网络状态&#xff08;流量、拓扑等&#xff09;的变化。\color{red}但不能及时适应网络状态&#xff08…

我的世界Bukkit服务器插件开发教程(十三)资源包与玩家资料

十三、资源包与玩家资料 1.资源包&#xff08;Resource Pack&#xff09; 早期的 Minecraft 并没有资源包一说&#xff0c;而是被叫做材质包。有些服务器为了让玩家拥有更好的游戏体验&#xff0c;一般会在自己特制的客户端中存放一些资源包供玩家加载。 显然&#xff0c;使用…