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

LinkedList底层原理

节点(Node)结构

LinkedList 的核心是一个内部类 Node,每个 Node 对象代表链表中的一个元素,并且每个节点包含三个部分:

  1. 元素值 (item):存储实际的数据。
  2. 前驱节点引用 (prev):指向当前节点前面的节点。
  3. 后继节点引用 (next):指向当前节点后面的节点。
    private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}

LinkedList 类维护了两个引用,分别是指向链表的头部节点和尾部节点:

  1. 头节点 (first):指向链表的第一个节点。
  2. 尾节点 (last):指向链表的最后一个节点。
  3. 长度(size)
transient int size = 0;
transient Node<E> first;
transient Node<E> last;

链表的基本操作

        插入操作

        插入新节点时,通常需要更新相邻节点的前后指针以及链表的头尾指针。例如,插入到链表尾部的操作addLast():

  1. 创建一个新的 Node 实例。
  2. 将新节点的 prev 指向当前尾部节点。
  3. 如果链表为空,则同时设置 first 和 last 指向新节点;否则,设置当前尾部节点的 next 指向新节点,并更新 last 指向新节点。

源码: 

    public void addLast(E e) {linkLast(e);}void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;modCount++;}

 示例:

public class LinkedListTest {public static void main(String[] args) {LinkedList<String> sites = new LinkedList<>();sites.add("Google");sites.addLast("Wiki");System.out.println(sites);}
}
        删除操作

  1. 找到要删除的节点。
  2. 更新前驱节点的 next 指针和后继节点的 prev 指针。
  3. 如果删除的是头部节点,更新 first;如果是尾部节点,更新 last

