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

Java实现单向链表

✅作者简介:热爱Java后端开发的一名学习者,大家可以跟我一起讨论各种问题喔。
🍎个人主页:Hhzzy99
🍊个人信条:坚持就是胜利!
💞当前专栏:Java数据结构与算法
🥭本文内容:Java实现单向链表的两种形式

单向链表


文章目录

  • 单向链表
    • 单向链表的特点
    • 单向链表代码实现(无哨兵)
    • 测试T1
    • 单向链表代码实现(有哨兵)
    • 测试T2
  • 结语


单向链表的特点

单向链表,顾名思义它是单向的,一个节点有数据部分和next指针部分组成,数据部分用来保存数据,next指针指向下一个节点,所以单向链表的每个节点都只知道下一个节点是什么,而不知道上一个节点是什么。
在这里插入图片描述

单向链表代码实现(无哨兵)

/****@description:单向链表*@author: Hhzzy99*@date:2023/3/4**/
public class SinglyLinkedList implements Iterable<Integer>{//整体private Node head = null;//头指针@Overridepublic Iterator<Integer> iterator() {return new Iterator<Integer>() {Node p = head;@Overridepublic boolean hasNext() {//是否有下一个元素return p != null;}@Overridepublic Integer next() {//返回当前值,并指向下一个元素int value = p.value;p = p.next;return value;}};}/*** 节点类*/private static class Node{int value;//值Node next;//下一个结点指针public Node(int value, Node next) {this.value = value;this.next = next;}}/*** 链表头添加元素* @param value 元素值*/public void addFirst(int value){//1.链表为空
//        head = new Node(value,null);//2.链表非空head = new Node(value,head);}//链表遍历public void loop1(Consumer<Integer> consumer){Node p = head;while(p != null){consumer.accept(p.value);p = p.next;}}/*** for循环+函数式接口Consumer* @param consumer 函数式接口*/public void loop2(Consumer<Integer> consumer){for (Node p = head; p != null; p = p.next){consumer.accept(p.value);}}/*** 最后一个元素* @return Node p*/private Node findLast(){if(head == null)return null;Node p;for(p = head; p.next != null; p = p.next){}return p;}/*** 最后面添加元素* @param value 元素值*/public void addLast(int value){Node last = findLast();if(last == null){addFirst(value);return;}last.next = new Node(value,null);}/*** 寻找索引为index的元素* @param index 寻找的元素的索引* @return Node p*/private Node findNode(int index){int i = 0;for(Node p = head; p.next != null; p = p.next,i++){if(i == index)return p;}return null;}/*** 获取索引位置的元素* @param index 索引值* @throws IllegalArgumentException - 找不到索引,抛出index非法异常*/public int get(int index){Node p = findNode(index);if(p == null)//抛异常throw new IllegalArgumentException(String.format("index [%d] 不合法%n",index));return p.value;}/*** 向索引位置插入元素* @param index 索引值* @param value 待插入值* @throws IllegalArgumentException - 找不到索引,抛出index非法异常*/public void insert(int index, int value){if(index == 0){addFirst(value);return;}Node prev = findNode(index - 1);//找到上一个节点if (prev == null)//找不到throw new IllegalArgumentException(String.format("index [%d] 不合法%n",index));prev.next = new Node(value,prev.next);}/*** 删除第一个元素* @throws IllegalArgumentException - 找不到索引,抛出index非法异常*/public void removeFirst(){if(head == null)throw new IllegalArgumentException(String.format("index [%d] 不合法%n",0));head = head.next;}/*** 删除索引为index的元素* @param index 要删除元素的索引值* @throws IllegalArgumentException - 找不到索引,抛出index非法异常*/public void remove(int index){if(index == 0){removeFirst();return;}Node prev = findNode(index - 1);//上一个节点if (prev == null)throw new IllegalArgumentException(String.format("index [%d] 不合法%n",index));if (prev.next == null)throw new IllegalArgumentException(String.format("index [%d] 不合法%n",index));prev.next = prev.next.next;//prev.next是被删除的元素}
}

测试T1

