做网站要执照吗/百度seo关键词报价
前言
前面有很详细的讲过线性表(顺序表和链表),当时讲的链表以单链表为主,但在实际应用中双链表有很多应用场景,例如大家熟知的LinkedList。
双链表与单链表区别
单链表和双链表都是线性表的链式实现,它们的主要区别在于节点结构。单链表的节点包含数据字段 data
和一个指向下一个节点的指针 next
,而双链表的节点除了 data
和 next
,还包含指向前一个节点的指针 pre
。这个区别会导致它们在操作上有些差异。
单链表:
单链表的一个节点,有储存数据的data
,还有后驱节点next
(指针)。单链表想要遍历的操作都得从前节点—>后节点。
双链表:
双链表的一个节点,有存储数据的data
,也有后驱节点next
(指针),这和单链表是一样的,但它还有一个前驱节点pre
(指针)。
双链表结构的设计
上一篇讲单链表的时候,当时设计一个带头结点的链表就错过了不带头结点操作方式,这里双链表就不带头结点设计实现。所以本文构造的这个双链表是:不带头节点、带尾指针(tail)的双向链表。
对于链表主体:
public class DoubleLinkedList<T> {private Node<T> head;private Node<T> tail;private int size;public DoubleLinkedList(){this.head = null;this.tail = null;size = 0;}public void addHead(T data){}public void add(T data, int index){}public void addTail(T data){}public void deleteHead(){}public void delete(int index){}public void deleteTail(int index){}public T get(int index){}public int getSize() {return size;}private static class Node<T> {T data;Node<T> pre;Node<T> next;public Node() {}public Node(T data) {this.data = data;}}
}
具体操作分析
对于一个链表主要的操作还是增删,查询的话不做详细解释。
剖析增删其实可以发现大概有头插入、编号插入、末尾插入、头删除、编号删除、尾删除几种情况。然而这几种关于头尾操作的可能会遇到临界点比如链表为空时插入删除、或者删除节点链表为空。
这个操作是不带头结点的操作,所以复杂性会高一些!
头插入
头插入区分头为空和头不为空两种情况
头为空:这种情况head和tail都指向新节点
头不为空:
- 新节点的next指向head
- head的pre指向新节点
- head指向新节点(认新节点为head)
尾插入
尾插需要考虑tail为null和不为null的情况。流程和头插类似,需要考虑tail指针最后的指向。
tail为null:此时head也为null,head和tail指向新节点。
tail不为null:
- 新节点的pre指向tail
- tail的next指向新节点
- tail指向新节点
编号插入
按编号插入分情况讨论,如果是头插或者尾插就直接调用对应的方法。普通方法的实现方式比较灵活,可以找到前驱节点和后驱节点,然后进行指针插入,但是往往很多时候只用一个节点完成表示和相关操作,就非常考验对表示的理解,这里假设只找到preNode节点。
index为0:调用头插
index为size:调用尾插
index在(0,size):
- 找到前驱节点preNode
- 新节点next指向nextNode(此时用preNode.next表示)
- nextNode(此时新节点.next和preNode.next都可表示)的pre指向新节点
- preNode的next指向新节点
- 新节点的pre指向preNode
头删除
头删除需要注意的就是删除不为空时候头删除只和head节点有关
head不为null:
- head = head.next 表示头指针指向下一个节点
- head 如果不为null(有可能就一个节点),head.pre = null 断掉与前一个节点联系 ;head如果为null,说明之前就一个节点head和pre都指向第一个节点,此时需要设置tail为null。
尾删除
尾删除和头删除类似,考虑好tail节点情况
如果tail不为null:
- tail = tail.pre
- 如果tail不为null,那么tail.next = null 表示删除最后一个,如果tail为null,说明之前head和tail都指向一个唯一节点,这时候需要head = null。
编号删除
编号删除和编号插入类似,先考虑是否为头尾操作,然后再进行正常操作。
index为0:调用头删
index为size:调用尾删
index在(0,size):
- 找到待删除节点current
- 前驱节点(current.pre)的next指向后驱节点(current.next)
- 后驱节点的pre指向前驱节点
完整代码
根据上面的流程,实现一个不带头结点的双链表,在查找方面,可以根据靠头近还是尾近,选择从头或者尾开始遍历。
代码:
/** 不带头节点的*/
package code.linearStructure;/*** @date 2023.11.02* @author bigsai* @param <T>*/
public class DoubleLinkedList<T> {private Node<T> head;private Node<T> tail;private int size;public DoubleLinkedList() {this.head = null;this.tail = null;size = 0;}// 在链表头部添加元素public void addHead(T data) {Node<T> newNode = new Node<>(data);if (head == null) {head = newNode;tail = newNode;} else {newNode.next = head;head.pre = newNode;head = newNode;}size++;}// 在指定位置插入元素public void add(T data, int index) {if (index < 0 || index > size) {throw new IndexOutOfBoundsException("Index is out of bounds");}if (index == 0) {addHead(data);} else if (index == size) {addTail(data);} else {Node<T> newNode = new Node<>(data);Node<T> preNode = getNode(index-1);//step 1 2 新节点与后驱节点建立联系newNode.next = preNode;preNode.next.pre = newNode;//step 3 4 新节点与前驱节点建立联系preNode.next = newNode;newNode.pre = preNode;size++;}}// 在链表尾部添加元素public void addTail(T data) {Node<T> newNode = new Node<>(data);if (tail == null) {head = newNode;tail = newNode;} else {newNode.pre = tail;tail.next = newNode;tail = newNode;}size++;}// 删除头部元素public void deleteHead() {if (head != null) {head = head.next;if (head != null) {head.pre = null;} else { //此时说明之前head和tail都指向唯一节点,链表删除之后head和tail都应该指向nulltail = null;}size--;}}// 删除指定位置的元素public void delete(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("Index is out of bounds");}if (index == 0) {deleteHead();} else if (index == size - 1) {deleteTail();} else {Node<T> current = getNode(index);current.pre.next = current.next;current.next.pre = current.pre;size--;}}// 删除尾部元素public void deleteTail() {if (tail != null) {tail = tail.pre;if (tail != null) {tail.next = null;} else {//此时说明之前head和tail都指向唯一节点,链表删除之后head和tail都应该指向nullhead = null;}size--;}}// 获取指定位置的元素public T get(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("Index is out of bounds");}Node<T> node = getNode(index);return node.data;}// 获取链表的大小public int getSize() {return size;}private Node<T> getNode(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("Index is out of bounds");}if (index < size / 2) {Node<T> current = head;for (int i = 0; i < index; i++) {current = current.next;}return current;} else {Node<T> current = tail;for (int i = size - 1; i > index; i--) {current = current.pre;}return current;}}private static class Node<T> {T data;Node<T> pre;Node<T> next;public Node(T data) {this.data = data;}}
}
结语
在插入删除的步骤,很多人可能因为繁琐的过程而弄不明白,这个操作的写法可能是多样的,但本质操作都是一致的,要保证能成功表示节点并操作,这个可以画个图一步一步捋一下,看到其他不同版本有差距也是正常的。
还有很多人可能对一堆next.next搞不清楚,那我教你一个技巧,如果在等号右侧,那么它表示一个节点,如果在等号左侧,那么除了最后一个.next其他的表示节点。例如node.next.next.next可以看成(node.next.next).next。
在做数据结构与算法链表相关题的时候,不同题可能给不同节点去完成插入、删除操作。这种情况操作时候要谨慎先后顺序防止破坏链表结构。
系列仓库地址:https://github.com/javasmall/bigsai-algorithm
csdn专栏:数据结构与算法
原创不易,还请三连支持一下!
相关文章:

