深入解析:[数据结构] LinkedList

news/2025/9/21 12:22:37/文章来源:https://www.cnblogs.com/wzzkaifa/p/19103456

1. 什么是 LinkedList

  LinkedList (官方文档)

LinkedList是Java集合框架中的一个双向链表实现,位于java.util包中。它实现了ListDeque接口,支持高效的插入和删除操作,但随机访问性能较差


2. LinkedList 的 特性

  • 双向链表结构:每个节点(Node)包含前驱(prev)、后继(next)和当前元素(item)的引用
  • 非连续内存存储:与ArrayList不同,LinkedList的元素在内存中不连续存储
  • 动态大小:无需预先分配空间,大小随元素增减动态变化


3. LinkedList 实现的接口

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

4. LinkedList 的使用

4.1 LinkedList 的创建

① LinkedList 的创建

public static void main(String[] args) {
List list1 = new LinkedList<>();
list1.add(1);
list1.add(2);
list1.add(3);
System.out.println(list1);
}

② 用 ArrayList 来构造 LinkedList

public static void main(String[] args) {
List list2 = new java.util.ArrayList<>();
list2.add(22);
list2.add(122);
list2.add(233);
list2.add(344);
System.out.println(list2);
List list3 = new LinkedList<>(list2);
}

4.2 LinkedList常用方法的介绍

方法解释
 boolean add (E e)尾插 e
void add (int index , E element)将 e 插入到 index 位置
boolean addAll (Collection<? extends E> c)尾插 c 中的元素
E remove (int index)删除 index 位置的元素
boolead remove (Object o)删除遇到的第一个元素 o
E get (int index)获取下标 index 的元素
E set (int index , E element)将下标 index 位置的元素设置为 element
void clear ()清空
boolean contains (Object o)判断 o 是否包含在线性表中
int indexOf (Object o)返回第一个 o 所在位置的下标
int lastindexOf (Object o)返回最后一个 o 所在位置的下标
List<E> subList (int fromIndex , int toIndex)截取部分 list

部分方法演示

public static void main(String[] args) {
LinkedList list = new LinkedList<>();
list.add(11);
list.add(22);
list.add(33);
list.add(44);
list.add(99);
list.add(22);
System.out.println(list);//[11, 22, 33, 44, 99, 22]
list.add(0,88);//指定位置插入
System.out.println(list);//[88, 11, 22, 33, 44, 99, 22]
list.remove(0);//删除指定下标元素
list.removeFirst();//删除第一个元素
list.removeLast();//删除最后一个元素
System.out.println(list);//[22, 33, 44, 99]
list.set(3,00);//将下标为3的元素设置为0
System.out.println(list);//[22, 33, 44, 0]
List list1 = list.subList(0,4);//截取list 从[0,4)下标 并复制为新的链表
System.out.println(list1);//[22, 33, 44, 0]
list.clear();//清空链表
System.out.println(list);//[]
}

4.3 LinkedList 的遍历

注意 : 以下代码省略了 main 方法

LinkedList list = new LinkedList<>();
list.add(11);
list.add(22);
list.add(33);
list.add(44);
list.add(99);
list.add(22);

① for each 遍历

//for each 遍历
for (int e:list) {
System.out.print(e+" ");//11 22 33 44 99 22
}
System.out.println();

② for 循环遍历

//for 循环遍历
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i)+" ");//11 22 33 44 99 22
}
System.out.println();

③ 迭代器遍历(正向遍历)

//迭代器遍历(正向遍历)
ListIterator it = list.listIterator();
while (it.hasNext()){
System.out.print(it.next()+" ");//11 22 33 44 99 22
}
System.out.println();

④ 迭代器遍历(方向遍历)

ListIterator it1 = list.listIterator(list.size());
while (it1.hasPrevious()){
System.out.print(it1.previous()+" ");//22 99 44 33 22 11
}
System.out.println();

5. LinkedList 与 ArrayList 的对比

5.1 场景选择

场景推荐使用原因
频繁随机访问ArrayList基于数组的索引访问效率更高(O (1))
频繁插入删除LinkedList链表结构修改引用即可,无需移动元素
内存敏感场景ArrayList链表节点有额外内存开销
作为队列使用LinkedList实现了 Deque 接口,队列操作更便捷

5.2 区别

不同点ArrayListLinkedList
存储空间上物理上一定连续逻辑上连续,但物理上不一定连续
随机访问支持,时间复杂度 O (1)不支持,时间复杂度 O (N)
头插需要搬移元素,效率低,时间复杂度 O (N)只需修改引用的指向,时间复杂度 O (1)
插入空间不够时需要扩容没有容量的概念
应用场景元素高效存储 + 频繁访问任意位置插入和删除频繁