/****@description:测试*@author: Hhzzy99*@date:2023/3/4**/
public class TestSinglyLinkedList {private SinglyLinkedList getSinglyLinkedList() {//addFirst    addLastSinglyLinkedList singlyLinkedList = new SinglyLinkedList();singlyLinkedList.addFirst(1);singlyLinkedList.addLast(2);singlyLinkedList.addLast(3);singlyLinkedList.addLast(4);return singlyLinkedList;}@Test//测试get()public void test01(){SinglyLinkedList singlyLinkedList = getSinglyLinkedList();System.out.println(singlyLinkedList.get(2));System.out.println(singlyLinkedList.get(5));}@Test//测试insertpublic void test02(){SinglyLinkedList singlyLinkedList = getSinglyLinkedList();singlyLinkedList.loop1(value -> {System.out.print(value + ",");});System.out.println();System.out.println("=============");singlyLinkedList.insert(0,18);singlyLinkedList.loop1(value -> {System.out.print(value + ",");});}@Test//测试removepublic void test03(){SinglyLinkedList singlyLinkedList = getSinglyLinkedList();singlyLinkedList.loop1(value -> {System.out.print(value + ",");});System.out.println();singlyLinkedList.removeFirst();for (Integer ele:singlyLinkedList) {System.out.print(ele + ",");}System.out.println();}@Test//测似removepublic void test04(){SinglyLinkedList singlyLinkedList = getSinglyLinkedList();singlyLinkedList.loop1(value -> {System.out.print(value + ",");});System.out.println();singlyLinkedList.remove(2);for (Integer ele:singlyLinkedList) {System.out.print(ele + ",");}System.out.println();}
}

test01:第一个获取到值,第二个超出索引,抛出预设的异常
在这里插入图片描述
test02:符合预期
在这里插入图片描述
test03:符合预期
在这里插入图片描述
test04:符合预期
在这里插入图片描述

单向链表代码实现(有哨兵)


/****@description:单向链表(带哨兵)*@author: Hhzzy99*@date:2023/3/4**/
public class SinglyLinkedListSentinel implements Iterable<Integer>{//整体private Node head = new Node(999,null);//头指针->哨兵@Overridepublic Iterator<Integer> iterator() {return new Iterator<Integer>() {Node p = head.next;@Overridepublic boolean hasNext() {//是否有下一个元素return p != null;}@Overridepublic Integer next() {//返回当前值,并指向下一个元素int value = p.value;p = p.next;return value;}};}/*** 节点类*/private static class Node{int value;//值Node next;//下一个结点指针public Node(int value, Node next) {this.value = value;this.next = next;}}/*** 链表头添加元素* @param value 元素值*/public void addFirst(int value){insert(0,value);}//链表遍历public void loop1(Consumer<Integer> consumer){Node p = head.next;while(p != null){consumer.accept(p.value);p = p.next;}}/*** for循环+函数式接口Consumer* @param consumer 函数式接口*/public void loop2(Consumer<Integer> consumer){for (Node p = head.next; p != null; p = p.next){consumer.accept(p.value);}}/*** 最后一个元素* @return Node p*/private Node findLast(){Node p;for(p = head; p.next != null; p = p.next){}return p;}/*** 最后面添加元素* @param value 元素值*/public void addLast(int value){Node last = findLast();last.next = new Node(value,null);}/*** 寻找索引为index的元素* @param index 寻找的元素的索引* @return Node p*/private Node findNode(int index){int i = -1;//从哨兵位置开始(-1)for(Node p = head; p.next != null; p = p.next,i++){if(i == index)return p;}return null;}/*** 获取索引位置的元素* @param index 索引值* @throws IllegalArgumentException - 找不到索引,抛出index非法异常*/public int get(int index){Node p = findNode(index);if(p == null)//抛异常throw new IllegalArgumentException(String.format("index [%d] 不合法%n",index));return p.value;}/*** 向索引位置插入元素* @param index 索引值* @param value 待插入值* @throws IllegalArgumentException - 找不到索引,抛出index非法异常*/public void insert(int index, int value){if(index == 0){addFirst(value);return;}Node prev = findNode(index - 1);//找到上一个节点if (prev == null)//找不到throw new IllegalArgumentException(String.format("index [%d] 不合法%n",index));prev.next = new Node(value,prev.next);}/*** 删除第一个元素* @throws IllegalArgumentException - 找不到索引,抛出index非法异常*/public void removeFirst(){remove(0);}/*** 删除索引为index的元素* @param index 要删除元素的索引值* @throws IllegalArgumentException - 找不到索引,抛出index非法异常*/public void remove(int index){Node prev = findNode(index - 1);//上一个节点if (prev == null)throw new IllegalArgumentException(String.format("index [%d] 不合法%n",index));if (prev.next == null)throw new IllegalArgumentException(String.format("index [%d] 不合法%n",index));prev.next = prev.next.next;//prev.next是被删除的元素}
}

测试T2

private SinglyLinkedListSentinel getSinglyLinkedListSentinel() {SinglyLinkedListSentinel list = new SinglyLinkedListSentinel();list.addLast(1);list.addLast(2);list.addLast(3);list.addLast(4);return list;}@Testpublic void test05(){SinglyLinkedListSentinel list = getSinglyLinkedListSentinel();list.loop2(ele->{System.out.print(ele+",");});System.out.println();System.out.println(list.get(2));System.out.println(list.get(10));//抛异常}@Testpublic void test06(){SinglyLinkedListSentinel list = getSinglyLinkedListSentinel();list.loop2(ele->{System.out.print(ele+",");});System.out.println();list.insert(2,7);list.loop2(ele->{System.out.print(ele+",");});System.out.println();list.remove(1);list.loop2(ele->{System.out.print(ele+",");});
//        list.insert(7,19);//抛异常}

test05:符合预期,抛出预设异常
在这里插入图片描述
test06:符合预期
在这里插入图片描述


结语

本文展示了Java实现单向链表的代码,希望对大家有所帮助!大家如果感兴趣可以点点赞,关注一下,你们的支持是我最强大的动力,非常感谢您的阅读(❁´◡`❁)

相关文章:

Java实现单向链表

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;Java数据结构与算法 &#x1f9…...

3月4日,30秒知全网,精选7个热点

///印度最大供电商罕见于现货市场购煤&#xff0c;能源供应短缺成忧 据知情人士透露&#xff0c;这家印度国有发电公司计划在下周左右发布300万吨的招标 ///QQ音乐推出AIGC黑胶播放器 这是国内音乐行业首个运用AI技术&#xff0c;通过文字、图片指令快速生成不同风格的播放器…...

EXCEL-职业版本(2)

Excel-职业版本&#xff08;2&#xff09; 定位 1.如何快速定位到不连续的空值&#xff0c;填充为0 1.在任意空单元格里复制0 2.选中数据区域CtrlA 3.CtrlG 4.选择【定位条件】 5.选择【空值】 6.ctrlV 粘贴 即可 2.怎么一次性计算每个小组的数量 单价和金额的和? 1.选中…...

java中延时队列的实现

大家好&#xff0c;我是一名CRUD工程师&#xff0c;最近我朋友突然来问我如何实现延时队列&#xff0c;我脱口而出就是MQ。不过突然想到公司的项目好像用的是java的一个原生类。于是我就想着趁周末的时间好好的去探究一下各方法实现延时队列的优缺点。 延迟消息 延迟消息就是字…...

基于java的circle buffer的实现

总目录链接==>> AutoSAR入门和实战系列总目录 文章目录 缓冲区示例什么是循环缓冲区?方法 1:使用数组插入元素删除元素方法 2:使用链表插入元素:删除元素:当数据经常从一个地方移动到另一个地方或从一个进程移动到另一个进程或被频繁访问时,它不能存储在永久性内存…...

通用方法——为什么重写equals还要重写hashcode

本文介绍java.lang.Object类中的两个方法&#xff1a;equals和hashCode。这两个方法大家应该都知道&#xff0c;但是这两个方法的作用是什么、为什么重写equals还要重写hashCode、它们之间有什么关系和约定等&#xff0c;今天就来带大家了解一下。 1、hashCode hashCode即散列…...

JavaSE学习进阶day2_01 包和权限修饰符

第一章 包 1.1 包 包在操作系统中其实就是一个文件夹。包是用来分门别类的管理技术&#xff0c;不同的技术类放在不同的包下&#xff0c;方便管理和维护。 在IDEA项目中&#xff0c;建包的操作如下&#xff1a; 这个咱们在基础班就谈到过。 包名的命名规范&#xff1a; 路径…...

Android性能调优 - 省电优化

省电&#xff1a;通过工具Battery Historian查看到:耗电大头: 屏幕、网络、cpuled/oled屏幕显示:降低亮度&#xff0c;开深色模式&#xff1b;锁屏间隔缩短到 &#xff1b;亮屏需要一直持有唤醒锁&#xff0c;还有gps定位也需要用到唤醒锁;网络&#xff1a; 常用的网络优化措施…...

ElasticSearch - SpringBoot整合ES之全文搜索匹配查询 match

文章目录1. 数据准备2. match 匹配查询1. 全文检索2. 简化查询DSL语句3. match 匹配查询原理官方文档地址&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/index.html权威指南&#xff1a;https://www.elastic.co/guide/cn/elasticsearch/guide/current/…...

句子的改写和扩写

目录 1.句子改写 2.句子扩写 &#xff08;不低于15个句子算是长句子&#xff0c;不能太多长句子&#xff09; 1.句子改写 我绝不会嫁给你的。 如果你是世界上最后一个男人&#xff0c;我就去寺庙。 If you married me,I would jump into the well. 如果你嫁给我&#xff0c;我…...

DockerFile创建及案例

DockerFile dockerfile是用来构建docker镜像的文件&#xff0c;命令脚本参数脚本&#xff01; 构建步骤 编写一个dockerfile文件docker build 构建成为一个对象docker run 运行镜像docker push 发布镜像&#xff08;DockerHub、阿里云镜像仓库&#xff09; 去官网Docker-Hub…...

第十四届蓝桥杯三月真题刷题训练——第 1 天

目录 题目1&#xff1a;数列求值 代码&#xff1a; 题目2&#xff1a;质数 代码&#xff1a; 题目3&#xff1a;饮料换购 代码&#xff1a; 题目1&#xff1a;数列求值 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出…...

基于容器云提交spark job任务

容器云提交spark job任务 容器云提交KindJob类型的spark任务&#xff0c;首先需要申请具有Job任务提交权限的rbac&#xff0c;然后编写对应的yaml文件&#xff0c;通过spark内置的spark-submit命令&#xff0c;提交用户程序(jar包)到集群执行。 1、创建任务job提交权限rbac …...

Linux系统调用之目录操作函数

前言 如果&#xff0c;想要深入的学习Linux系统调用中mkdir&#xff0c;rmdir&#xff0c;rename&#xff0c;chdir&#xff0c;getcwd等这些有关于目录操作函数&#xff0c;还是需要去自己阅读Linux系统中的帮助文档。 具体输入命令&#xff1a; man 2 mkdir/rmdir/rename/ch…...

设计模式-策略模式

前言 作为一名合格的前端开发工程师&#xff0c;全面的掌握面向对象的设计思想非常重要&#xff0c;而“设计模式”是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的&#xff0c;代表了面向对象设计思想的最佳实践。正如《HeadFirst设计模式》中说的一句话&…...

面试+算法:罗马数字及Excel列名与数字互相转换

概述 算法是一个程序员的核心竞争力&#xff0c;也是面试最重要的考查环节。 试题 判断一个罗马数字是否有效 罗马数字包含七种字符&#xff1a;I&#xff0c;V&#xff0c;X&#xff0c;L&#xff0c;C&#xff0c;D和M&#xff0c;如下 字符数值I1V5X10L50C100D500M1000…...

Connext DDS路由服务Routing Service(1)

1 简介 RTI路由服务是一种开箱即用的解决方案,允许开发人员快速扩展和集成不同或地理位置分散的实时系统。它跨域、LAN和WAN扩展RTI ConnextDDS应用程序,包括防火墙和NAT穿越。 它还支持DDS到DDS的桥接,允许您对数据进行转换。这允许未修改的DDS应用程序进行通信,即使它们是…...

如何使用SaleSmartly进行Facebook Messenger 营销、销售和支持

如何使用SaleSmartly&#xff08;ss客服&#xff09;进行Facebook Messenger 营销、销售和支持上篇文章我们讲了什么是Facebook Messenger CRM以及获得Facebook Messenger CRM的注意事项&#xff0c;现在你有更多时间与客户聊天&#xff0c;让我们看看你如何使用SaleSmartly&am…...

教资教育知识与能力中学教学

目录 3.1 教学概述 3.2 教学过程 3.3 教学原则*【简答/辨析重点】 3.4 教学方法 3.5 教学组织形式 3.6 教学工作基本环节 3.7 教学评价 3.1 教学概述 1、教学的意义【14/18辨析】 教学是传授系统知识、促进学生发展的最有效形式&#xff1b; 教学是学校进行全面发展教…...

IDEA中使用Tomcat的两种方式:集成本地Tomcat使用Tomcat Maven插件

一、前言 在IDEA中创建完一个Maven Web项目&#xff0c;并补齐了目录以后&#xff0c;准备使用Tomcat时&#xff0c;就需要在自己创建的项目中去部署Tomcat&#xff0c;前文已经介绍了如何创建Maven Web&#xff0c;所以这里就不多加赘述&#xff0c;直接讲述部署Tomcat的方法…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

Linux 下 DMA 内存映射浅析

序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存&#xff0c;但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程&#xff0c;可以参考这篇文章&#xff0c;我觉得写的非常…...