链表的概念+MySingleList的实现

文章目录

  • 链表
    • 一、 链表的概念
      • 1.概念
      • 2. 结构
    • 二、MySingleList的实现
      • 1 .定义内部类
      • 2 .创建链表
      • 3. 遍历链表并打印
      • 4.查找单链表中是否包含关键字key
      • 5.得到链表的长度
      • 6.头插法
      • 7. 尾插法
      • 8.任意位置插入
      • 8.删除结点
          • 清空


链表

顺序存储:顺序表/ArrayList

  • 优点:给定下标的时候,查找速度快 o(1)
  • 缺点:插入和删除时要移动元素o(n) 、每次扩容会浪费资源

由于ArrayList的缺点,我们引入链式存储:链表

一、 链表的概念

1.概念

在这里插入图片描述

  • 链表在物理层面是非连续的存储结构,在逻辑上是连续的,通过引用链接次序来实现它的逻辑顺序
  • 链表由一个个结点组成,结点从堆上申请
  • 一个结点起码包含两个域,val域存储数组、next域存储下一个结点的地址

2. 结构

链表由多种结构:由头、无头、单向、双向、循环、非循环
排列组合后有八种,重点了解无头单向非循环链表和无头双向链表

二、MySingleList的实现

无头单向非循环链表的实现

1 .定义内部类

public class MySingleList {//链表是由一个一个的结点所组成的,可以把Node定义成一个内部类static class Node {public int val;//存储的数据public Node next;//存储下一个结点的地址public Node(int val) {//先不设置next,创建一个新的结点时,还不知道下一个结点是什么this.val = val;}}
}

链表是由一个个的结点所组成的,可以把Node定义成一个内部类

  • 定义一个val变量存储数据
  • 定义一个Node类型的next变量存储下一个结点的地址
  public Node head;//代表当前链表的头结点的引用

head 代表当前链表的头结点的引用

  • 因为现在写的是不带头结点的单链表,通过一个变量head,来引用当前链表的头结点
  • head引用哪个结点,哪个就是当前链表的头结点

2 .创建链表

