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中的链表实现介绍 学习数据结构的的链表和树时,会遇到节点(node)和链表(linked list)这两个术语,节点是处理数据结构的链表和树的基础。节点是一种数据元素,包括两个部分:一个是…...
演示Ansible中的角色使用方法(ansible roles)
文章目录一、ansible 角色简介二、roles目录结构三、role存放的路径:配置文件ansible.cfg中定义四、创建目录结构五、playbook中使用rolesplaybook变量会覆盖roles中的定义变量六、控制任务执行顺序七、ansible—galaxy命令工具八、安装选择的角色1.从网上下载&…...
Bash Shell 通过ls命令筛选文件
Bash Shell 通过ls命令及其管道根据大小名称筛选文件 最近参与的项目当中有需要用pyarmor加密项目的要求,听网上吹的pyarmor都那么神,用了一下感觉也一般,试用版普通模式下文件加密居然还有大小32KB的限制,加密到一半就失败了&am…...
2023-2-18 刷题情况
删列造序 III 题目描述 给定由 n 个小写字母字符串组成的数组 strs ,其中每个字符串长度相等。 选取一个删除索引序列,对于 strs 中的每个字符串,删除对应每个索引处的字符。 比如,有 strs [“abcdef”,“uvwxyz”] …...
【Linux】进程控制
文章目录进程创建简单认识一下fork()函数为什么fork()会有两个返回值fork通过写时拷贝的方式创建子进程进程终止进程退出码进程退出的方式exit()和_exit()进程等待进程等待方法 -- wait()和waitpid()status参数解释waitpid()的pid参数waitpid()的options参数 - 阻塞和非阻塞进程…...
谷歌seo快排技术怎么做?Google排名霸屏推广原理
本文主要分享关于谷歌快速排名的方法和所需要的条件。 本文由光算创作,有可能会被剽窃和修改,我们佛系对待这种行为吧。 首先提出一个问题:谷歌seo快排技术怎么做?如何达到谷歌霸屏的效果? 答案是:利用谷…...
MySQL的优化
目录 一.概念 二.查看SQL执行频率 三.定位低效率执行SQL 定位低效率执行SQL—慢查询日志 操作 定位低效率执行SQL—show processlist 四.explain分析执行计划 字段说明 explain中的id explain中的select_type explain中的type explain中的table explain中的rows ex…...
实现qq群消息接收和发送功能
QQWebsocketClient是什么 实现qq群消息接收和发送功能,基于websocket技术和cqhttp服务开发 一、 效果截图 二、实现思路 使用cqhttp进行socket反向代理,获取qq聊天的所有消息 编写java客户端,连接至cqhttp服务器获取聊天消息 获取聊天消…...
压缩20M文件从30秒到1秒的优化过程
压缩20M文件从30秒到1秒的优化过程 有一个需求需要将前端传过来的10张照片,然后后端进行处理以后压缩成一个压缩包通过网络流传输出去。之前没有接触过用Java压缩文件的,所以就直接上网找了一个例子改了一下用了,改完以后也能使用࿰…...
如何选择合适的固态继电器?
如何选择合适的固态继电器? 在选择固态继电器(SSR)时,应根据实际应用条件和SSR性能参数,特别要考虑到使用中的过流和过压条件以及SSR的负载能力,这有助于实现固态继电器的长寿命和高可靠性。然后࿰…...
SAP 忘记SAP系统Client 000的所有账号密码
忘记SAP系统Client 000的所有账号密码。 Solution 在SAP系统DB中删除账号SAP*,SAP系统会自动创建SAP*这个账号,然后初始密码是“PASS”,这样就获得Client 000 SAP*账号。 Step by Step 以Oracle数据库为例: 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、查看日志官网地址:1、安装配置 sudo yum install -y yum-utils 设置镜像地址 sudo yum-config-manager \--add-repo \https:…...
A Time Series is Worth 64 Words(PatchTST模型)论文解读
摘要 我们提出了一种高效的基于Transformer设计的模型,用于多变量时间序列预测和自我监督表征学习(self-supervised learning)。它基于两个关键部分:1、将时间序列分隔成子序列级别的patches,作为Transformer的输入&a…...
微服务学习:SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
目录 一、高级篇 二、面试篇 实用篇 day05-Elasticsearch01 安装elasticsearch 1.部署单点es 2.部署kibana 一、高级篇 二、面试篇 实用篇 day05-Elasticsearch01 安装elasticsearch 1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器,因此需要…...
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…...
高可用的“异地多活”架构设计
前言 后台服务可以划分为两类,有状态和无状态。高可用对于无状态的应用来说是比较简单的,无状态的应用,只需要通过 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,当我们使用 EnableTransactionManagement 注解来开启 Spring 事务时,该注解代理的功能就是向 Spring 容器中添加了两个 Bean…...
【华为OD机试真题 Python】创建二叉树
前言:本专栏将持续更新华为OD机试题目,并进行详细的分析与解答,包含完整的代码实现,希望可以帮助到正在努力的你。关于OD机试流程、面经、面试指导等,如有任何疑问,欢迎联系我,wechat:steven_moda;email:nansun0903@163.com;备注:CSDN。 题目描述 请按下列描达构建…...
抖音无水印视频批量下载器:从零开始的高效内容采集指南
抖音无水印视频批量下载器:从零开始的高效内容采集指南 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 你是否曾遇到过这样的困境?想要保存抖音上的精彩视频用于学习参考,…...
情感GDP报告:测试员负面情绪成经济指标的行业变革
一、导言:情感GDP的崛起与测试行业新坐标 2025年全球情感计算市场规模突破596亿元(数据来源:2024年情感计算行业报告),"情感GDP"作为衡量情绪价值的经济指标,正重塑职业评价体系。软件测试领域首…...
OpenClaw飞书机器人配置指南:百川2-13B-4bits量化模型对话触发
OpenClaw飞书机器人配置指南:百川2-13B-4bits量化模型对话触发 1. 为什么选择OpenClaw飞书百川2的组合? 去年我接手了一个小团队的日报自动化项目,需要每天收集5个成员的进度更新并生成汇总报告。最初尝试用Python脚本钉钉机器人࿰…...
当Logo消失,品牌资产还剩多少?
这个问题问得直接——品牌费尽心思把Logo放大、放正、放在C位,可如果有一天消费者真的“看不见”它,品牌还剩下什么?答案取决于品牌建设的本质:是在做识别符号,还是在做价值沉淀。1. 认知资产:剩不下什么Lo…...
Bedtools:基因组数据分析的高效工具集
Bedtools:基因组数据分析的高效工具集 【免费下载链接】bedtools A powerful toolset for genome arithmetic. 项目地址: https://gitcode.com/gh_mirrors/be/bedtools 项目价值与应用场景 Bedtools作为一款专注于基因组算术操作的工具集,在生物…...
脑波货币化:公司用我的焦虑情绪炒期货
一、软件测试工程师:焦虑的“完美生产者”在持续集成、敏捷交付的现代开发流程中,软件测试从业者长期处于多重压力夹击之下:精确性高压:对缺陷零容忍的行业标准,使每一次测试执行如同走钢丝技术迭代焦虑:AI…...
WebSocket消息压缩终极指南:如何平衡性能与带宽的完整实践
WebSocket消息压缩终极指南:如何平衡性能与带宽的完整实践 【免费下载链接】async-http-client Asynchronous Http and WebSocket Client library for Java 项目地址: https://gitcode.com/gh_mirrors/as/async-http-client 在现代实时应用中,We…...
Qwen3-ASR-1.7B开源ASR教程:适配国产昇腾/寒武纪平台的移植可行性分析
Qwen3-ASR-1.7B开源ASR教程:适配国产昇腾/寒武纪平台的移植可行性分析 1. 项目背景与模型介绍 「清音听真」是基于Qwen3-ASR-1.7B语音识别引擎的高精度转录平台。作为0.6B版本的跨代升级,这个1.7B参数的模型在复杂语音场景处理能力上实现了显著提升。 …...
OpenClaw+GLM-4.7-Flash:3个提升开发效率的自动化脚本
OpenClawGLM-4.7-Flash:3个提升开发效率的自动化脚本 1. 为什么选择这个技术组合? 作为一名长期在终端里摸爬滚打的开发者,我一直在寻找能够真正融入日常工作的AI助手方案。直到遇到OpenClawGLM-4.7-Flash这个组合,才找到了理想…...
C/C++进阶知识1.0
C/C进阶知识 1.delete与delete[ ] ClassA *pclassanew ClassA[5]; delete pclassa; 与 int *p new int[5]; delete p; 1.1内置类型 不调用析构函数 1.2自定义类型 析构函数调用一次 2.内存知识 2.1栈堆增长方向不同的原因: 栈向下增长堆向上增长的设计目的是…...
