当前位置: 首页 > news >正文

Java中的链表实现介绍

Java中的链表实现介绍

学习数据结构的的链表和树时,会遇到节点(node)和链表(linked list)这两个术语,节点是处理数据结构的链表和树的基础。节点是一种数据元素,包括两个部分:一个是实际需要用到的数据;另一个存储下一个节点位置【用数据结构中的术语,称为数据域(Data field) 与 指针域(pointer field)】。链表是一系列节点串联形成的数据结构,链表中的元素在内存中并不是连续的。

链表存储有序的元素集合,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。因此链表增删非首尾元素时不需要移动元素,只需要更改next的指向即可。

本文仅以单链表为例介绍。

单链表只有一个指向其他节点的变量,也就是在这种类型的数据结构中,任何两个数据元素之间只有一个链接,参见下图:

链表的操作包括了创建、删除、插入、输出等。

创建就是空间的分配,将头、尾指针及链表结点个数等初始化。删除和插入根据被操作元素的位置可以细分为头删除(插入),尾删除(插入),中间删除(插入)。

插入操作

头插入实际上是增加一个新节点,然后把新增加的结点指针指向原来头指针指向的元素,再把头指针指向新增的节点。

尾插入也是增加一个新节点,该节点指针置为null,然后把原尾结点指针指向新增加的节点,最后把尾指针指向新增加的节点即可。

中间插入稍复杂,首先增加一个节点,然后新增节点的指针指向插入位置的后一个节点,把插入位置的前一个节点指针指向新插入节点即可。

删除操作

删除头元素时,先将头指针指向下一个节点,然后把原头结点的指针置空即可。

删除尾元素时,首先找到链表倒数第2个元素,然后把尾指针指向这个元素,接着把原倒数第2个元素的指针置空。

删除中间元素相对复杂一些,首先将要删除的节点的前一个节点指针指向要删除的节点的下一个节点,然后把要删除节点的指针置空。

上面提到是单链表最基本的操作,除此之外还有其它操作不多说了。下面给出代码示例。

下面介绍两种实现方式。

一、使用Java.util 包的LinkedList类实现

JAVA提供的LinkedList类简要介绍

JAVA提供的LinkedList类,它也可以被当作堆栈、队列或双端队列进行操作。

LinkedList 实现 List 接口,能进行列表的相关操作。

LinkedList 实现了 Queue 接口,可作为队列使用。

LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。

LinkedList官方文档LinkedList (Java Platform SE 8 )

LinkedList 类位于 java.util 包中,使用前需要引入它,语法格式如下:

import java.util.LinkedList;

常用的方法(Method)及说明

public boolean add(E e)

链表末尾添加元素,返回是否成功,成功为 true,失败为 false。

public void add(int index, E element)

向指定位置插入元素。

public boolean addAll(Collection c)

将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。

public boolean addAll(int index, Collection c)

将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。

public void addFirst(E e)

元素添加到头部。

public void addLast(E e)

元素添加到尾部。

public boolean offer(E e)

向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。

public boolean offerFirst(E e)

头部插入元素,返回是否成功,成功为 true,失败为 false。

public boolean offerLast(E e)

尾部插入元素,返回是否成功,成功为 true,失败为 false。

public void clear()

清空链表。

public E removeFirst()

删除并返回第一个元素。

public E removeLast()

删除并返回最后一个元素。

public boolean remove(Object o)

删除某一元素,返回是否成功,成功为 true,失败为 false。

public E remove(int index)

删除指定位置的元素。

public E poll()

删除并返回第一个元素。

public E remove()

删除并返回第一个元素。

public boolean contains(Object o)

判断是否含有某一元素。

public E get(int index)

返回指定位置的元素。

public E getFirst()

返回第一个元素。

public E getLast()

返回最后一个元素。

public int indexOf(Object o)

查找指定元素从前往后第一次出现的索引。

public int lastIndexOf(Object o)

查找指定元素最后一次出现的索引。

public E peek()

返回第一个元素。

public E element()

返回第一个元素。

public E peekFirst()

返回头部元素。

public E peekLast()

返回尾部元素。

public E set(int index, E element)

设置指定位置的元素。

public Object clone()

克隆该列表。

public Iterator descendingIterator()

返回倒序迭代器。

public int size()

返回链表元素个数。

public ListIterator listIterator(int index)