数据结构与算法—双链表
前言 前面有很详细的讲过线性表(顺序表和链表),当时讲的链表以单链表为主,但在实际应用中双链表有很多应用场景,例如大家熟知的LinkedList。 双链表与单链表区别 单链表和双链表都是线性表的链式实现,它们的主要区别在于节点结构…...

linux继续循环案例测试ping网络,目录下的文件权限循环输出
第一:查看本机ip #ip addr 通过脚本访问本机ip1-100,是否可以ping通,并显示结果,上图 知识点 ping -c 数字1 -w 数字1,向目的ip发送1个数据包,等待1秒,无回复中止 &>/dev/null 知…...

关于SSP3D复现
关于SSP3D复现的问题 准备工作 下载Xshell和XFTP:家校免费版下载链接连接服务器(可能需要与服务器处在相同网络下)GitHub上下载源码:SSP3D 左上角新建会话,输入名称和主机 点击左侧菜单“用户身份验证”,…...

在直播系统中使用RTSP协议传递视频
目录 概述 1、环境准备 2、拉流URL地址 3、导播软件取流 (1)OBS中拉取RTSP流 (2)芯象中拉取RTSP流 (3)vMix中拉取RTSP流 写在最后 概述 提到RTSP协议,很容易想到RTMP协议,它…...

Notion汉化
Notion真无语,汉化版都没有。真的无力吐槽。 2023.11.7汉化经历 教程链接:github Reamd7/notion-zh_CN at 2.4.20-handmade (github.com) 网页版: 油猴下载插件。 Notion中文汉化 浏览器插件下载 windows: github realse 这…...

