数据结构入门到入土——链表(完)LinkedList

目录

一,双向链表

1.单向链表的缺点

2.什么是双向链表?

3.自主实现双向链表

接口实现:

二,LinkedList

1.LinkedList的使用

1.1 什么是LinkedList?

1.2 LinkedList的使用

1.LinkedList的构造

2.LinkedList的其它常用方法介绍

3.LinkedList的遍历

三,ArrayList与LinkedList的区别


一,双向链表

1.单向链表的缺点

再了解单向链表的实现以及使用过后,我们发现单项链表存在存在缺点:

1.如下图,当cur访问下一个节点时无法再访问到上一个节点

2.尾插法的时间复杂度为O(N)

为应对该类问题,于是就有了双向链表

2.什么是双向链表?

定义:双向链表由一系列的节点组成,每个节点包含两个指针,分别指向前一个节点和后一个节点。与单向链表不同,双向链表可以从任意节点开始,向前或向后遍历链表。

如下图所示:

这是一个无头双向链表,从中我们不难看出它与无头单向链表的区别:

1.不仅有头节点通过next进行顺序访问,还有尾节点通过prev进行逆序访问

2.额外有一个prev域访问上一个已访问过的节点

3.自主实现双向链表

接口实现:

接口部分:

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 display();//清空单链表public void clear();}

接口重写部分:

public class MyList implements IList{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;//尾节点//头插法@Overridepublic void addFirst(int data) {ListNode node = new ListNode(data);if (this.head == null) {this.head = node;this.last = node;} else {node.next = this.head;this.head.prev = node;this.head = node;}}//尾插法@Overridepublic void addLast(int data) {ListNode node = new ListNode(data);if (this.head == null) {this.head = node;this.last = node;} else {this.last.next = node;node.prev = this.last;this.last = node;}}//任意位置插入,第一个数据节点为0号下标@Overridepublic void addIndex(int index, int data) {ListNode node = new ListNode(data);ListNode cur = this.head;if (index >= 0 && index <= size()) {if (index == 0) {addFirst(data);return;}if (index == size()) {addLast(data);return;}int count = 1;while (cur != null) {ListNode curNext = cur.next;if (count == index) {node.next = curNext;curNext.prev = node;cur.next = node;node.prev = cur;}count++;cur = cur.next;}} else {throw new IndexException("添加下标异常!");}}//查找是否包含关键字key是否在单链表当中@Overridepublic boolean contains(int key) {ListNode cur = this.head;while (cur != null) {if (cur.val == key) {return true;}cur = cur.next;}return false;}//删除第一次出现关键字为key的节点@Overridepublic void remove(int key) {ListNode cur = this.head;while (cur != null) {ListNode curNext = cur.next;if (cur.val == key) {//删头节点if (cur.prev == null) {//this.head.val = null;this.head = head.next;head.prev = null;return;}//删尾节点if (cur.next == null) {//this.last.val == null;this.last = last.prev;last.next = null;return;}curNext.prev = cur.prev;cur.prev.next = curNext;return;}cur = cur.next;}}@Overridepublic void removeAllKey(int key) {ListNode cur = this.head;while (cur != null) {ListNode curNext = cur.next;if (cur.val == key) {//删头节点if (cur.prev == null) {//this.head.val = null;this.head = head.next;head.prev = null;} else if (cur.next == null) {//this.last.val == null;this.last = last.prev;last.next = null;} else {curNext.prev = cur.prev;cur.prev.next = curNext;}}cur = cur.next;}}//得到单链表的长度@Overridepublic int size() {ListNode cur = this.head;int count = 0;while (cur != null) {count++;cur = cur.next;}return count;}//打印单链表@Overridepublic void display() {ListNode cur = this.head;if (head == null) {System.out.println("[" + "]");} else {System.out.print("[");while (cur != null) {if (cur == last) {System.out.print(cur.val);} else {System.out.print(cur.val + " ");}cur = cur.next;}System.out.println("]");}}//清空单链表@Overridepublic void clear() {ListNode cur = this.head;while (cur.next != null) {ListNode curNext = cur.next;//cur.val =null;cur.prev = null;cur.next = null;}this.head = null;this.last = null;}
}

二,LinkedList

LinkedList是一个双向链表,以上双向链表便是模拟LinkedList

1.LinkedList的使用

1.1 什么是LinkedList?

LinkedList的官方文档

LinkedList的底层是双向链表结构,由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引用将节点连接起来了,因此在在任意位置插入或者删除元素时,不需要搬移元素,效率比较高。
在集合框架中,LinkedList也实现了List接口
【说明】
1. LinkedList实现了List接口
2. LinkedList的底层使用了双向链表
3. LinkedList没有实现RandomAccess接口,因此LinkedList不支持随机访问
4. LinkedList的任意位置插入和删除元素时效率比较高,时间复杂度为O(1)
5. LinkedList比较适合任意位置插入的场景

1.2 LinkedList的使用

1.LinkedList的构造
方法
解释
LikedList()
无参构造
public LinkedList(Collection<? extends E> c)
使用其他集合容器中元素构造 List