public void creatList(){//创建一个链表Node node1 = new Node(12);Node node2 = new Node(86);Node node3 = new Node(33);Node node4 = new Node(45);node1.next =node2;node2.next =node3;node3.next =node4;head=node1;//创建头结点}

创建各个结点,给定val值,每个结点的next依次引用下一个结点的地址
确定头结点,head引用node1所引用的地址

在这里插入图片描述

3. 遍历链表并打印

public void disPlay() {//不要改变headNode cur = head;//定义一个cur,让cur移动,head不动//链表遍历完,head==null//遍历到尾部,不打印最后一个,head.next==nullwhile (cur!=null){System.out.print(cur.val+" ");cur = cur.next;}System.out.println();}

1.通过cur来代替head,保证head不会发生改变
2.循环的判断依据是cur!=null,这样能遍历完整
cur.next!=null会少打印最后一个

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

public boolean contains(int key) {Node cur = head;while (cur != null) {//当cur为空时,遍历完if (cur.val == key) {return true;}cur = cur.next;//cur向后移动}return false;}

5.得到链表的长度

 public int size(){int count = 0;Node cur = head;while (cur!=null) {//遍历一遍链表 o(n)count++;cur=cur.next;}return count ;}

遍历数组,直到cur为null跳出循环,说明已经走完整个链表,返回记录的次数

6.头插法

在这里插入图片描述

 public void addFirst(int data){Node node = new Node(data);//新建一个结点node.next=head;head = node;}

1.创建新的结点
2.将新结点的next域存放原本头结点的地址值
3.让新结点成为新的头结点
这样就完成了头插法的实现

7. 尾插法

在这里插入图片描述

 public void addList(int data) {Node node = new Node(data);if (head == null) {//判断头结点为空的情况head = node;//让新建的结点成为头节点return;//}Node cur = head;//让cur代替headwhile (cur.next != null) {cur = cur.next;}//当cur的next为null时,找到了最后一个结点//找到最后一个结点后,插入node结点cur.next = node;}

1.创建一个新结点
2.判断头结点是否为空
3.遍历链表找到当前最后一个结点
4.将新结点插到末尾
链表的插入只是修改指向

8.任意位置插入

在这里插入图片描述

public void addIndex(int index, int data) throws IndexOutOfException {checkIndex(index);//先检查index的值是否合法if (index == 0) {//如果index=0,调用头插法addFirst(data);return;}if (index == size()) {//如果index的值为链表长度,调用尾插法addList(data);return;}Node cur = findIndexSubOne(index);//找到index的前一个元素Node node = new Node(data);node.next = cur.next;cur.next = node;}private void checkIndex(int index) {if (index < 0 || index > size()) {throw new IndexOutOfException("index位置不合法");}}//走index-1步,返回当前索引的地址private Node findIndexSubOne(int index) {Node cur = head;int count = 0;while (count != index - 1) {cur = cur.next;count++;}return cur;}

1.调用checkIndex方法先检查index的值是否合法,不合法抛出异常
2.判断索引,如果是0,调用头插法,如果等于链表长,调用尾插法
3.调用findIndexSubOne方法,找到index的前一个节点,返回地址值
4.创建一个新结点,使新结点的next域的值等于前一个结点next域的值
5.再让前一个结点的next域,引用新结点的地址值。

8.删除结点

删除第一次出现关键字为key的结点
在这里插入图片描述

 public void remove(int key) {if (head == null) {//判断是否是空节点return; //一个结点都没有}if (head.val == key) {//如果当前头结点的元素等于要删除的元素head = head.next;//头结点向后移动return;}Node cur = searchPrev(key);//找到key的前驱结点if (cur == null) {//没有要删除的keyreturn;}Node del = cur.next;//要删除的结点cur.next = del.next;//or cur.next = cur.next.next;}private Node searchPrev(int key) {//找到key的前一个结点Node cur = head;while (cur.next != null) { //cur.next==null,说明cur已经走到最后一个结点if (cur.next.val == key) {//如果cur下一个结点的值等于keyreturn cur;//找到key的前一个结点}cur = cur.next;}return null;//没有你要删除的结点}

1.先定义searchPrev方法,遍历链表,如果cur的下一个结点的值=key,cur就为key的前驱结点
2.判断:如果头结点为空,链表中没有元素,直接返回
3.如果头结点的值,就是要删除的元素,头结点后移,直接返回
4.都不是,进入searchPrev方法,返回前驱结点cur;
5.如果返回的cur==null,说明遍历完链表,没有要删除的元素
6.要删除的结点del就是cur的下一个结点
7.让cur结点的next域引用del的下一个结点的地址;
完成删除

删除所有值为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;}cur = cur.next;}if (head.val == key) {//最后处理头结点//如果头结点的值等于key,头结点后移head = head.next;}}

1.判断头结点是否为空
2.设置prev为头结点,cur为下一个结点(头结点key的情况最后考虑)
3.遍历链表,直到cur==null为止
4.如果cur的值等于key,prev的next域引用cur下一个结点的地址,cur后移一位
5.否则,prev移动到cur,cur后移一位
6.最后处理头结点,如果头结点刚好等于key,将头结点后移一位。

清空
   public void clear(){//清空,让链表中所有的结点都不被引用head =null;}

清空,让链表中所有的结点都不被引用,head置为空

点击移步博客主页,欢迎光临~

偷cyk的图

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

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

相关文章

【数据库范式】实际案例分析

前言 在日常业务研发过程中&#xff0c;我们常常需要与数据库表打交道。设计范式是数据表设计的基本原则&#xff0c;对于数据表的设计范式&#xff0c;我们特别容易忽略它的存在。很多时候&#xff0c;当数据库运行了一段时间之后&#xff0c;我们才发现数据表设计上有问题。然…

linux常见命令-文件目录类

9.4 文件目录类 &#xff08;1&#xff09;pwd 指令:显示当前工作目录的绝对路径 &#xff08;2&#xff09;Is指令:查看当前目录的所有内容信息 基本语法&#xff1a; ls [选项,可选多个] [目录或是文件] 常用选项:-a:显示当前目录所有的文件和目录&#xff0c;包括隐藏的…

钢铁异常分类 few-shot 问题 小陈读paper 钢铁2

很清爽的 abstract 给出链接 前面的背景意义 其实 是通用的 这里替大家 整理一吓吓 1 缺陷分类在钢铁表面缺陷检测中 有 意义。 2 大多数缺陷分类模型都是基于完全监督的学习&#xff0c; 这需要大量带有图像标签的训练数据。 在工业场景中收集有缺陷的图像是非常困难…

C++入门(c++历史篇)

&#x1f4d9; 作者简介 &#xff1a;RO-BERRY &#x1f4d7; 学习方向&#xff1a;致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f4d2; 日后方向 : 偏向于CPP开发以及大数据方向&#xff0c;欢迎各位关注&#xff0c;谢谢各位的支持 重点 1. 什么是C2. C的发展…

RTOS(6)任务管理

任务状态理论 我们是怎么实现&#xff0c;两个同优先级的任务之间交替执行的呢&#xff1f; 任务切换的基础&#xff1a;tick中断&#xff01; tick为1ms一个周期&#xff0c;可以通过修改时钟配置修改&#xff1b; running&#xff1a;正在进行的任务3为running&#xff…

`SQL`编写判断是否为工作日函数编写

SQL编写判断是否为工作日函数编写 最近的自己在写一些功能,遇到了对于工作日的判断,我就看了看sql,来吧!~(最近就是好疲惫) 我们一起看看(针对ORACLE) 1.声明: CREATE OR REPLACE PACKAGE GZYW_2109_1214.PKG_FUN_GETDAY_HDAY AS /** * 通过节假日代码获取指定的日期[查找基…

drawio简介以及下载安装

drawio简介以及下载安装 drawio是一款非常强大的开源在线的流程图编辑器&#xff0c;支持绘制各种形式的图表&#xff0c;提供了 Web端与客户端支持&#xff0c;同时也支持多种资源类型的导出。 访问网址&#xff1a;draw.io或者直接使用app.diagrams.net直接打开可以使用在线版…

STM32 裸机编程 03

MCU 启动和向量表 当 STM32F429 MCU 启动时&#xff0c;它会从 flash 存储区最前面的位置读取一个叫作“向量表”的东西。“向量表”的概念所有 ARM MCU 都通用&#xff0c;它是一个包含 32 位中断处理程序地址的数组。对于所有 ARM MCU&#xff0c;向量表前 16 个地址由 ARM …

VSCode搭建ESP32 ESP-IDF开发环境-Windows

陈拓 2023/10/09-2023/10/14 1. 安装Windows系统下的ESP32 ESP-IDF开发环境 见《Windows系统安装ESP32 ESP-IDF开发环境》 Windows系统安装ESP32 ESP-IDF开发环境-CSDN博客Windows系统安装ESP32 ESP-IDF开发环境。https://blog.csdn.net/chentuo2000/article/details/1339225…

迅为RK3588开发板使用RKNN-Toolkit-lite2运行测试程序

1 首先也需要部署运行环境&#xff0c;将库文件放入 RK3588 开发板上&#xff0c;我们将网盘资料“iTOP-3588 开发 板 \02_ 【 iTOP-RK3588 开 发 板 】 开 发 资 料 \12_NPU 使 用 配 套 资 料 \05_Linux_librknn_api\librknn_api\aarch64”路径下的文件通过U盘拷贝到开发板的…

AI AIgents时代-(五.)Autogen

由微软开发的 Autogen 是一个新的 Agents 项目&#xff0c;刚一上线就登上GitHub热榜&#xff0c;狂揽11k星✨✨✨ 项目地址&#xff1a;https://github.com/microsoft/autogen Autogen 允许你根据需要创建任意数量的Agents&#xff0c;并让它们协同工作以执行任务。它的独特之…

stable-diffusion-webui sdxl模型代码分析

采样器这块基本都是用的k-diffusion&#xff0c;模型用的是stability的原生项目generative-models中的sgm&#xff0c;这点和fooocus不同&#xff0c;fooocus底层依赖comfyui中的models&#xff0c;comfy是用load_state_dict的方式解析的&#xff0c;用的load_checkpoint_guess…

实时精准 自我防护 | 开源网安RASP平台能力获客户认可!

近日&#xff0c;开源网安收到了一封来自华润数科的感谢信&#xff0c;表达了对开源网安团队在网络安全工作中给予大力支持的衷心感谢。开源网安十分注重客户的需求和信任&#xff0c;客户的满意和认可是开源网安最大的追求。 在助力华润数科网络安全工作开展过程中&#xff0c…

nextjs-一个基于React的全栈框架

一、nextjs基本介绍 Next.js是一个基于React的轻量级框架&#xff0c;用于构建React应用程序。它在React的基础上提供了一些增强功能&#xff0c;包括服务器渲染&#xff08;SSR&#xff09;、静态生成&#xff08;SSG&#xff09;、路由等。Next.js的目标是简化React应用程序…

十八、字符串(1)

本章概要 字符串的不可变 的重载与 StringBuilder 意外递归字符串操作 字符串操作毫无疑问是计算机程序设计中最常见的行为之一。 在 Java 大展拳脚的 Web 系统中更是如此。在本章中&#xff0c;我们将深入学习在 Java 语言中应用最广泛的 String 类&#xff0c;并研究与之相关…

pymysql连接Mariadb/Mysql出现错误(配置正确情况下)解决办法

场景&#xff1a;在kali中使用python中pymysql对Mariadb进行连接&#xff0c;在整个过程中配置全部正确&#xff0c;但是就是无法进行连接&#xff0c;提示结果如下&#xff1a; Access denied for user rootlocalhost解决办法&#xff1a;进入数据库中&#xff0c;将默认密码…

实验室烧杯可以用超声波清洗机吗

实验室烧杯可以用超声波清洗机吗&#xff1f;答案是可以的&#xff01;超声波清洗机不仅可以清洗实验烧杯&#xff0c;还可以用于清洗实验室中的试管、培养皿、移液管、载玻片、容量瓶、锥形瓶等各类实验器皿。在实验中&#xff0c;如果烧杯清洁不到位&#xff0c;会使得实验数…

分布式存储 vs. 全闪集中式存储:金融数据仓库场景下的性能对比

作者&#xff1a;深耕行业的 SmartX 金融团队 张德敏 近年来随着金融行业的高速发展&#xff0c;经营决策者及监管机构对信息时效性的要求越来越高&#xff0c;科技部门面临诸多挑战。例如&#xff0c;不少金融机构使用数仓业务系统&#xff0c;为公司高层提供日常经营报表&am…

CSV文件新增数据知多少

CSV文件编辑数据时 一、如果数据的长度不超过11位&#xff0c;直接正常输入 二、如果数据的长度大于等于11位&#xff0c;新增数据时&#xff0c;将列格式改为文本&#xff0c;并且输入数字&#xff0c;数字使用文本格式保存 如果数字长度超过11位&#xff0c;则展示为E科学…

seq“ 和 “time“ 字段

在RTP&#xff08;Real-time Transport Protocol&#xff09;报文中&#xff0c;"seq" 和 "time" 字段分别表示以下内容&#xff1a; 1. **Seq&#xff08;Sequence Number&#xff09;字段**&#xff1a;Seq字段是RTP头部中的一个16位字段&#xff0c;用…