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)和…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