返回从指定位置开始到末尾的迭代器。

public Object[] toArray()

返回一个由链表元素组成的数组。

public T[] toArray(T[] a)

返回一个由链表元素转换类型而成的数组。

 

JAVA提供的LinkedList类使用示例(来源https://www.cnblogs.com/jbclown/p/16024181.html ),源码如下:

import java.util.LinkedList; // 引入 LinkedList 类
public class LinkedListTest {public static void main(String[] args) {//引入LinkedList类LinkedList<String> lList = new LinkedList<String>();//添加元素lList.add("hello");lList.add("world");lList.add("java");lList.add("LinkedList");//链表元素个数System.out.println(lList.size());//getFirst()方法获取头部元素System.out.println(lList.getFirst()); //hello//addFirst() 在头部添加元素lList.addFirst("the");  //[the, hello, world, java, LinkedList]System.out.println(lList);//addLast() 在尾部添加元素lList.addLast("ArrayList"); //[the, hello, world, java, LinkedList, ArrayList]System.out.println(lList);// removeFirst() 移除头部元素lList.removeFirst();  // [hello, world, java, LinkedList, ArrayList]// set(int index, E element) 指定元素替换指定位置的元素lList.set(1,"the"); //[hello, the, java, LinkedList, ArrayList]System.out.println(lList);// add( int index,E element) 指定位置插入元素lList.add(2,"world"); //[hello, the, world, java, LinkedList, ArrayList]System.out.println(lList);// for-each 迭代元素System.out.println("for-each 迭代元素:");for (String s : lList){System.out.println(s);}}
}

输出:

4
hello
[the, hello, world, java, LinkedList]
[the, hello, world, java, LinkedList, ArrayList]
[hello, the, java, LinkedList, ArrayList]
[hello, the, world, java, LinkedList, ArrayList]
for-each 迭代元素:
hello
the
world
java
LinkedList
ArrayList

 

二、自定义实现类实现

我们也可以自定义实现类似功能,请看下面的介绍。

Java单向链表的代码实现(java单向链表的模拟实现_java模拟单向链表_忆兮513的博客-CSDN博客 )

由链表类MyList、测试类main和异常类IndexOutOfException组成

链表类MyList源码:

public class MyList {public static class ListNode{int val;public ListNode next;public ListNode(int val){this.val=val;}};public ListNode head;public void createList(){ListNode ListNode1=new ListNode(45);ListNode ListNode2=new ListNode(35);ListNode ListNode3=new ListNode(55);ListNode ListNode4=new ListNode(34);ListNode1.next=ListNode2;ListNode2.next=ListNode3;ListNode3.next=ListNode4;ListNode4.next=null;this.head=ListNode1;}public void display(){/*** 这样会把head弄成空*//*while(head!=null){System.out.print(head.val+" ");head=head.next;}*/ListNode cur=head;while(cur!=null){System.out.print(cur.val+" ");cur=cur.next;}        }//头插法public void addFirst(int data) {ListNode node=new ListNode(data);node.next=head;head=node; }//尾插法public void addLast(int data) {ListNode node = new ListNode(data);if (head == null) {head = node;} else {ListNode cur = head;while (cur.next != null) {cur = cur.next;}cur.next = node;}}//检查index是否合法private void checkindex(int index){if(index<0||index>size()){throw new IndexOutOfException("位置不合法,请重新输入:");}}//找到index-1位置的节点private ListNode FindIndexNode(int index){ListNode cur=head;while (index-1!=0){cur=cur.next;index--;}return cur;}//任意位置插入,第一个数据节点为0号下标public void addIndex(int index,int data){checkindex(index);if(index==0){addFirst(data);return;}else if(index==size()){addLast(data);return;}else {ListNode node = new ListNode(data);ListNode cur=FindIndexNode(index);node.next=cur.next;cur.next=node;}}//查找是否包含关键字key是否在单链表当中public boolean contains(int key){ListNode cur=this.head;while(cur!=null){if(cur.val==key){return true;}cur=cur.next;}return false;}//删除第一次出现关键字为key的节点public void remove(int key){ListNode cur=head;while (cur.next!=null) {if (cur.next.val == key) {cur.next = cur.next.next;return;}cur=cur.next;}}//删除所有值为key的节点public void removeAllKey(int key){ListNode cur=head.next;ListNode pre=head;while(cur!=null){if(cur.val==key){pre.next=cur.next;cur=cur.next;}else{pre=cur;cur=cur.next;}}if(head.val==key){head=head.next;}}//得到单链表的长度public int size(){int count=0;ListNode cur=head;while(cur!=null){cur=cur.next;count++;}return count;}public void clear(){ListNode cur=head;ListNode curNext=null;while(cur!=null){curNext=cur.next;cur.next=null;cur=curNext;}head=null;}}

异常类IndexOutOfException源码:

public class IndexOutOfException extends RuntimeException{public IndexOutOfException(){}public IndexOutOfException(String mes){super(mes);}
}

 测试类main源码:

public class main {public static void main(String[] args) {MyList list=new MyList();list.createList();list.display();System.out.println(list.contains(45));System.out.println(list.size());list.addFirst(99);list.display();System.out.println();//换行list.addLast(999);list.display();System.out.println();list.addIndex(1,50);list.display();System.out.println();list.removeAllKey(45);list.display();list.clear();list.display();}
}

运行结果:

45 35 55 34 true
4
99 45 35 55 34 
99 45 35 55 34 999 
99 50 45 35 55 34 999 
99 50 35 55 34 999

 

相关文章:

Java中的链表实现介绍

Java中的链表实现介绍 学习数据结构的的链表和树时&#xff0c;会遇到节点&#xff08;node&#xff09;和链表&#xff08;linked list&#xff09;这两个术语&#xff0c;节点是处理数据结构的链表和树的基础。节点是一种数据元素&#xff0c;包括两个部分&#xff1a;一个是…...

演示Ansible中的角色使用方法(ansible roles)

文章目录一、ansible 角色简介二、roles目录结构三、role存放的路径&#xff1a;配置文件ansible.cfg中定义四、创建目录结构五、playbook中使用rolesplaybook变量会覆盖roles中的定义变量六、控制任务执行顺序七、ansible—galaxy命令工具八、安装选择的角色1.从网上下载&…...

Bash Shell 通过ls命令筛选文件

Bash Shell 通过ls命令及其管道根据大小名称筛选文件 最近参与的项目当中有需要用pyarmor加密项目的要求&#xff0c;听网上吹的pyarmor都那么神&#xff0c;用了一下感觉也一般&#xff0c;试用版普通模式下文件加密居然还有大小32KB的限制&#xff0c;加密到一半就失败了&am…...

2023-2-18 刷题情况

删列造序 III 题目描述 给定由 n 个小写字母字符串组成的数组 strs &#xff0c;其中每个字符串长度相等。 选取一个删除索引序列&#xff0c;对于 strs 中的每个字符串&#xff0c;删除对应每个索引处的字符。 比如&#xff0c;有 strs [“abcdef”,“uvwxyz”] &#xf…...

【Linux】进程控制

文章目录进程创建简单认识一下fork()函数为什么fork()会有两个返回值fork通过写时拷贝的方式创建子进程进程终止进程退出码进程退出的方式exit()和_exit()进程等待进程等待方法 -- wait()和waitpid()status参数解释waitpid()的pid参数waitpid()的options参数 - 阻塞和非阻塞进程…...

谷歌seo快排技术怎么做?Google排名霸屏推广原理

本文主要分享关于谷歌快速排名的方法和所需要的条件。 本文由光算创作&#xff0c;有可能会被剽窃和修改&#xff0c;我们佛系对待这种行为吧。 首先提出一个问题&#xff1a;谷歌seo快排技术怎么做&#xff1f;如何达到谷歌霸屏的效果&#xff1f; 答案是&#xff1a;利用谷…...

MySQL的优化

目录 一.概念 二.查看SQL执行频率 三.定位低效率执行SQL 定位低效率执行SQL—慢查询日志 操作 定位低效率执行SQL—show processlist 四.explain分析执行计划 字段说明 explain中的id explain中的select_type explain中的type explain中的table explain中的rows ex…...

实现qq群消息接收和发送功能

QQWebsocketClient是什么 实现qq群消息接收和发送功能&#xff0c;基于websocket技术和cqhttp服务开发 一、 效果截图 二、实现思路 使用cqhttp进行socket反向代理&#xff0c;获取qq聊天的所有消息 编写java客户端&#xff0c;连接至cqhttp服务器获取聊天消息 获取聊天消…...

压缩20M文件从30秒到1秒的优化过程

压缩20M文件从30秒到1秒的优化过程 有一个需求需要将前端传过来的10张照片&#xff0c;然后后端进行处理以后压缩成一个压缩包通过网络流传输出去。之前没有接触过用Java压缩文件的&#xff0c;所以就直接上网找了一个例子改了一下用了&#xff0c;改完以后也能使用&#xff0…...

如何选择合适的固态继电器?

如何选择合适的固态继电器&#xff1f; 在选择固态继电器&#xff08;SSR&#xff09;时&#xff0c;应根据实际应用条件和SSR性能参数&#xff0c;特别要考虑到使用中的过流和过压条件以及SSR的负载能力&#xff0c;这有助于实现固态继电器的长寿命和高可靠性。然后&#xff0…...

SAP 忘记SAP系统Client 000的所有账号密码

忘记SAP系统Client 000的所有账号密码。 Solution 在SAP系统DB中删除账号SAP*&#xff0c;SAP系统会自动创建SAP*这个账号&#xff0c;然后初始密码是“PASS”&#xff0c;这样就获得Client 000 SAP*账号。 Step by Step 以Oracle数据库为例&#xff1a; 1.以<SID>ADM账…...

Connext DDS可扩展类型Extensible Types指南

RTI Connext DDS 可扩展类型Extensible Types指南 可扩展类型Extensible TypesConnextDDSv6.1.1版本,包含了对OMG“DDS的可扩展和动态主题类型Extensible andDynamic Topic Types for DDS”规范1.3版的部分支持,该规范来自对象管理组OMG。这种支持,允许系统以更灵活的方式定义…...

Docker简单使用

文章目录1、安装配置2、服务启动3、Docker镜像下载4、Docker启动容器5、容器的常用命令6、Docker进入容器内部7、宿主机与容器交换文件8、查看日志官网地址&#xff1a;1、安装配置 sudo yum install -y yum-utils 设置镜像地址 sudo yum-config-manager \--add-repo \https:…...

A Time Series is Worth 64 Words(PatchTST模型)论文解读

摘要 我们提出了一种高效的基于Transformer设计的模型&#xff0c;用于多变量时间序列预测和自我监督表征学习&#xff08;self-supervised learning&#xff09;。它基于两个关键部分&#xff1a;1、将时间序列分隔成子序列级别的patches&#xff0c;作为Transformer的输入&a…...

微服务学习:SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

目录 一、高级篇 二、面试篇 实用篇 day05-Elasticsearch01 安装elasticsearch 1.部署单点es 2.部署kibana 一、高级篇 二、面试篇 实用篇 day05-Elasticsearch01 安装elasticsearch 1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要…...

nginx平滑升级

1.平滑升级操作1.1 备份安装目录下的nginxcd /usr/local/nginx/sbin mv nginx nginx.bak1.2 复制objs目录下的nginx到当前sbin目录下cp /opt/software/nginx/nginx-1.20.2/objs/nginx /usr/local/nginx/sbin/1.3 发送信号user2给nginx老版本对应的进程kill -user2 more /usr/lo…...

高可用的“异地多活”架构设计

前言 后台服务可以划分为两类&#xff0c;有状态和无状态。高可用对于无状态的应用来说是比较简单的&#xff0c;无状态的应用&#xff0c;只需要通过 F5 或者任何代理的方式就可以很好的解决。后文描述的主要是针对有状态的服务进行分析。 服务端进行状态维护主要是通过磁盘…...

【面试题】Map和Set

1. Map和Object的区别 形式不同 // Object var obj {key1: hello,key2: 100,key3: {x: 100} } // Map var m new Map([[key1, hello],[key2, 100],[key3, {x: 100}] ])API不同 // Map的API m.set(name, 小明) // 新增 m.delete(key2) // 删除 m.has(key3) // …...

Spring之事务底层源码解析

Spring之事务底层源码解析 1、EnableTransactionManagement工作原理 开启 Spring 事务本质上就是增加了一个 Advisor&#xff0c;当我们使用 EnableTransactionManagement 注解来开启 Spring 事务时&#xff0c;该注解代理的功能就是向 Spring 容器中添加了两个 Bean&#xf…...

【华为OD机试真题 Python】创建二叉树

前言:本专栏将持续更新华为OD机试题目,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于OD机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:nansun0903@163.com;备注:CSDN。 题目描述 请按下列描达构建…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...