echarts有背景的柱状图,鼠标滑过提示信息都是展示背景柱状图的值
// 上一篇文章介绍了如何实现有背景的柱状图,现在又遇到一个问题,鼠标滑过柱子,提示信息是背景柱子的值,解决方案,自定义tooltip的formatter,上代码tooltip: {//鼠标悬浮提示数据formatter: function (para…...

华为防火墙基本原理工作方法总结
防火墙只会对tcp首包syn建立会话表,其它丢掉,如synack,ack udp直接建立会话表 icmp只对首包请求包建立会话表,其它包,如应答的不会建立直接丢掉 防火墙状态查看: rule name trust_untrust source-zone tru…...

Spring Cloud之多级缓存
目录 传统缓存 多级缓存 JVM进程缓存 Caffeine 缓存驱逐策略 实现进程缓存 常用Lua语法 数据类型 变量声明 循环使用 定义函数 条件控制 安装OpenResty 实现Nginx业务逻辑编写 请求参数解析 实现lua访问tomcat JSON的序列化和反序列化 Tomcat的集群负载均衡 …...

融云荣登「2023 年度 PaaS 企业排行榜」
11 月 2 日,中国科学院旗下《互联网周刊》颁布“2023 年度 PaaS 企业排行榜”,融云荣登榜单。关注【融云全球互联网通信云】了解更多 根据中国信息通信研究院《云计算白皮书 2023》:2022 年,PaaS 增长强势,总收入 342 …...

YOLOv8轻量化模型:模型轻量化设计 | 轻量级可重参化EfficientRep| 来自YOLOv6思想
💡💡💡本文解决什么问题:在几乎不保证精度下降的前提下,轻量级模型创新设计 EfficientRep 在关键点检测任务中 | GFLOPs从9.6降低至8.5, mAP50从0.921下降至0.912,mAP50-95从0.697提升至0.779 YOLO轻量化模型专栏:http://t.csdnimg.cn/AeaEF 1.YOLOv6介绍 论文…...

【JavaSE】基础笔记 - 类和对象(下)
目录 1、this引用 1.1、为什么要有this引用 1.2、什么是this引用 1.3、 this引用的特性 2、 对象的构造及初始化 2.1、 如何初始化对象 2.2、构造方法 2.2.1、概念 2.2.2、特性 2.3、默认初始化 2.4、就地初始化 上篇:【JavaSE】基础笔记 - 类和对象&#…...

浅析刚入门Python初学者的注意事项
文章目录 一、注意你的Python版本1.print()函数2.raw_input()与input()3.比较符号,使用!替换<>4.repr函数5.exec()函数 二、新手常遇到的问题1、如何写多行程序?2、如何执行.py文件?3、and,or,not4、True和False…...

2023NOIP A层联测26 总结
T1 求 ∑ i 1 n ∑ j i n ( ⨁ k i j a k ) 2 \sum\limits_{i1}^n\sum\limits_{ji}^n\left(\bigoplus\limits_{ki}^{j}a_k\right)^2 i1∑nji∑n(ki⨁jak)2, n , a i ≤ 2 1 0 5 n,a_i\le2\times10^5 n,ai≤2105。先转成前缀和,然后就没思…...

响应式编程-Project Reactor Mono 介绍
响应式编程-Project Reactor Mono 介绍 本文以Mono的角度来介绍Reactor编程,Flux的使用同理。 初体验 Web应用 controller 方法在Spring webmvc 和 Spring webFlux下Controller方法实现示例如下: Spring webmvc: GetMapping("/test1") …...