public static void main(String[] args) {

// 构造一个空的LinkedList

List<Integer> list1 = new LinkedList<>();

List<String> list2 = new java.util.ArrayList<>();

list2.add("JavaSE");

list2.add("JavaWeb");

list2.add("JavaEE");

// 使用ArrayList构造LinkedList

List<String> list3 = new LinkedList<>(list2);

}

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 位置元素
boolean 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<Integer> list = new LinkedList<>();

list.add(1); // add(elem): 表示尾插

list.add(2);

list.add(3);

list.add(4);

list.add(5);

list.add(6);

list.add(7);

System.out.println(list.size());

System.out.println(list);

// 在起始位置插入0

list.add(0, 0); // add(index, elem): index位置插入元素elem

System.out.println(list);

list.remove(); // remove(): 删除第一个元素,内部调用的是removeFirst()

list.removeFirst(); // removeFirst(): 删除第一个元素

list.removeLast(); // removeLast(): 删除最后元素

list.remove(1); // remove(index): 删除index位置的元素

System.out.println(list);

// contains(elem): 检测elem元素是否存在,如果存在返回true,否则返回false

if(!list.contains(1)){

list.add(0, 1);

}

list.add(1);

System.out.println(list);

System.out.println(list.indexOf(1)); // indexOf(elem): 从前往后找到第一个elem的位置

System.out.println(list.lastIndexOf(1)); // lastIndexOf(elem): 从后往前找第一个1的位置

int elem = list.get(0); // get(index): 获取指定位置元素

list.set(0, 100); // set(index, elem): index位置的元素设置为elem

System.out.println(list);

// subList(from, to): list[from, to)之间的元素构造一个新的LinkedList返回

List<Integer> copy = list.subList(0, 3);

System.out.println(list);

System.out.println(copy);

list.clear(); // list中元素清空

System.out.println(list.size());

}

3.LinkedList的遍历

public static void main(String[] args) {

LinkedList<Integer> list = new LinkedList<>();

list.add(1); // add(elem): 表示尾插

list.add(2);

list.add(3);

list.add(4);

list.add(5);

list.add(6);

list.add(7);

System.out.println(list.size());

// foreach遍历

for (int e:list) {

System.out.print(e + " ");

}

System.out.println();

// 使用迭代器遍历---正向遍历

ListIterator<Integer> it = list.listIterator();

while(it.hasNext()){

System.out.print(it.next()+ " ");

}

System.out.println();

// 使用反向迭代器---反向遍历

ListIterator<Integer> rit = list.listIterator(list.size());

while (rit.hasPrevious()){

System.out.print(rit.previous() +" ");

}

System.out.println();

}

三,ArrayList与LinkedList的区别

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

完。

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

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

相关文章

elementUI点击el-card选中变色,且点击别的空白处不变色

1. <script>的data中添加属性&#xff1a; selectIndex: 0 2.<template>中添加el-card元素&#xff1a; click.native调用原生click方法。 click.native是在vue中&#xff0c;避免vue父模块调用成了vue成子模块中的this.emit(click, value)的方法&#xff0c;而…

Pruning Papers

[ICML 2020] Rigging the Lottery: Making All Tickets Winners 整个训练过程中mask是动态的&#xff0c;有drop和grow两步&#xff0c;drop是根据权重绝对值的大小丢弃&#xff0c;grow是根据剩下激活的权重中梯度绝对值生长没有先prune再finetune/retrain的两阶段过程 Laye…

C++-nullptr-类型推导

1、nullptr&#xff08;掌握&#xff09;&#xff08;NULL 就是0&#xff09; NULL 在源码当中就是0&#xff0c;因此可能会存在一些二义性的问题。 #include <iostream> #include <memory> using namespace std;void func(int a) {cout << "a " …

[原创][R语言]股票分析实战[9]:周内第N天转换为星期N因子

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ联系: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、D…

工业异常检测AnomalyGPT-Demo试跑

写在前面&#xff1a;如果你有大的cpu和gpu可以使用&#xff0c;直接根据官方的安装说明就可以&#xff0c;如果没有&#xff0c;可以点进来试着看一下我个人的安装经验。 一、试跑环境 NVIDIA4090显卡24g,cpu内存33G&#xff0c;交换空间8g,操作系统ubuntu22.04(试跑过程cpu…

问题 F: 分巧克力

题目描述 儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。小明一共有 N 块巧克力&#xff0c;其中第i 块HiWi 的方格组成的长方形。 为了公平起见&#xff0c;小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。 切出的巧克力需要满足&am…

SEO写作:撰写在Google上排名的博客文章的13个技巧

随着排名的提高&#xff0c;您的网站可以提高其整体知名度。最终目标是通过有效的优化来推动自然流量&#xff0c;增加转化率&#xff0c;并实现业务目标。 如果你不针对搜索引擎优化你的内容&#xff0c;你的网站可能会在搜索引擎结果页面&#xff08;SERP&#xff09;上出现…

第7章-第9节-Java中的Stream流(链式调用)