6. LinkedList 的模拟实现

①接口

public interface IList {
//头插法
public void addFirst(int data);
//尾插法
public void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data);
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key);
//删除第一次出现关键字为key的节点
public void remove(int key);
//删除所有值为key的节点
public void removeAllKey(int key);
//得到单链表的长度
public int size();
public void clear();
public void display();
}

②具体方法的实现

public class MyLinkedList implements IList  {
static class ListNode{//内部类
public ListNode prev;//结点的前驱
public ListNode next;//结点的后继
public int val;
public ListNode(int val){
this.val = val;
}
}
//类成员
public ListNode head;//头结点
public ListNode last;//尾结点
//头插法
@Override
public void addFirst(int data) {
ListNode node = new ListNode(data);
if(head == null){
head = last = node;
}else{
node.next = head;
head.prev = node;
head = node;
}
}
//尾插法
@Override
public void addLast(int data) {
ListNode node = new ListNode(data);
if(head == null){
head = last = node;
}else{
last.next = node;
node.prev = last;
last = node;
}
}
//寻找下标为 index 的结点
private ListNode findIndex(int index){
ListNode cur = head;
while (index != 0) {
cur = cur.next;
index--;
}
return cur;
}
//任意位置插入结点
@Override
public void addIndex(int index, int data) {
int len = size();
if(indexsize()){
return;
}
if(index == 0){
addFirst(data);
return;
}
if(index == len){
addLast(data);
return;
}
ListNode node = new ListNode(data);
ListNode cur = findIndex(index);
cur.prev.next = node;
node.next = cur;
node.prev = cur.prev;
cur.prev = node;
}
//查找是否包含 key 在链表中
@Override
public boolean contains(int key) {
ListNode cur = head;
while (cur!=null){
if(cur.val == key){
return true;
}
cur = cur.next;
}
return false;
}
@Override
public void remove(int key) {
ListNode cur = head;
while(cur!=null){
if(cur.val == key){
//删除
if(cur == head){
head = head.next;
if(head != null) {
head.prev = null;
}
}else {
cur.prev.next = cur.next;
if (cur.next == null) {
last = last.prev;
} else {
cur.next.prev = cur.prev;
}
}
return;
}
cur = cur.next;
}
}
@Override
public void removeAllKey(int key) {
ListNode cur = head;
while(cur!=null){
if(cur.val == key){
//删除
if(cur == head){
head = head.next;
if(head != null) {
head.prev = null;
}
}else {
cur.prev.next = cur.next;
if (cur.next == null) {
last = last.prev;
} else {
cur.next.prev = cur.prev;
}
}
}
cur = cur.next;
}
}
//求链表的长度
@Override
public int size() {
if(head == null){
return 0;
}
ListNode cur = head;
int count = 0;
while (cur!=null){
count++;
cur = cur.next;
}
return count;
}
//清空链表
@Override
public void clear() {
ListNode cur = head;
while (cur!=null){
ListNode curN = cur.next;
cur.prev = null;
cur.next = null;
cur = curN;
}
}
//打印链表
@Override
public void display() {
ListNode cur = head;
while (cur!=null){
System.out.print(cur.val+" ");
cur = cur.next;
}
System.out.println();
}
}

③测试

public class Test {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addFirst(12);//头插法
myLinkedList.addLast(22);//尾插法
myLinkedList.addFirst(45);
myLinkedList.addFirst(22);
myLinkedList.display();//22 45 12 22
myLinkedList.addIndex(2,44);//任意位置插入
myLinkedList.display();//22 45 44 12 22
myLinkedList.remove(45);//删除元素 45
myLinkedList.display();//22 44 12 22
myLinkedList.removeAllKey(22);//删除所有元素 22
myLinkedList.display();//44 12
}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/908770.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

US$34 MB ESL Emulator

MB ESL EmulatorTop 4 Reasons To Get MB ESL Emulator1. This device works with Mercedes EIS.2. It emulates both of old (W202, 208, 210) and new (203, 208, 211, 639).3. ESL types functioning.You can use t…

采用python test测试http接口

采用python test测试http接口pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco"…

CF2147 Codeforces Global Round 29 (Div. 1 + Div. 2) 解题报告

A 题挂机半天,B 题挂机半天,D 题脑子犯蠢,3t寄了。省流 A 题挂机半天,B 题挂机半天,D 题脑子犯蠢,3t寄了。9.20 内含剧透,请vp后再来。 赛前 白天刚打完失败的 ccpc 网络赛,不过心态已经调整的非常平和,然后抱…

