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

LinkedList的顶级理解

目录

1.LinkedList的介绍

LinkedList的结构

2.LinkedList的模拟实现

2.1创建双链表 

2.2头插法

2.3尾插法

2.4任意位置插入

2.5查找关键字

2.6链表长度

2.7遍历链表

2.8删除第一次出现关键字为key的节点

2.9删除所有值为key的节点

2.10清空链表

2.11完整代码

3.LinkedList的使用 

3.1LinkedList的构造

3.2LinkedList的其他常用方法介绍 

 3.3LinkedList的遍历

3.4ArrayList和LinkedList的区别


1.LinkedList的介绍

LinkedList的底层是双向链表结构,元素存储在单独的节点中,通过引用将节点连接起来了。

如果对双向链表或链表不太清晰,可以先看看本博主写的有关链表的文章。

链表的顶级理解_WHabcwu的博客-CSDN博客

在集合框架中,LinkedList也实现了List接口,具体如下:

注意: 

1. LinkedList 实现了 List 接口
2. LinkedList 的底层使用了双向链表
3. LinkedList 没有实现 RandomAccess 接口,因此 LinkedList 不支持随机访问
4. LinkedList 的任意位置插入和删除元素时效率比较高,时间复杂度为 O(1)
5. LinkedList 比较适合任意位置插入的场景

 

LinkedList的结构

 

  • 前驱节点:用于存储前一节点的位置,用prev表示
  • 后继节点:用于储存下一节点的位置,用next表示
  • 所需要储存的数据,用val表示
  • 头节点:用head表示
  • 尾节点:用last表示

2.LinkedList的模拟实现

无非是增删查改,在某位置的插入与删除,对数据内容进行管理和操作。

具体实现内容:

(1)创建双链表

(2)头插法

(3)尾插法

(4)任意位置插入

(5)查找关键字

(6)链表长度

(7)遍历链表

(8)删除第一次出现关键字为key的节点

(9)删除所有值为key的节点

(10)清空链表

2.1创建双链表 

public class MyLinkedList {static class ListNode {public int val;public ListNode prev;//前驱public ListNode next;//后继public ListNode(int val) {this.val = val;}}public ListNode head;//头节点public ListNode last;//尾节点
}

2.2头插法

(1)首先判断头节点是否为null若为null,则该节点就是头节点,也是尾节点.

(2)头节点不为null,将原先head的前驱节点指向新增节点位置,新增节点后驱节点指向head节点的位置。

(3)head指向新增节点位置。

    //插法 O(1)public void addFirst(int data){ListNode node = new ListNode(data);if(head == null) {head = node;last = node;}else {node.next = head;head.prev = node;head = node;}}

2.3尾插法

与头插法大同小异

    //尾插法 O(1)public void addLast(int data){ListNode node = new ListNode(data);if(head == null) {head = node;last = node;}else {last.next = node;node.prev = last;last = node;}}

2.4任意位置插入

需要插入的位置必须为合法,如果不合法,我们会抛出一个异常进行提醒

public class ListIndexOutOfException extends RuntimeException{public ListIndexOutOfException() {}public ListIndexOutOfException(String message) {super(message);}
}

任意位置插入,我们可以分为种情况,插在开头,插在结尾,插在中间

    //任意位置插入,第一个数据节点为0号下标public void addIndex(int index,int data){if(index < 0 || index > size()) {throw new ListIndexOutOfException("违规数据");}if(index == 0) {addFirst(data);return;}if(index == size()) {addLast(data);return;}ListNode cur = findIndex(index);//ListNode node = new ListNode(data);cur.prev.next = node;node.next = cur;node.prev = cur.prev;cur.prev = node;}

2.5查找关键字

直接遍历查找即可

    //查找是否包含关键字key是否在单链表当中public boolean contains(int key){ListNode cur = head;while (cur != null) {if(cur.val == key) {return true;}cur = cur.next;}return false;}

2.6链表长度

用一个len变量进行记录,遍历链表