1、什么是Stream流 Lambda表达式&#xff0c;基于Lambda所带来的函数式编程&#xff0c;又引入了一个全新的Stream概念&#xff0c;用于解决集合类库既有的鼻端。 2、案例 假设现在有一个需求&#xff0c; 将list集合中姓张的元素过滤到一个新的集合中&#xff1b;然后将过滤…

Realm Management Extension领域管理扩展简介

本博客介绍了领域管理扩展(RME),这是Arm的架构扩展。RME是Arm机密计算架构(Arm CCA)的硬件组件,同时包括软件元素。RME动态地将资源和内存转移到新的受保护的地址空间,高特权软件或TrustZone固件无法访问。由于存在这个地址空间,Arm CCA构建了受保护的执行环境,称为领…

详解Oracle数据库的启动

Oracle数据库的启动&#xff0c;其概念可参考Overview of Instance and Database Startup。 其过程可参见下图&#xff1a; 当数据库从关闭状态进入打开数据库状态时&#xff0c;它会经历以下阶段。 阶段Mount状态描述1实例在没有挂载数据库的情况下启动实例已启动&#xff…

Numerical calculation and its application based on NumPy/SciPy

Numerical calculation and its application based on NumPy/SciPy 线性代表微分和积分统计插值 线性代表 { 3 x 1 2 x 2 8 − 3 x 1 5 x 2 − 1 \begin{cases} \begin{equation} \begin{split} 3x_12x_2 8\\ -3x_15x_2 -1 \end{split} \end{equation} \end{cases} {3x1​…

SpringBoot 注解超全详解

使用注解的优势&#xff1a; 采用纯java代码&#xff0c;不在需要配置繁杂的xml文件 在配置中也可享受面向对象带来的好处 类型安全对重构可以提供良好的支持 减少复杂配置文件的同时亦能享受到springIoC容器提供的功能 1 注解详解&#xff08;配备了完善的释义&#xff0…

深入了解鸿鹄工程项目管理系统源码:功能清单与项目模块的深度解析

工程项目管理软件是现代项目管理中不可或缺的工具&#xff0c;它能够帮助项目团队更高效地组织和协调工作。本文将介绍一款功能强大的工程项目管理软件&#xff0c;该软件采用先进的Vue、Uniapp、Layui等技术框架&#xff0c;涵盖了项目策划决策、规划设计、施工建设到竣工交付…

uni-app顶部导航条固定

1.准备 scroll-view 滚动容器&#xff0c;包裹需要滚动的区域 <!-- 自定义导航栏 --><CustomNavbar /><scroll-view class"scroll-view" scroll-y><!-- 自定义轮播图 --><XtxSwiper :bannerList"bannerList" /><!-- 首页…

5分钟彻底搞懂什么是token

大家好啊&#xff0c;我是董董灿。 几年前在一次工作中&#xff0c;第一次接触到自然语言处理模型 BERT。 当时在评估这个模型的性能时&#xff0c;领导说这个模型的性能需要达到了 200 token 每秒&#xff0c;虽然知道这是一个性能指标&#xff0c;但是对 token 这个概念却不…

新年喝酒有讲究,怎么喝葡萄酒呢?

中国的新年有着独特又深远的意义&#xff0c;无论人在天涯海角&#xff0c;回家团圆是每个人的心愿。新年亲朋好友欢聚一堂&#xff0c;没有酒哪有气氛&#xff0c;所以喝酒是必不可少的活动项目。云仓酒庄的品牌雷盛红酒LEESON分享那么&#xff0c;新年喝啥酒&#xff0c;葡萄…

小明找位置(100%用例)C卷 (JavaPythonC++Node.jsC语言)

小朋友出操,按学号从小到大排成一列;小明来迟了,请你给小明出个主意,让他尽快找到他应该排的位置。 算法复杂度要求不高于nLog(n);学号为整数类型,队列规模<=10000; 输入描述 1、第一行:输入已排成队列的小朋友的学号(正整数),以”,”隔开例: 93 95 97 100 102 123 1…

GB/T 28886-2012 建筑用塑料门检测

建筑用塑料门是指基材为未增塑聚氯乙烯PVC-U型材并内衬增强型钢的门&#xff0c;根据用途分为室外门和室内用门。 GB/T 28886-2012 建筑用塑料门检测项目 测试项目 测试标准 外观 GB/T 28886 门的装配 GB/T 28886 力学性能 GB/T 11793 抗风压性能 GB/T 7106 水密性 …

CRC16常见的标准

本文整理CRC16常见的标准算法&#xff0c;有以下几种&#xff1a; 模式多项式初始值数据位序结果处理CRC16_CCITTx16x12x51&#xff08;0x1021&#xff09;0x0000低位在前&#xff0c;高位在后与0x0000异或CRC16_CCITT_FALSEx16x12x51&#xff08;0x1021&#xff09;0xFFFF低位…

uniapp 创建组件

组件&#xff1a;用于将某个功能的 HTML、CSS、JS 封装到一个文件中&#xff0c;提高代码的复用性和可维护性。 创建组件 一、在根目录中创建 components 文件夹&#xff0c;右键点击新建组件。 二、输入组件名称、选择默认模板、点击创建组件。 三、在组件中正常编写内容即可…