US$29 Vag R250 VW Audi Dashboard Programmer Free Shipping

R250 VW Audi Dashboard Programmer You can use R250 to program Siemens/VDO new cryptography system Description:This product looks like a small box that needs to be connected to a PC running Win98/Me/XP…

数字图像基础知识

前言 数字图像(Digital Image),又称数码图像或数位图像,以数字形式存储于电子设备中。 有多种方式可以生成数字图像。 一种是物理收集,例如使用数码相机、扫描仪、卫星遥感器、红外/热成像仪、核磁共振 MRI 等设备…

详细介绍:农业XR数字融合工作站,赋能农业专业实践学习

详细介绍:农业XR数字融合工作站,赋能农业专业实践学习pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&…

标题:分享一个值得推荐的免费云服务——阿贝云

最近在搭建个人网站时,无意中发现了一个提供免费虚拟主机和免费云服务器的平台——阿贝云。经过一段时间的使用,我真的被它的稳定性和易用性打动了! 阿贝云不仅提供了完全免费的云服务器资源,还支持多种常见环境,…

PPT2Note使用说明

PPT2Note使用说明 简介 PPT2Note是一个应用于教学的使用工具,可以自动抓取在教学大屏上打开的PPT文件并发送至绑定的用户笔记中。解决了PPT翻页太快漏截图问题。

第三周:面向对象入门2与类的识别

第三周:面向对象入门2与类的识别集美大学课程实验报告-第三周:面向对象入门2与类的识别项目名称 内容课程名称 Java程序设计班级 网安2412指导教师 郑如滨学生姓名 王嘉熙学号 202421336061实验项目名称 面向对象入门…

详细介绍:Flink-新增 Kafka source 引发状态丢失导致启动失败

详细介绍:Flink-新增 Kafka source 引发状态丢失导致启动失败2025-09-21 11:59 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !impor…

【面向接口编程(IOP)典型场景】底层组件如何实现回调通知上层应用系统? 另外一种实现方式

【面向接口编程(IOP)典型场景】底层组件如何实现回调通知上层应用系统? 另外一种实现方式偶然看到一篇文章, https://www.cnblogs.com/buguge/p/19055703 对这篇文章的设计进行了更改。 原来设计的类图 和流程图 :…

GEE训练教程:Sentinel-2卫星影像揭秘飓风奥蒂斯破坏力 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

设置Redis在CentOS7上的自启动配置

在CentOS 7系统中,要设置Redis服务的自启动,需要配置Redis服务以便它能够在系统启动时自动运行。为此,我们将使用 systemctl命令,这是CentOS 7 中管理服务的推荐方法。 首先,确保已经正确地安装了Redis服务并且它…

挂载配置文件以Docker启动Redis服务

要使用Docker启动Redis服务,并挂载配置文件,首先需要确保已经安装好Docker环境。以下是具体步骤和相关的解释: 步骤1:准备Redis配置文件 您需要准备一个Redis配置文件,此文件会包含Redis服务器的配置指令。创建一…

abc418d

AtCoder ABC418 D XNOR Operation link 题意 给定一个长度为 \(n\) 的 01 串 \(s\),每次可以选择相邻的两个位置。如果两个位置字符相同,把它们缩成 \(1\),否则缩成 \(0\)。求 \(s\) 中有多少个子串经过操作可以变成…

Chapter 6 Joining Images

# 这个是numpy的功能 # imgHor = np.hstack((img, img)) # imgVer = np.vstack((img, img))def stackImages(scale, imgArray):rows = len(imgArray)cols = len(imgArray[0])rowsAvailable = isinstance(imgArray[0], …

动态主机配置协议(DHCP)中的中继机制及其配置

动态主机配置协议(Dynamic Host Configuration Protocol, DHCP)是一种网络协议,用于自动分配IP地址和其他网络配置信息给网络设备。在一个复杂的网络环境中,尤其是在不同子网之间,一台DHCP服务器可能无法直接为所…

DDD - 概念复习

领域 在 DDD 中,“领域(Domain)” 指的是软件要解决的 “业务范围” 及其包含的所有业务概念、规则和逻辑。 简单来说:如果你开发的是 “电商系统”,那么 “电商” 就是核心领域,包含 “商品、订单、支付、物流”…

进一步理解自适应卡尔曼滤波(AKF) - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

CSP-J1S1_2025

考点小记与错题整理。考点小记等比数列求和公式 已知等比数列 \(\{a_n\}\) ,公比为 \(q\),前 \(n\) 项和为 \(S_n\) 。 则有 \(S_n = \begin{cases} na_1, &q = 1 \\ \large \frac{a_1(1 - q ^ n)}{1 - q}, &…