    public int size(){int len = 0;ListNode cur = head;while (cur != null) {len++;cur = cur.next;}return len;}

2.7遍历链表

    public void display(){ListNode cur = head;while (cur != null) {System.out.print(cur.val+" ");cur = cur.next;}System.out.println();}

2.8删除第一次出现关键字为key的节点

(1)一个节点都没有
(2)删除数据在第一个
(3)没有你要删除的数据
(4)有你要删除的数据且不是第一个

(5)删除数据最后一个

 找到就return;

    //删除第一次出现关键字为key的节点public void remove(int key){ListNode cur = head;while (cur != null) {//开始删除了if(cur.val == key) {//1. 删除的是头节点if(cur == head) {head = head.next;//只有一个节点if(head != null) {head.prev = null;}}else {//中间  尾巴cur.prev.next = cur.next;//不是尾巴节点if(cur.next != null) {cur.next.prev = cur.prev;}else {//是尾巴节点last = last.prev;}}return;}cur = cur.next;}}

2.9删除所有值为key的节点

与删除第一次出现关键字为key的节点几乎是一模一样的;

我们只需要遍历完就好,只需要return删掉就好。

    //删除所有值为key的节点public void removeAllKey(int key){ListNode cur = head;while (cur != null) {//开始删除了if(cur.val == key) {//1. 删除的是头节点if(cur == head) {head = head.next;//只有一个节点if(head != null) {head.prev = null;}}else {//中间  尾巴cur.prev.next = cur.next;//不是尾巴节点if(cur.next != null) {cur.next.prev = cur.prev;}else {//是尾巴节点last = last.prev;}}}cur = cur.next;}}

2.10清空链表

只需要遍历整个链表,将每个节点的前驱与后继节点都置为null就好

    public void clear(){ListNode cur = head;while(cur != null) {cur.prev  = null;cur = cur.next;cur.prev.next = null;}head = null;last = null;}

2.11完整代码

public class MyLinkedList {static class ListNode {public int val;public ListNode prev;//前驱public ListNode next;//后继public ListNode(int val) {this.val = val;}}public ListNode head;//头节点public ListNode last;//尾节点//头插法 O(1)public void addFirst(int data){ListNode node = new ListNode(data);if(head == null) {head = node;last = node;}else {node.next = head;head.prev = node;head = node;}}//尾插法 O(1)public void addLast(int data){ListNode node = new ListNode(data);if(head == null) {head = node;last = node;}else {last.next = node;node.prev = last;last = node;}}//任意位置插入,第一个数据节点为0号下标public void addIndex(int index,int data){if(index < 0 || index > size()) {throw new ListIndexOutOfException("违规数据");}if(index == 0) {addFirst(data);return;}if(index == size()) {addLast(data);return;}ListNode cur = findIndex(index);//ListNode node = new ListNode(data);cur.prev.next = node;node.next = cur;node.prev = cur.prev;cur.prev = node;}private ListNode findIndex(int index) {ListNode cur = head;while (index != 0) {cur = cur.next;index--;}return cur;}//查找是否包含关键字key是否在单链表当中public boolean contains(int key){ListNode cur = 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 != null) {//开始删除了if(cur.val == key) {//1. 删除的是头节点if(cur == head) {head = head.next;//只有一个节点if(head != null) {head.prev = null;}}else {//中间  尾巴cur.prev.next = cur.next;//不是尾巴节点if(cur.next != null) {cur.next.prev = cur.prev;}else {//是尾巴节点last = last.prev;}}return;}cur = cur.next;}}//删除所有值为key的节点public void removeAllKey(int key){ListNode cur = head;while (cur != null) {//开始删除了if(cur.val == key) {//1. 删除的是头节点if(cur == head) {head = head.next;//只有一个节点if(head != null) {head.prev = null;}}else {//中间  尾巴cur.prev.next = cur.next;//不是尾巴节点if(cur.next != null) {cur.next.prev = cur.prev;}else {//是尾巴节点last = last.prev;}}}cur = cur.next;}}public int size(){int len = 0;ListNode cur = head;while (cur != null) {len++;cur = cur.next;}return len;}public void display(){ListNode cur = head;while (cur != null) {System.out.print(cur.val+" ");cur = cur.next;}System.out.println();}public void clear(){ListNode cur = head;while(cur != null) {cur.prev  = null;cur = cur.next;cur.prev.next = null;}head = null;last = null;}
}

3.LinkedList的使用 

3.1LinkedList的构造

3.2LinkedList的其他常用方法介绍 

 

