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

数据结构--线性表双向链表的实现

目录

思路设计

总体思维导图

插入部分

头插法+尾插法

任意位置插入

删除部分

头结点

尾节点

中间节点

只有头结点且删除的就是头结点

​编辑

清空链表部分

遍历清空链表的所有节点

不遍历清空

各部分代码

Main部分

MyListedList部分

IndexOutOfException部分

总结


思路设计

设计Main,MyListedList,IndexOutOfException 三个文件。

Ma负责主函数的运行,MyList负责各种方法,IndexOut负责输入错误的提示。

总体思维导图

插入部分

头插法+尾插法

任意位置插入

删除部分

头结点

尾节点

中间节点

只有头结点且删除的就是头结点

清空链表部分

遍历清空链表的所有节点

不遍历清空

各部分代码

Main部分

public class Main {public static void main(String[] args) {//这个是顺序表的写法,现在是双向链表//MyListedList<Integer> myListedList= new MyListedList();MyListedList myListedList= new MyListedList();myListedList.addFirst(1);myListedList.addFirst(2);myListedList.addFirst(3);myListedList.addFirst(4);/*myListedList.addLast(1);myListedList.addLast(2);myListedList.addLast(3);myListedList.addLast(4);*///System.out.println(myListedList.size());//System.out.println(myListedList.contains(10));//myListedList.display();//myListedList.addIndex(0,99);//myListedList.display();myListedList.removeAllKey(1);myListedList.clear();myListedList.display();}
}

MyListedList部分

public class MyListedList {static class ListNode{private int val;private ListNode prev;private ListNode next;//重写构造方法得以调用//才能保证下面传入的data能使用//ListNode node = new ListNode(data);public ListNode(int val) {this.val = val;}}//双向链表的头节点public ListNode head;//双向链表的尾节点public ListNode last;//得到单链表的长度//size,display,contains都是要遍历定义头指针public int size(){ListNode cur = head;int count = 0;while (cur != null){count++;cur = cur.next;}return count;}public void display(){//遍历定义一个头结点指针,让其不断往后走ListNode cur = head;while (cur != null){System.out.print(cur.val+" ");cur = cur.next;}System.out.println();}//查找是否包含关键字key是否在单链表当中public boolean contains(int key){ListNode cur = head;while (cur != null){if(cur.val == key){return true;}cur = cur.next;}return false;}//头插法public void addFirst(int data){ListNode node = new ListNode(data);//如果插入的节点的前后指针都是空的话//要修改链表里面的头尾指针if(head == null){head = node;last = node;}else {//先改变next再改变pervnode.next = head;head.prev = node;head = node;}}//尾插法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;//或者 last = last.next}}//任意位置插入,第一个数据节点为0号下标public void addIndex(int index,int data){checkIndex(index);if(index == 0){addFirst(data);return;}if(index == size()){addLast(data);return;}//声明curListNode cur = seachIndex(index);ListNode node = new ListNode(data);node.next = cur;cur.prev.next = node;node.prev = cur.prev;cur.prev = node;}//定义cur找到插入的位置private ListNode seachIndex(int index){ListNode cur = head;while (index != 0){cur = cur.next;index--;}return cur;}private void checkIndex(int index){if (index < 0 || index > size()){//可以自定义抛出RuntimeException(运行异常)一个异常throw new IndexOutOfException("index 不合法!"+index);}}//删除第一次出现关键字为key的节点public void remove(int key){ListNode cur = head;if(head == null) {head = cur;last = cur;}while (cur != null){if(cur.val == key){//如果要删除的是头结点if(cur == head){//移动位置head = head.next;//只有头节点,且其就是删除的节点if(head != null){head.prev = null;}else {last = null;}}else {//删除中间节点if(cur.next != null){cur.prev.next = cur.next;cur.next.prev = cur.prev;} else {//删除尾巴节点cur.prev.next = cur.next;last = last.prev;}}return;}else {cur = cur.next;}}}//删除所有值为key的节点public void removeAllKey(int key){ListNode cur = head;if(head == null) {head = cur;last = cur;}while (cur != null){if(cur.val == key){//如果要删除的是头结点if(cur == head){//移动位置head = head.next;//只有头节点,且其就是删除的节点if(head != null){head.prev = null;}else {last = null;}}else {//删除中间节点if(cur.next != null){cur.prev.next = cur.next;cur.next.prev = cur.prev;} else {//删除尾巴节点cur.prev.next = cur.next;last = last.prev;}}//删除key数据了之后往后走,查看//是否还有要删除的数据去遍历cur = cur.next;//return;}else {//就算这个数据不是我要删除的数据,我也往后走去遍历cur = cur.next;}}}public void clear(){ListNode cur = head;while (cur != null){ListNode curNext = cur.next;if(cur == null){cur = curNext;}else {cur.next = null;cur.prev = null;cur = curNext;}}head = null;last = null;}
}

IndexOutOfException部分

public class IndexOutOfException extends RuntimeException{//提供两个构造方法public IndexOutOfException() {}public IndexOutOfException(String message) {super(message);}
}

总结

部分方法大体上写法都大致相同,关键在于具体方法部分,比如:删除的节点就只有一个,而且这个要删除的节点就是头结点,那么这种特殊情况是在写完正常删除操作后,输入数据判断得到的结果,针对这样的情况要画图分析,一步一步慢慢思考如何设计程序代码,出错没有关系,再次调试画图看看有没有漏掉的地方,一次次修改相信最终会获得成功完成任务的代码。

数据结构的核心就是,代码容易写,思考最难想的一个学习过程,由此可见画图在帮助我们理清思路,规整代码写法的时候就尤为重要!


希望这篇博客能给读者在学习数据结构时提供一些帮助。

相关文章:

数据结构--线性表双向链表的实现

目录 思路设计 总体思维导图 插入部分 头插法尾插法 任意位置插入 删除部分 头结点 尾节点 中间节点 只有头结点且删除的就是头结点 ​编辑 清空链表部分 遍历清空链表的所有节点 不遍历清空 各部分代码 Main部分 MyListedList部分 IndexOutOfException部分 …...

第一个Flutter应用(一)

1、创建项目 1.1 新建 1.2 选择Flutter SDK的位置 1.3 项目名称 英文单词加下划线起名规范&#xff0c;其他默认即可。 1.4 点击运行 发生报错显示我们的JAVA版本不符合 1.5 更改版本设置 1.6 再次启动项目 2、分析页面代码 以下是lib/main.dart的源代码&#xff08;为了阅…...

批量查询快递单号物流信息:高效掌握最后更新动态

在电商和物流行业蓬勃发展的今天&#xff0c;快递单号的物流信息追踪显得尤为重要。对于商家和客户来说&#xff0c;了解包裹的最后更新物流状态是确保货物安全、及时送达的关键。本文将介绍如何批量查询快递单号的物流信息&#xff0c;帮助您高效掌握每个包裹的最新动态。 1运…...

随着硬件水平的提升,LabVIEW有哪些过去的编程方法被淘汰掉了

随着硬件水平的不断提升&#xff0c;尤其是处理器性能、存储能力、通信速度等方面的飞跃&#xff0c;LabVIEW的一些早期编程方法逐渐被更高效、现代的编程技术所取代。以下是一些随着硬件升级而逐步淘汰的LabVIEW编程方法和技术&#xff1a; 1. 低效的数据流传输方式 过去由于…...

Leetcode 206.反转链表

题目链接&#xff1a;206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 题目描述: 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 解题思路…...

基于springboot和vue.js 养老院管理系统设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm springcloud等开发框架&#xff09; vue .net php phython node.js uniapp小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆…...

高效数据处理:MapReduce与Hive的实战应用

文章目录 hive分析汇总互联网日志分析1.项目需求2.数据说明3.算法思路 用户电影推荐1.项目需求2.数据说明3.算法思路4.解题步骤 简单数据统计WordCount数据说明 疫情数据分析1.项目需求2.数据说明step1:创建ods层数据表step2&#xff1a;创建dwd层数据表step3&#xff1a;创建d…...

【含开题报告+文档+PPT+源码】基于springboot的迎新系统

开题报告 大学迎新系统是为了满足大学在新生入学时的信息化处理需求而开发的系统。在传统方式下&#xff0c;我们新生接待工作是需要新生报名表&#xff0c;就使得我们需要耗费大量的纸张&#xff0c;这将造成资源浪费。在接待新生的时候需要让新生勾选、填写大量的表格&#…...

C#-委托delegate

C#-委托delegate 通常情况下&#xff0c;函数内部需要调用其他函数来实现代码的重用&#xff0c;但这样有一个问题&#xff1a; 如果需要更换所调用的函数则需要对该函数的定义再次修改&#xff0c; 事实上&#xff0c;在程序运行过程中&#xff0c;函数也是作为一个存储在堆中…...

编译Thingsboard3.7.0的过程记录

1、首先去掉test测试&#xff0c;否则会有一堆问题&#xff0c;pom.xml修改如下&#xff1a; <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>${surefire.version}</ve…...

vulnhub-THE PLANETS-EARTH靶机

下载并导入靶机至VMWare&#xff0c;设置网络模式为NAT&#xff0c;开机 开启攻击机&#xff08;kali&#xff09;&#xff0c;也设置为Nat模式&#xff0c;与靶机处于同一网段 扫描靶机ip Nmap 192.168.114.0/24 扫描网段内活跃的主机 可以推断靶机ip为192.168.114.129 扫描…...

【C语言】分支和循环(2)

&#x1f914;个人主页: 起名字真南 &#x1f619;个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 关系操作符2 条件操作符3 逻辑操作符 &#xff1a;|| &#xff0c;&& &#xff0c;&#xff01;3.1 逻辑取反运算符3.2 与运算符3.3 或运算符3.4 练习闰年判断3.5 短…...

Python数据分析-远程办公与心理健康分析

一、研究背景 随着信息技术的飞速发展和全球化的推进&#xff0c;远程工作&#xff08;Remote Work&#xff09;成为越来越多企业和员工的选择。尤其是在2020年新冠疫情&#xff08;COVID-19&#xff09;爆发后&#xff0c;全球范围内的封锁措施使得远程工作模式迅速普及。根据…...

LabVIEW提高开发效率技巧----使用动态事件

在LabVIEW开发过程中&#xff0c;用户交互行为可能是多样且不可预知的。为应对这些变化&#xff0c;使用动态事件是一种有效的策略。本文将从多个角度详细介绍动态事件的概念及其在LabVIEW开发中的应用技巧&#xff0c;并结合实际案例&#xff0c;说明如何通过动态事件提高程序…...

【STM32开发之寄存器版】(五)-窗口看门狗WWDG

一、前言 窗口看门狗简介&#xff1a; 窗口看门狗通常被用来监测&#xff0c;由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位变成0前被刷新&#xff0c;看门狗电路在达到预置的时间周期时&#xff0c;会产生一个M…...

Leetcode203.移除链表元素-Python

题目链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&a…...

属性拷贝MapStruct

端请求通过VO对象接收&#xff0c;并通过DTO对象进行流转&#xff0c;最后转换成DO对象与数据库DAO层进行交互&#xff0c;反之亦然。 当业务简单的时候&#xff0c;可以通过手动编码getter/setter函数来复制对象属性。但是当业务变的复杂&#xff0c;对象属性变得很多&#x…...

Chromium 添加书签功能浅析c++

1、在点击添加书签时候此UI控制逻辑代码在 chrome\browser\ui\views\bookmarks\bookmark_bar_view.cc chrome\browser\ui\views\bookmarks\bookmark_bar_view.h 可以在此看到完成 移除 按钮逻辑&#xff0c;以及书签监听事件等。。。 // Implementation for BookmarkNodeAdd…...

Spring Cloud Netflix Ribbon 负载均衡详解和案例示范

1. 引言 在传统的集中式架构中&#xff0c;负载均衡器一般是放置在服务器端的&#xff0c;例如 Nginx等。随着微服务架构的兴起&#xff0c;服务实例的数量和部署地点变得更加动态和分布式&#xff0c;这使得在客户端进行负载均衡成为了一种可行且更灵活的方案。Netflix Ribbo…...

Armeria gPRC 高级特性 - 装饰器、无框架请求、阻塞处理器、Nacos集成、负载均衡、rpc异常处理、文档服务......

文章目录 定义一个示例高级特性装饰器概述简单案例多种装饰方式 无框架请求概述使用方式 阻塞任务处理器背景概述多种使用方式 rpc 异常统一处理使用方式更详细的异常信息 Armeria 提供 gRPC 客户端多种调用方式同步调用异步调用使用装饰器 负载均衡简单案例Armeria 提供的所有…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

Ascend NPU上适配Step-Audio模型

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

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...