链表的概念+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.hqwc.cn/news/140201.html

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

相关文章

单片机点亮led管(01)

如何开始学习单片机 1&#xff1a;实践第一 2&#xff1a;补充必要的理论知识&#xff0c;缺什么补什么 3&#xff1a;做工程积累经验&#xff08;可以在网络上收集题目&#xff0c;也可以有自己的想法大胆的实验&#xff09; 单片机是什么&#xff1f; 单片机&#xff08…

AI绘画使用Stable Diffusion(SDXL)绘制中国古代神兽

一、引言 说到神奇异兽&#xff0c;脑海中首先就会跳出我国古代神话传说中的各种神兽。比如青龙、白虎、朱雀、玄武&#xff0c;再比如麒麟、凤凰、毕方、饕餮等等&#xff0c;这些都是大家耳熟能详的的神兽。 这些神兽不仅体现了人们丰富的创造力和想象力&#xff0c;更是我…

嵌入式和 Java选哪个?

今日话题&#xff0c;嵌入式和 Java 走哪个?对于嵌入式领域有浓厚兴趣的人&#xff0c;并不会比Java行业薪资低&#xff0c;处于上中游水平。特别是从2020年开始&#xff0c;嵌入式领域受益于芯片产业的兴起&#xff0c;表现出了强劲的增长势头。薪资水平受多方面因素影响。以…

快速实现MQTT协议网关网口连接西门子PLC

MQTT协议网关网口连接西门子SMART200PLC操作说明v1.3 目录 一. 使用流程 二. 准备工作 2.1 需要准备如下物品 2.2 LF220网关准备工 2.3 PLC准备工作 2.4 电脑的准备工作 2.5 MQTT服务器 三. MQTT网关登陆平台配置步骤 3.1 登录 3.2 网关概况 3.3 MQTT连…

专题三:穷举、暴搜、深搜、回溯、剪枝【递归、搜索、回溯】

1、全排列 class Solution { public:vector<vector<int>> ret;vector<int> path;bool check[7];void dfs(vector<int>& nums){if(nums.size() path.size()) {ret.push_back(path);return;}for(int i 0;i < nums.size();i){if(check[i] fals…

接口自动化测试持续集成,Soapui接口功能测试参数化

按照自动化测试分层实现的原理&#xff0c;每一层的脚本实现都要进行参数化&#xff0c;自动化的目标就是要实现脚本代码与测试数据分离。当测试数据进行调整的时候不会对脚本的实现带来震荡&#xff0c;从而提高脚本的稳定性与灵活度&#xff0c;降低脚本的维护成本。Soapui最…

学信息系统项目管理师第4版系列31_信息系统工程

1. 信息系统战略三角突出了业务战略、信息系统和组织机制之间的必要一致性 1.1. 【高23上选07】 2. 软件工程 2.1. 软件工程方法是完成软件工程项目的技术手段&#xff0c;它支持整个软件生命周期 2.2. 软件工程使用的工具是人们在开发软件的活动中智力和体力的扩展与延伸 …

常见的 NoSQL 数据库有哪些?

前言 今天我们来介绍一下工作开发中常见的一些NoSQL数据库及其基本特点。欢迎在评论区留下文章中没有介绍且好用的NOSQL数据库&#x1f91e;。 什么是&#xff08;NOSQL&#xff09;非关系型数据库 非关系型数据库又被称为 NoSQL&#xff08;Not Only SQL )&#xff0c;意为不…

Pika v3.5.1发布!

Pika 社区很高兴宣布&#xff0c;我们今天发布已经过我们生产环境验证 v3.5.1 版本&#xff0c;https://github.com/OpenAtomFoundation/pika/releases/tag/v3.5.1 。 该版本不仅做了很多优化工作&#xff0c;还引入了多项新功能。这些新功能包括 动态关闭 WAL、ReplicationID…

中文编程开发语言工具编程案例:计时计费管理系统软件连接灯控器编程案例

中文编程开发语言工具编程案例&#xff1a;计时计费管理系统软件连接灯控器编程案例 中文编程开发语言工具编程案例&#xff1a;计时计费管理系统软件连接灯控器编程案例 中文编程系统化教程&#xff0c;不需英语基础。学习链接 https://edu.csdn.net/course/detail/39036

清除git历史敏感数据--bfg的应用

项目场景&#xff1a; 开源项目中的git历史中存在敏感 信息&#xff0c;如数据库地址&#xff0c;端口&#xff0c;密码&#xff0c;用户等 我们我们在主分支擦除密码&#xff0c;用户名等&#xff0c;git的历史记录里还是会有相关信息&#xff0c;并不能真正做到清除敏感信息…

黑豹程序员-架构师学习路线图-百科:MySQL

文章目录 1、什么是MySQL2、MySQL受喜爱程度经典四人组&#xff1a; 3、发展历史4、MariaDB 1、什么是MySQL MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 …