部分源码: 

    public boolean remove(Object o) {//处理null值if (o == null) {for (Node<E> x = first; x != null; x = x.next) {if (x.item == null) {unlink(x);//删除return true;}}} else {for (Node<E> x = first; x != null; x = x.next) {if (o.equals(x.item)) {unlink(x);//删除return true;}}}return false;}//删除操作E unlink(Node<E> x) {final E element = x.item;final Node<E> next = x.next;final Node<E> prev = x.prev;if (prev == null) {first = next;} else {prev.next = next;x.prev = null;}if (next == null) {last = prev;} else {next.prev = prev;x.next = null;}x.item = null;size--;modCount++;return element;}
查找操作

查找一个节点通常是从头节点开始遍历链表,直到找到目标节点或到达尾部节点。

源码:  

public int indexOf(Object o) {int index = 0;for (Node<E> x = first; x != null; x = x.next) {if (o == null ? x.item == null : o.equals(x.item))return index;++index;}return -1;
}

基于源码,他有以下特点:

  1. 快速插入和删除:
    • 插入和删除操作的时间复杂度通常为 O(1)。
    • 插入和删除操作只需要修改相邻节点的引用,而不需要移动元素。
    • 这一点与 ArrayList 不同,ArrayList 在插入或删除时可能需要移动大量元素。
  2. 随机访问相对较慢:
    • 随机访问某个位置的元素需要从头或尾开始遍历,时间复杂度为 O(n)。
    • 这是因为链表不像数组那样连续存储数据,无法直接通过索引访问元素。
  3. 允许重复元素
  4. 允许 null
  5. 线程不安全:
    • LinkedList 的基本操作(如 addgetsetremove 等)不是线程安全的。
    • 如果多个线程并发地访问或修改 LinkedList,需要外部同步机制。
  6. 所有指定位置的操作都是从头开始遍历进行的:
    对于基于索引的操作(如 get(int index) 或 set(int index, E element)),遍历会从头部开始直到到达指定的位置。
  7. 有序性:即元素的顺序保持不变,除非显式地重新排序或修改链表。
  8. 实现多种接口:

   LinkedList 实现了 ListDeque(双端队列)、Queue 等接口,因此可以作为队列、堆栈或双端队列使用。

什么时候会使用到这些接口?

使用 List 接口

如果你需要一个有序的列表,那么使用 List 接口。

例如:

  • 维护一个动态的历史记录列表:例如浏览器的历史记录,或者最近打开的文件列表。
  • 实现一个灵活的任务列表:其中任务可能被添加或移除,并且这种操作非常频繁。

使用 Queue 接口

如果你需要一个先进先出的数据结构,那么使用 Queue 接口。

例如:

  • 消息队列:处理来自客户端的消息或事件。
  • 任务队列:例如用于异步处理的作业队列,如批量处理任务、打印队列等。
  • 缓存队列:例如在内存中缓存最近访问的数据项,当队列满时移除最旧的数据项。

使用 Deque 接口

如果你需要一个可以从两端进行操作的数据结构,那么使用 Deque 接口。

例如:

  • 滑动窗口算法:在算法问题中,需要维护一个固定长度的滑动窗口,例如计算滑动窗口内的最大值或最小值。
  • 后进先出(LIFO)操作:虽然 Deque 支持 FIFO 和 LIFO 操作,但如果你需要一个简单的栈,可以使用 Deque 的相关方法。
  • 双端队列队列:例如在实现优先级队列时,你可以使用双端队列来存储不同优先级的元素。

示例代码

import java.util.LinkedList;
import java.util.Queue;
import java.util.Deque;public class LinkedListExample {public static void main(String[] args) {// 使用 LinkedList 作为 QueueQueue<String> queue = new LinkedList<>();queue.offer("One");queue.offer("Two");System.out.println("Queue: " + queue);System.out.println("Poll from Queue: " + queue.poll());// 使用 LinkedList 作为 DequeDeque<Integer> deque = new LinkedList<>();deque.addFirst(1);deque.addLast(2);System.out.println("Deque: " + deque);System.out.println("Remove from front of Deque: " + deque.removeFirst());}
}

相关文章:

LinkedList底层原理

节点&#xff08;Node&#xff09;结构 LinkedList 的核心是一个内部类 Node&#xff0c;每个 Node 对象代表链表中的一个元素&#xff0c;并且每个节点包含三个部分&#xff1a; 元素值 (item)&#xff1a;存储实际的数据。前驱节点引用 (prev)&#xff1a;指向当前节点前面…...

CSS技巧专栏:一日一例 11 -纯CSS实现多彩渐变按钮系列特效

CSS技巧专栏:一日一例 11 -纯CSS实现多彩渐变按钮系列特效 本篇,推荐给你几个按钮,先看一下图片 本例图片 案例分析 这是一个系列的按钮,它们具有共同的特点: 底层按钮层,具有一个彩色的渐变边框,上层是依据hover效果需要,可以是渐变,可以时白色。 鼠标hover效果…...

基于微信小程序+SpringBoot+Vue的自助点餐系统(带1w+文档)

基于微信小程序SpringBootVue的自助点餐系统(带1w文档) 基于微信小程序SpringBootVue的自助点餐系统(带1w文档) 基于微信小程序的自助点餐系统前后台分离&#xff0c;让商品订单&#xff0c;用户反馈信息&#xff0c;商品信息等相关信息集中在后台让管理员管理&#xff0c;让用…...

04-Charles中的Map Remote和Map Local介绍

Charles提供了Map Remote和Map Local两个功能。 Map Remote是将指定的网络请求重定向到另一个网址。Map Local是将指定的网络请求重定向到本地文件。 一、Map Remote 假设代码中调用了接口A&#xff0c;但是接口A的响应结果不能满足需求&#xff1b;此时&#xff0c;有另一个…...

R语言优雅的进行广义可加模型泊松回归分析

泊松回归&#xff08;Poisson regression&#xff09;是以结局变量为计数结果时的一种回归分析。泊松回归在我们的生活中应用非常广泛&#xff0c;例如&#xff1a;1分钟内过马路人数&#xff0c;1天内火车站的旅客流动数&#xff0c;1天内的银行取钱人数&#xff0c;一周内的销…...

大模型学习笔记十四:Agent模型微调

文章目录 一、大模型需要Agent技术的原因二、Prompt Engineering可以实现Agent吗&#xff1f;&#xff08;1&#xff09;ReAct原理展示和代码&#xff08;2&#xff09;ModelScope&#xff08;3&#xff09;AutoGPT&#xff08;4&#xff09;ToolLLaMA 三、既然AutoGPT可以满足…...

大疆创新2025校招内推

大疆2025校招-内推 一、我们是谁&#xff1f; 大疆研发软件团队&#xff0c;致力于把大疆的硬件设备和大疆用户紧密连接在一起&#xff0c;我们的使命是“让机器有温度&#xff0c;让数据会说话”。 在消费和手持团队&#xff0c;我们的温度来自于激发用户灵感并助力用户创作…...

搜索引擎项目(四)

SearchEngine 王宇璇/submit - 码云 - 开源中国 (gitee.com) 基于Servlet完成前后端交互 WebServlet("/searcher") public class DocSearcherServlet extends HttpServlet {private static DocSearcher docSearcher new DocSearcher();private ObjectMapper obje…...

声音克隆一键本地化部署 GPT-SoVITS

文章目录 GPT-SoVITS 介绍1:GPT-SoVITS安装2:GPT-SoVITS使用2.1 人声伴奏分离,去混响去延时工具2.2 语音切分工具2.3 语音降噪工具2.4 中文批量离线ASR工具2.5 语音文本校对标注工具GPT-SoVITS 介绍 GPT-SoVITS: 是一个由RVC变声器创始人“花儿不哭”推出的免费开源项目。…...

使用【Easypoi】实现百万数据导出

本文使用easypoi实现百万级数据导出 文章目录 前言一、一般情况下导出二、解决思路三、实现步骤导入依赖重写方法调用实现 结束 前言 下文实现了通过easypoi实现将百万级数据导出 一、一般情况下导出 一般导出流程&#xff08;简单导出&#xff09;&#xff1a; 创建对应的…...

GRL-图强化学习

GRL代码解析 一、agent.py二、drl.py三、env.py四、policy.py五、utils.py 一、agent.py 这个Python文件agent.py实现了一个强化学习&#xff08;Reinforcement Learning, RL&#xff09;的智能体&#xff0c;用于在图环境&#xff08;graph environment&#xff09;中进行学习…...

昇思25天学习打卡营第22天|Pix2Pix实现图像转换

Pix2Pix图像转换学习总结 概述 Pix2Pix是一种基于条件生成对抗网络&#xff08;cGAN&#xff09;的深度学习模型&#xff0c;旨在实现不同图像风格之间的转换&#xff0c;如从语义标签到真实图像、灰度图到彩色图、航拍图到地图等。这一模型由Phillip Isola等人在2017年提出&…...

全感知、全覆盖、全智能的智慧快消开源了。

智慧快消视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。AI安全管理平台&…...

ABC364:D - K-th Nearest(二分)

题目 在一条数线上有 NQNQ 个点 A1,…,AN,B1,…,BQA1​,…,AN​,B1​,…,BQ​ &#xff0c;其中点 AiAi​ 的坐标为 aiai​ &#xff0c;点 BjBj​ 的坐标为 bjbj​ 。 就每个点 j1,2,…,Qj1,2,…,Q 回答下面的问题&#xff1a; 设 XX 是 A1,A2,…,ANA1​,A2​,…,AN​ 中最…...

hive中分区与分桶的区别

过去&#xff0c;在学习hive的过程中学习过分桶与分区。但是&#xff0c;却未曾将分区与分桶做详细比较。今天&#xff0c;回顾skew join时涉及到了分桶这一概念&#xff0c;一时间无法区分出分区与分桶的区别。查阅资料&#xff0c;特地记录下来。 一、Hive分区 1.分区一般是…...

Blender材质-PBR与纹理材质

1.PBR PBR:Physically Based Rendering 基于物理的渲染 BRDF:Bidirection Reflectance Distribution Function 双向散射分散函数 材质着色操作如下图&#xff1a; 2.纹理材质 左上角&#xff1a;编辑器类型中选择&#xff0c;着色器编辑器 新建着色器 -> 新建纹理 -> 新…...

微软的Edge浏览器如何设置兼容模式

微软的Edge浏览器如何设置兼容模式&#xff1f; Microsoft Edge 在浏览部分网站的时候&#xff0c;会被标记为不兼容&#xff0c;会有此网站需要Internet Explorer的提示&#xff0c;虽然可以手动点击在 Microsoft Edge 中继续浏览&#xff0c;但是操作起来相对复杂&#xff0c…...

SpringBoot开启多端口探究(1)

文章目录 前情提要发散探索从management.port开始确定否需要开启额外端口额外端口是如何开启的ManagementContextFactory的故事从哪儿来创建过程 management 相关API如何被注册 小结 前情提要 最近遇到一个需求&#xff0c;在单个服务进程上开启多网络端口&#xff0c;将API的…...

优化算法:2.粒子群算法(PSO)及Python实现

一、定义 粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;PSO&#xff09;是一种模拟鸟群觅食行为的优化算法。想象一群鸟在寻找食物&#xff0c;每只鸟都在尝试找到食物最多的位置。它们通过互相交流信息&#xff0c;逐渐向食物最多的地方聚集。PSO就是基于这…...

ThreadLocal面试三道题

针对ThreadLocal的面试题&#xff0c;我将按照由简单到困难的顺序给出三道题目&#xff0c;并附上参考答案的概要。 1. 简单题&#xff1a;请简述ThreadLocal是什么&#xff0c;以及它的主要作用。 参考答案&#xff1a; ThreadLocal是Java中的一个类&#xff0c;用于提供线…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...