Java链表及源码解析
文章目录
- 创建一个ILindkedList接口创建方法(模拟实现链表方法)
- 创建MyLinkedList来实现接口的方法
- 创建链表节点
- addFirst方法(新增头部属性)
- addLast方法(新增到末尾一个属性)
- remove方法(删除指定属性)
- addIndex方法(任意位置添加一个元素属性)
- removeAll(删除所有指定元素)
- display打印
- contains(链表中包含某个元素)
- size(获取链表元素的数量)
- clean(清空)
- MyLinkedList代码如下:
- Test代码:
- **链表是通过逻辑储存的方式通过节点的引用来获取元素值,每个节点包含两个部分 首先第一部分是value元素值。 第二部分是next来获取下个节点的地址,通过next来串联各个地址获取其中的value元素
有序数组如果想要新增或者删减元素需要从头开始遍历逐个进行覆盖确保有序数组中的有序,时间复杂度为O(m*n)。
链表的复杂度相对有序数组要方便他的时间复杂度分别是O(1)和O(N)。 **

创建一个ILindkedList接口创建方法(模拟实现链表方法)
public interface ILinkedList {//首位置新增元素public void addFirst(int data);//最后位置新增元素public void addLast(int data);//在指定位置新增元素public void addIndex(int index,int data);//在链表中删除key元素public void remove(int key);//删除所有key的元素public void removeAll(int key);//打印链表元素public void display();//是否包含datapublic boolean contains(int data);//获取链表中元素的大小public int size();void clean();
}
创建MyLinkedList来实现接口的方法
import javax.xml.soap.Node;public class MyLinkedList implements ILinkedList{//创建一个static内部类来初始化节点属性static class NodeList{//元素值public int value;//节点指向的下一个地址public NodeList next;//构造方法只给value通过这个值来next下一个节点public NodeList(int value) {this.value = value;}}
创建链表节点
//这里可以尝试创建一个链表public void createLinkedList(){NodeList node1=new NodeList(23);NodeList node2=new NodeList(25);NodeList node3=new NodeList(38);NodeList node4=new NodeList(55);//通过获取的对象来访问next链接下一个节点实现链接node1.next=node2;node2.next=node3;node3.next=node4;//这里node4的next节点为空值//head作为头部来访问各个节点this.head=node1;}
addFirst方法(新增头部属性)

@Overridepublic void addFirst(int data) {//增加一个元素到链表中,增加到头部//将data元素放入到类中NodeList node=new NodeList(data);NodeList cur=this.head;//这里node.next来获取头部地址node.next=head;//将node赋给headhead=node;}
addLast方法(新增到末尾一个属性)

@Overridepublic void addLast(int data) {//增加一个元素到末尾NodeList node=new NodeList(data);NodeList cur=this.head;//这里我们查找最后一个位置的next节点是否为null,如果是null;while(cur.next!=null){cur = cur.next;}//循环出来cur.next的节点为nullcur.next=node;}
remove方法(删除指定属性)

@Overridepublic void remove(int key) {//删除指定元素的next地址节点if(this.head==null){return;}//得到前缀NodeList cur = findRemoveKey(key);//判断返回值是否是空的if(cur==null){System.out.println("未找到该元素"+key);return;}//将cur.next给到dele得到节点NodeList dele=cur.next;//将后一个节点的next给到cur.next从而指向其他节点dele原有节点消失cur.next=dele.next;}private NodeList findRemoveKey(int key){NodeList cur=this.head;//cur.next不等于null数值while(cur.next!=null){if(cur.next.value==key){return cur;}//cur.next节点获取下一个curcur = cur.next;}return null;}
addIndex方法(任意位置添加一个元素属性)

removeAll(删除所有指定元素)

@Overridepublic void removeAll(int key) {if(this.head==null){return;}NodeList pre=this.head;NodeList cur=pre.next;//cur!=null说明有数据while(cur!=null){//value值为key进入循环if(cur.value==key){//pre的下个节点为cur的下一个节点,取消掉cur=key这个节点的链接pre.next=cur.next;cur=cur.next;}else{//如果不等于pre要跳到cur的位置来继续作为前一项pre=cur;//cur获取下一项cur=cur.next;}}//不要忽略头部,如果是key要替换掉if(this.head.value==key){this.head=this.head.next;}}
@Overridepublic void addIndex(int index, int data)throws ErrorRuntimeExcepetion {//给一个位置,放入data元素//如果index的值小于0或者大于本身长度抛出异常显示下标try {if(index<0||index>size()){throw new ErrorRuntimeExcepetion("范围不准确"+index);}}catch (ErrorRuntimeExcepetion e){e.printStackTrace();return;}//如果index的位置是0或者index的位置是最后一个if(index==0){addFirst(data);}if(index==size()){addLast(data);}//走到这里index的值为其范围内容,首先获取index-1的位置NodeList cur = searchPre(index);//生成data元素链表NodeList node=new NodeList(data);if(cur==null){return;}//将原来cur.index的地址赋值给node.index来后移node.next=cur.next;//将现在的cur.index的地址指向nodecur.next=node;}private NodeList searchPre(int index){NodeList cur=this.head;//求一个index-1的范围int count=0;while(count<index-1){cur=cur.next;count++;}//获取到index-1位置的curreturn cur;}
display打印
@Overridepublic void display() {//创建一个对象接收head值,来进行打印NodeList cur=this.head;//cur不等于nullwhile(cur!=null){//通过cur引用value来打印元素System.out.print(cur.value+" ");//通过next中下一个节点的地址来访问元素cur=cur.next;}System.out.println();}
contains(链表中包含某个元素)
@Overridepublic boolean contains(int data) {//链表中是否包含dataNodeList cur=this.head;if(cur.value==data){//如果value是data返回truereturn true;}else{while(cur.next!=null){//循环每个节点判断是否为dataif(cur.next.value==data){return true;}cur=cur.next;}}return false;}
size(获取链表元素的数量)
@Overridepublic int size() {//获取链表的元素大小NodeList cur = this.head;//如果cur中为null没有任何元素大小是0if (cur == null) {return 0;}int count=0;//计数while(cur!=null){count++;cur=cur.next;}return count;}
clean(清空)

@Overridepublic void clean() {if(this.head==null){return;}//将每个节点置为空属性并且回收NodeList cur=this.head;while(cur!=null){NodeList curNext=cur.next;cur.next=null;cur=curNext;}//置空nullthis.head=null;}
MyLinkedList代码如下:
import javax.xml.soap.Node;public class MyLinkedList implements ILinkedList{//创建一个static内部类来初始化节点属性static class NodeList{//元素值public int value;//节点指向的下一个地址public NodeList next;//构造方法只给value通过这个值来next下一个节点public NodeList(int value) {this.value = value;}}//创建一个带头链表来获取当前的节点第一个元素public NodeList head;//这里可以尝试创建一个链表public void createLinkedList(){NodeList node1=new NodeList(23);NodeList node2=new NodeList(25);NodeList node3=new NodeList(38);NodeList node4=new NodeList(55);//通过获取的对象来访问next链接下一个节点实现链接node1.next=node2;node2.next=node3;node3.next=node4;//这里node4的next节点为空值//head作为头部来访问各个节点this.head=node1;}@Overridepublic void addFirst(int data) {//增加一个元素到链表中,增加到头部//将data元素放入到类中NodeList node=new NodeList(data);NodeList cur=this.head;//这里node.next来获取头部地址node.next=head;//将node赋给headhead=node;}@Overridepublic void addLast(int data) {//增加一个元素到末尾NodeList node=new NodeList(data);NodeList cur=this.head;//这里我们查找最后一个位置的next节点是否为null,如果是null;while(cur.next!=null){cur = cur.next;}//循环出来cur.next的节点为nullcur.next=node;}@Overridepublic void remove(int key) {//删除指定元素的next地址节点if(this.head==null){return;}//得到前缀NodeList cur = findRemoveKey(key);//判断返回值是否是空的if(cur==null){System.out.println("未找到该元素"+key);return;}//将cur.next给到dele得到节点NodeList dele=cur.next;//将后一个节点的next给到cur.next从而指向其他节点dele原有节点消失cur.next=dele.next;}private NodeList findRemoveKey(int key){NodeList cur=this.head;//cur.next不等于null数值while(cur.next!=null){if(cur.next.value==key){return cur;}//cur.next节点获取下一个curcur = cur.next;}return null;}@Overridepublic void removeAll(int key) {if(this.head==null){return;}NodeList pre=this.head;NodeList cur=pre.next;//cur!=null说明有数据while(cur!=null){//value值为key进入循环if(cur.value==key){//pre的下个节点为cur的下一个节点,取消掉cur=key这个节点的链接pre.next=cur.next;cur=cur.next;}else{//如果不等于pre要跳到cur的位置来继续作为前一项pre=cur;//cur获取下一项cur=cur.next;}}//不要忽略头部,如果是key要替换掉if(this.head.value==key){this.head=this.head.next;}}@Overridepublic void addIndex(int index, int data)throws ErrorRuntimeExcepetion {//给一个位置,放入data元素//如果index的值小于0或者大于本身长度抛出异常显示下标try {if(index<0||index>size()){throw new ErrorRuntimeExcepetion("范围不准确"+index);}}catch (ErrorRuntimeExcepetion e){e.printStackTrace();return;}//如果index的位置是0或者index的位置是最后一个if(index==0){addFirst(data);}if(index==size()){addLast(data);}//走到这里index的值为其范围内容,首先获取index-1的位置NodeList cur = searchPre(index);//生成data元素链表NodeList node=new NodeList(data);if(cur==null){return;}//将原来cur.index的地址赋值给node.index来后移node.next=cur.next;//将现在的cur.index的地址指向nodecur.next=node;}private NodeList searchPre(int index){NodeList cur=this.head;//求一个index-1的范围int count=0;while(count<index-1){cur=cur.next;count++;}//获取到index-1位置的curreturn cur;}@Overridepublic void display() {//创建一个对象接收head值,来进行打印NodeList cur=this.head;//cur不等于nullwhile(cur!=null){//通过cur引用value来打印元素System.out.print(cur.value+" ");//通过next中下一个节点的地址来访问元素cur=cur.next;}System.out.println();}@Overridepublic boolean contains(int data) {//链表中是否包含dataNodeList cur=this.head;if(cur.value==data){//如果value是data返回truereturn true;}else{while(cur.next!=null){//循环每个节点判断是否为dataif(cur.next.value==data){return true;}cur=cur.next;}}return false;}@Overridepublic int size() {//获取链表的元素大小NodeList cur = this.head;//如果cur中为null没有任何元素大小是0if (cur == null) {return 0;}int count=0;//计数while(cur!=null){count++;cur=cur.next;}return count;}@Overridepublic void clean() {if(this.head==null){return;}//将每个节点置为空属性并且回收NodeList cur=this.head;while(cur!=null){NodeList curNext=cur.next;cur.next=null;cur=curNext;}//置空nullthis.head=null;}
}
Test代码:
public class Test {public static void main(String[] args) {MyLinkedList myLinkedList=new MyLinkedList();//这里创建链表对象
// myLinkedList.createLinkedList();//访问创建的链表myLinkedList.addFirst(10);myLinkedList.addFirst(10);myLinkedList.addLast(10);myLinkedList.addLast(10);myLinkedList.addIndex(3,39);myLinkedList.addIndex(5,10);System.out.println(myLinkedList.contains(39));myLinkedList.display();myLinkedList.remove(39);myLinkedList.removeAll(10);myLinkedList.display();myLinkedList.clean();myLinkedList.addFirst(1);myLinkedList.display();System.out.println("链表中的元素大小为"+myLinkedList.size());}
}
#运行结果

相关文章:
Java链表及源码解析
文章目录 创建一个ILindkedList接口创建方法(模拟实现链表方法)创建MyLinkedList来实现接口的方法创建链表节点addFirst方法(新增头部属性)addLast方法(新增到末尾一个属性)remove方法(删除指定属性)addInd…...
十、快速入门go语言之方法
文章目录 方法:one: 方法的概念:star2: 内嵌类型的方法和继承:star2: 多重继承 📅 2024年5月9日 📦 使用版本为1.21.5 方法 1️⃣ 方法的概念 ⭐️ 在Go语言中没有类这个概念,可以使用结构体来实现,那类方法呢?Go也…...
JVM 处理多线程并发执行
JVM(Java Virtual Machine)在处理多线程并发执行方面具有强大的支持,主要依赖于其内置的线程模型、内存模型以及同步机制。 JVM 通过以下关键机制和组件来管理多线程并发执行: 1. 线程模型 Java 线程与操作系统线程:…...
【D3.js in Action 3 精译_039】4.3 D3 面积图的绘制方法及其边界标签的添加
当前内容所在位置: 第四章 直线、曲线与弧线的绘制 ✔️ 4.1 坐标轴的创建(上篇) 4.1.1 D3 中的边距约定(中篇)4.1.2 坐标轴的生成(中篇) 4.1.2.1 比例尺的声明(中篇)4.1…...
布谷直播源码部署服务器关于数据库配置的详细说明
布谷直播源码搭建部署配置接口数据库 /public/db.php(2019年8月后的系统在该路径下配置数据库,老版本继续走下面的操作) 在项目代码中执行命令安装依赖库(⚠️注意:如果已经有了vendor内的依赖文件的就不用执行了&am…...
Xfce桌面设置右键菜单:用右键打开VSCode
前言 AlmaLinux安装VSCode之后始终没有找到如何用右键菜单打开VSCode,比Windows麻烦多了。每次都需要先找到文件夹,然后用系统自带的Open In Terminal打开终端,再输入code .,才能够在当前文件夹中快速打开VSCode。那么࿰…...
【NLP自然语言处理】深入探索Self-Attention:自注意力机制详解
目录 🍔 Self-attention的特点 🍔 Self-attention中的归一化概述 🍔 softmax的梯度变化 3.1 softmax函数的输入分布是如何影响输出的 3.2 softmax函数在反向传播的过程中是如何梯度求导的 3.3 softmax函数出现梯度消失现象的原因 &…...
Pytorch训练时报nan
0. 引言 Pytorch训练时在batchN时loss为nan。经过断点检查发现在batchN-1时,网络参数非nan,输出非nan,但梯度为nan,导致网络参数已经全部被更新为nan,遇到这种情况应该如何排查,如何避免?由于导…...
JavaScript定时器详解:setTimeout与setInterval的使用与注意事项
在JavaScript中,定时器用于在指定的时间间隔后或周期性地执行代码。JavaScript 提供了两种主要的定时器函数:setTimeout 和 setInterval。以下是它们的详细解释和实现方式: 1. setTimeout setTimeout 函数用于在指定的毫秒数后执行一次函数…...
CSS——选择器、PxCook软件、盒子模型
选择器 结构伪类选择器 作用:根据元素的结构关系查找元素。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…...
Mysql 大表limit查询优化原理实战
文章目录 1 大表查询无条件优化&原理(入门)2 大表查询带 条件 优化&原理(进阶)2.1 where 后面的查询字段只有一个时,要求该字段是索引字段2.2 where 后面的查询字段有多个时,尽量让查询字段为索引字段且字段值基数大 3 大表查询带 排序 优化&…...
在vscode中开发运行uni-app项目
确保电脑已经安装配置好了node、vue等相关环境依赖 进行项目的创建 vue create -p dcloudio/uni-preset-vue 项目名 vue create -p dcloudio/uni-preset-vue uni-app 选择模版 这里选择【默认模版】 项目创建成功后在vscode中打开 第一次打开项目 pages.json 文件会报错&a…...
【JavaEE初阶 — 多线程】Thread的常见构造方法&属性
目录 Thread类的属性 1.Thread 的常见构造方法 2.Thread 的几个常见属性 2.1 前台线程与后台线程 2.2 setDaemon() 2.3 isAlive() Thread类的属性 Thread 类是JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的Thread 对象与之关联&am…...
ctfshow(316)--XSS漏洞--反射性XSS
Web316 进入界面: 审计 显示是关于反射性XSS的题目。 思路 首先想到利用XSS平台解题,看其他师傅的wp提示flag是在cookie中。 当前页面的cookie是flagyou%20are%20not%20admin%20no%20flag。 但是这里我使用XSS平台,显示的cookie还是这样…...
ubuntu22.04安装conda
在 Ubuntu 22.04 上安装 Conda 可以通过以下步骤进行: 下载 Miniconda(轻量级版本的 Conda): 打开终端并运行以下命令以下载 Miniconda 安装脚本: wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-…...
D58【python 接口自动化学习】- python基础之异常
day58 异常捕获 学习日期:20241104 学习目标:异常 -- 74 自定义异常捕获:如何定义业务异常? 学习笔记: 自定义异常的用途 自定义异常的方法 # 抛出一个异常 # raise ValueError(value is error) # ValueError: val…...
Java项目实战II基于Spring Boot的便利店信息管理系统(开发文档+数据库+源码)
目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在快节奏的…...
Java-日期计算工具类DateCalculator
DateCalculator是用于日期计算的工具类。这个工具类将包括日期的加减、比较、周期计算、日期 范围生成等功能。 import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.Period; import java.time.temporal.ChronoUnit;…...
单片机串口接收状态机STM32
单片机串口接收状态机stm32 前言 项目的芯片stm32转国产,国产芯片的串口DMA接收功能测试不通过,所以要由原本很容易配置的串口空闲中断触发DMA接收数据的方式转为串口逐字节接收的状态机接收数据 两种方式各有优劣,不过我的芯片已经主频跑…...
ipv6的 fc00(FC00::/7) 和 fec0(FEC0::/10)
ipv6的 fc00(FC00::/7)(唯一本地地址) 替代了 fec0(FEC0::/10) (站点本地地址,已弃用) ipv6的 fc00(FC00::/7) 替代了 fec0(FEC0::/10) , 在IPv6地址中,FC00::/7(通常简写为FC00)和…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
JDK 17 序列化是怎么回事
如何序列化?其实很简单,就是根据每个类型,用工厂类调用。逐个完成。 没什么漂亮的代码,只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...
EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...