 3.3LinkedList的遍历

    public static void main(String[] args) {LinkedList<Integer> linkedList = new LinkedList<>();linkedList.add(1);linkedList.add(2);linkedList.add(3);linkedList.add(4);linkedList.add(5);// foreach遍历for (int e:list) {System.out.print(e + " ");}System.out.println();System.out.println("=====================");// 使用迭代器遍历---正向遍历Iterator<Integer> iterator1 = linkedList.iterator();while(iterator1.hasNext()){System.out.println(iterator1.next());}System.out.println("=====================");// 使用反向迭代器---反向遍历ListIterator<Integer> iterator2 = linkedList.listIterator(linkedList.size());while (iterator2.hasPrevious()){System.out.println(iterator2.previous());}}

3.4ArrayList和LinkedList的区别

 


以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

 

相关文章:

LinkedList的顶级理解

目录 1.LinkedList的介绍 LinkedList的结构 2.LinkedList的模拟实现 2.1创建双链表 2.2头插法 2.3尾插法 2.4任意位置插入 2.5查找关键字 2.6链表长度 2.7遍历链表 2.8删除第一次出现关键字为key的节点 2.9删除所有值为key的节点 2.10清空链表 2.11完整代码 3.…...

再学http-为什么文件上传要转成Base64?

1 前言 最近在开发中遇到文件上传采用Base64的方式上传&#xff0c;记得以前刚开始学http上传文件的时候&#xff0c;都是通过content-type为multipart/form-data方式直接上传二进制文件&#xff0c;我们知道都通过网络传输最终只能传输二进制流&#xff0c;所以毫无疑问他们本…...

使用oracleVM搭建虚拟机

选择新建&#xff0c;点击 取名字&#xff0c;选择你的安装路径&#xff0c;选择你爹镜像光盘&#xff0c;再勾选下面的&#xff0c;表示跳过一些步骤 其他的都可以默认&#xff0c;下一步即可 创建好了&#xff0c;点击设置&#xff0c;改变光驱&#xff0c;硬盘的顺序 等待它…...

深入探讨C存储类和存储期——Storage Duration

&#x1f517; 《C语言趣味教程》&#x1f448; 猛戳订阅&#xff01;&#xff01;&#xff01; ​—— 热门专栏《维生素C语言》的重制版 —— &#x1f4ad; 写在前面&#xff1a;这是一套 C 语言趣味教学专栏&#xff0c;目前正在火热连载中&#xff0c;欢迎猛戳订阅&#…...

医学图像融合的深度学习方法综述

文章目录 Deep learning methods for medical image fusion: A review摘要引言非端到端的融合方法基于深度学习的决策映射基于深度学习的特征提取 端到端图像融合方法基于卷积神经网络(CNN)的图像融合方法单级特征融合方法多级特征融合基于残差神经网络的图像融合方法基于密集神…...

【Qt学习】04:QDialog

QDialog OVERVIEW QDialog一、自定义对话框1.模态对话框2.非模态对话框3.练习代码 二、标准对话框1.消息对话框2.文件对话框3.颜色对话框4.字体对话框 对话框是 GUI 程序中不可或缺的组成部分&#xff0c;对话框通常会是一个顶层窗口出现在程序最上层&#xff0c;用于实现短期任…...

如何更好的进行异常处理

背景 在实际开发中&#xff0c;我们都希望程序可以一直按照期望的流程&#xff0c;无误的走下去。但是由于不可避免的内外部因素&#xff0c;可能导致出现异常的情况&#xff0c;轻则导致报错&#xff0c;重则数据错乱、服务不可用等情况。严重影响系统的稳定性&#xff0c;甚至…...

若依微服务版部署到IDEA

1.进入若依官网&#xff0c;找到我们要下的微服务版框架 2.点击进入gitee,获取源码&#xff0c;下载到本地 3.下载到本地后&#xff0c;用Idea打开&#xff0c;点击若依官网&#xff0c;找到在线文档&#xff0c;找到微服务版本的&#xff0c;当然你不看文档&#xff0c;直接按…...

Elasticsearch 入门安装

1.Elasticsearch 是什么 The Elastic Stack, 包括 Elasticsearch、 Kibana、 Beats 和 Logstash&#xff08;也称为 ELK Stack&#xff09;。能够安全可靠地获取任何来源、任何格式的数据&#xff0c;然后实时地对数据进行搜索、分析和可视化。 Elaticsearch&#xff0c;简称为…...

【80天学习完《深入理解计算机系统》】第十一天 3.5 过程(函数调用)

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…...

LinuxUbuntu安装VMware tools Segmentation fault (core dumped)怎么解决

LinuxUbuntu安装VMware tools Segmentation fault (core dumped)怎么解决 在安装VMware Tools时遇到"Segmentation fault (core dumped)"错误&#xff0c;通常是由于兼容性问题或系统配置不正确导致的。以下是一些可能的解决方法&#xff1a; 检查VMware Tools兼容性…...

002微信小程序云开发API数据库-迁移状态查询/更新索引

文章目录 微信小程序云开发API数据库-迁移状态查询案例代码微信小程序云开发API数据库-更新索引案例代码 微信小程序云开发API数据库-迁移状态查询 在微信小程序中&#xff0c;云开发API数据库是一种方便快捷的数据库解决方案。但是&#xff0c;有时候我们可能需要将云开发数据…...

十几款拿来就能用的炫酷表白代码

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 表白代码 1、坐我女朋友好吗&#xff0c;不同意就关机.vbs2、坐我女朋友好吗&…...

证券低延时环境设置并进行性能测试

BIOS设置BIOS参考信息 关闭 logical Process Virtualization Technology 在System Profiles Settings 中System Profile 选择Performance Workload Profile 选择HPC Profile OS中信息参考在/etc/default/grub文件中添加 intel_idle.max_cstate=0 processor.max_cstate=0 idle=p…...

百度工程师浅析解码策略

作者 | Jane 导读 生成式模型的解码方法主要有2类&#xff1a;确定性方法&#xff08;如贪心搜索和波束搜索&#xff09;和随机方法。确定性方法生成的文本通常会不够自然&#xff0c;可能存在重复或过于简单的表达。而随机方法在解码过程中引入了随机性&#xff0c;以便生成更…...

windows下实现查看软件请求ip地址的方法

一、关于wmic和nestat wmic是Windows Management Instrumentation的缩写&#xff0c;是一款非常常用的用于Windows系统管理的命令行实用程序。wmic可以通过命令行操作&#xff0c;获取系统信息、安装软件、启动服务、管理进程等操作。 netstat命令是一个监控TCP/IP网络的非常有…...

【JAVA】String 类

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈Java &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; String 1. 字符串构造2. String对象的比…...

LoRA继任者ReLoRA登场,通过叠加多个低秩更新矩阵实现更高效大模型训练效果

论文链接&#xff1a; https://arxiv.org/abs/2307.05695 代码仓库&#xff1a; https://github.com/guitaricet/peft_pretraining 一段时间以来&#xff0c;大模型&#xff08;LLMs&#xff09;社区的研究人员开始关注于如何降低训练、微调和推理LLMs所需要的庞大算力&#xf…...

Elasticsearch 8.X reindex 源码剖析及提速指南

1、reindex 源码在线地址 为方便大家验证&#xff0c;这里给出 reindex github 源码地址。 https://github.com/elastic/elasticsearch/blob/001fcfb931454d760dbccff9f4d1b8d113f8708c/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java reindex 常见…...

前端组件库造轮子——Input组件开发教程

前端组件库造轮子——Input组件开发教程 前言 本系列旨在记录前端组件库开发经验&#xff0c;我们的组件库项目目前已在Github开源&#xff0c;下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。 文章旨在总结经验&#xff0c;开源…...

驱动残留清理技术解析:Display Driver Uninstaller实战指南

驱动残留清理技术解析&#xff1a;Display Driver Uninstaller实战指南 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-uninsta…...

超轻量级OpenClaw与LaTeX结合:学术文档自动化处理

超轻量级OpenClaw与LaTeX结合&#xff1a;学术文档自动化处理 科研工作者每天需要处理大量的文献整理、公式编辑和文档排版工作&#xff0c;传统手动方式耗时且容易出错。本文将展示如何用超轻量级OpenClaw实现学术文档的自动化处理&#xff0c;让LaTeX文档编写变得轻松高效。 …...

DynamicColor跨平台开发指南:iOS、macOS、watchOS的统一颜色解决方案

DynamicColor跨平台开发指南&#xff1a;iOS、macOS、watchOS的统一颜色解决方案 【免费下载链接】DynamicColor Yet another extension to manipulate colors easily in Swift and SwiftUI 项目地址: https://gitcode.com/gh_mirrors/dy/DynamicColor DynamicColor是一…...

别再纠结了!.NET后台任务调度,Hangfire和Quartz.NET到底怎么选?

Hangfire与Quartz.NET深度抉择指南&#xff1a;从业务场景到技术实现的精准匹配 在.NET生态系统中&#xff0c;后台任务调度是几乎所有企业级应用都无法绕开的核心需求。无论是电商平台的订单状态更新、金融系统的日终批处理&#xff0c;还是内容管理系统的定时数据同步&#x…...

5个关键步骤:使用SMUDebugTool解决AMD Ryzen硬件调试难题

5个关键步骤&#xff1a;使用SMUDebugTool解决AMD Ryzen硬件调试难题 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https:/…...

Sunshine开源游戏串流:打造你的专属云游戏服务器终极指南

Sunshine开源游戏串流&#xff1a;打造你的专属云游戏服务器终极指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 想要在任何设备上畅玩PC游戏&#xff1f;厌倦了被商业云游戏平…...

JMeter vs Claude Code:从“约束系统“到“解放系统“的工程设计范式跃迁

当你还在用 JMeter 写线程组的时候&#xff0c;Claude Code 已经在用自然语言编排测试工作流了。这不是工具的迭代&#xff0c;是工程设计范式的代际更替。前言&#xff1a;两代工程设计哲学的碰撞 2026 年&#xff0c;AI 编程工具已经从"代码生成器"进化为"自主…...

告别卡顿!用MobileNetv2+MPPTSNet-EC在树莓派上跑实时语义分割(附完整配置与性能测试)

树莓派实战&#xff1a;MobileNetv2MPPTSNet-EC实时语义分割全流程解析 当你在树莓派上第一次看到摄像头画面被实时分割成不同语义区域时&#xff0c;那种成就感绝对值得记录。本文将带你完整实现从模型选择到部署优化的全流程&#xff0c;用MobileNetv2MPPTSNet-EC这套组合拳&…...

UE5伤害系统避坑指南:Damage Type没用好?你的Apply Damage可能白写了

UE5伤害系统深度解析&#xff1a;如何用Damage Type构建高扩展性战斗机制 在虚幻引擎5的游戏开发中&#xff0c;伤害系统是战斗机制的核心支柱。许多开发者习惯性地将注意力集中在Damage Amount这个数值上&#xff0c;却忽视了Damage Type这个能够赋予游戏深度和多样性的强大工…...

终极PDF Arranger常见问题FAQ:解决用户最关心的30个疑问

终极PDF Arranger常见问题FAQ&#xff1a;解决用户最关心的30个疑问 【免费下载链接】pdfarranger Small python-gtk application, which helps the user to merge or split PDF documents and rotate, crop and rearrange their pages using an interactive and intuitive gra…...