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)和…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...