R语言实操记录——导出高清图片(矢量图)
R语言 R语言实操记录——导出高清图片(矢量图) 文章目录 R语言一、起因(闲聊,可跳过)二、如何在R中导出高清图片(矢量图)2.1、保存为EPS图片格式后转AI编辑2.2、保存为PDF格式(推荐…...

Apache Doris 开源最顶级基于MPP架构的高性能实时分析数据库
背景介绍 Apache Doris是一个基于MPP架构的易于使用,高性能和实时的分析数据库,以其极高的速度和易用性而闻名。海量数据下返回查询结果仅需亚秒级响应时间,不仅可以支持高并发点查询场景,还可以支持高通量复杂分析场景。 这些都…...

webgoat-Request Forgeries 请求伪造
(A8:2013) Request Forgeries Cross-Site Request Forgeries 跨站请求伪造,又称一键攻击或会话骑乘,简称CSRF (有时发音为 sea-surf)或 XSRF,是一种恶意利用网站,其中传输未经授权的命令 来自网站信任的用…...

【flask跨域问题】解决它
大概7-8年前,前后端还没开始分离或者刚开始分离的之前,跨域问题很多。 后来我就没在遇到过了,这次做一个小项目,又遇到了,记录下。 现在前端的脚手架都自己能解决了。 1. 跨域 是因为出于浏览器的同源策略限制。同源…...

虚幻引擎:如何在工程里面添加插件
1.在自己的项目中安装插件 在content目录下创建一个Plugins的文件,将插件文件放进去即可 2.在软件上安装,这样所有创建的项目都会带有此插件 将插件放在自己软件的这个目录下就好了...

SpringCloud Alibaba 【四】Openfeign
Openfeign配置与使用 前言介绍openfeign使用openfeign导入依赖启动类正式使用测试结果 前言 在springcloud中消费者项目需要调用提供者项目的接口,一开始用的是RestTemplate中的方法。但是RestTemplate进行远程调用时,直接调用controller层的接口&#…...

语音信号的线性预测分析、合成及MATLAB编程设计实现
需要的基础:AR模型、列文森-杜宾递推法 推荐阅读: 基于线性预测的语音编码原理解析 基于线性预测的语音编码原理解析 这篇文章和上一篇类似 语音信号的线性预测分析及其Matlab源码 这篇文章是要付费看的,但是他能预览的那部分写的确实好 语…...

rabbitMQ rascal/amqplib报错 Error: Unexpected close 排查
以下是一些可能导致此 RabbitMQ 客户端或任何其他 RabbitMQ 客户端中的套接字读取或写入失败的常见场景 1.错过(客户端)心跳 第一个常见原因是RabbitMQ 检测到心跳丢失。发生这种情况时,RabbitMQ 将添加一个有关它的日志条目,然…...

一文1600字使用Postman搞定各种接口token实战(建议收藏)
现在许多项目都使用jwt来实现用户登录和数据权限,校验过用户的用户名和密码后,会向用户响应一段经过加密的token,在这段token中可能储存了数据权限等,在后期的访问中,需要携带这段token,后台解析这段token才…...

Vue自定义组件学习笔记
专业描述: vue关于自定义组件的描述中,父子组件是相对的概念,父组件表示引用当前组件的组件,子组件就是当前组件; 1)关于props和emits选项的理解 1.props:我们平时写的.vue文件实际上就是一个自定义组件,只是一般不会考虑复用性,不会去设置props选项,…...

王道p18 第12题假设 A中的 n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素。若存在主元素,则输出该元素:否则输出-1
视频讲解在:👇 p18 第12题 c语言实现王道数据结构课后习题_哔哩哔哩_bilibili 从前向后扫描数组元素,标记出一个可能成为主元素的元素 Num。然后重新计数,确认 Num 是否是主元素。 我们可分为以下两步: 1.选取候选的主元素。依…...

OpenTiny Vue 3.11.0 发布:增加富文本、ColorPicker等4个新组件,迎来了贡献者大爆发!
非常高兴跟大家宣布,2023年10月24日,OpenTiny Vue 发布了 v3.11.0 🎉。 OpenTiny 每次大版本发布,都会给大家带来一些实用的新特性,8.14 我们发布了 v3.10.0 版本,增加了4个新组件,组件 Demo 支…...

vivado查看报告和消息5
1、可配置报告策略 “ Configurable Report Strategies ” ( 可配置报告策略 ) 支持在 Vivado 工程模式下运行综合与实现的每个步骤之后选择 要运行的报告命令。根据设计阶段、设计复杂性和用户首选项, 需自动生成一组不同的报告以供频繁查…...

基于javaweb+mysql的jsp+servlet学生成绩管理系统(管理员、教师、学生)
博主24h在线,想要源码文档部署视频直接私聊,9.9元拿走! 基于javawebmysql的jspservlet学生成绩管理系统(管理员、教师、学生)(javajspservletjavabeanmysqltomcat) 运行环境 Java≥8、MySQL≥5.7、Tomcat≥8 开发工具 eclipse/idea/myecl…...

基于卷积优化算法的无人机航迹规划-附代码
基于卷积优化算法的无人机航迹规划 文章目录 基于卷积优化算法的无人机航迹规划1.卷积优化搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用卷积优化算法来优化无人机航迹规划。 …...

科技云报道:不卷自研大模型,金山办公如何创新生成式AI?
科技云报道原创。 过去大半年里,很多人对大模型的前景寄予厚望。主流观点认为,每个行业、每款产品都可以通过大模型“重做一遍”。 “重做一遍”听起来想象空间很大,但实际上多数大模型产品需要漫长的训练周期和海量资源投入,落…...