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

手动实现LinkedList

前言

大家好,我是Maybe。最近在学习数据结构中的链表,自己手动实现了一个LinkedList。我想与大家分享一下。

思维导图

代码部分

package Constant;public class constant {public static final String INDEX_IS_WRONG="输入的下标不合法";
}
package utils;public class IndexException extends RuntimeException{public IndexException() {super();}public IndexException(String message) {super(message);}
}
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();
}
import Constant.constant;
import utils.IndexException;public class LinkedList implements IList {//1.定义一个内部类static class ListNode{public int val;//类型写成了String,应该是ListNode的public ListNode prev;public ListNode next;public ListNode(int val) {this.val = val;}}public ListNode head;//这个就要给个尾了public ListNode last;@Overridepublic void addFirst(int data) {if(head==null){ListNode node=new ListNode(data);head=last=node;}else{ListNode node=new ListNode(data);node.next=head;head.prev=node;head=node;}}@Overridepublic void addLast(int data) {if(head==null){ListNode node=new ListNode(data);//写成了node=last=null了head=last=node;}else{ListNode node=new ListNode(data);last.next=node;node.prev=last;//这里要注意last=last.next;}}@Override//在LinkedList中找到对应的cur,然后再cur之前插入public void addIndex(int index, int data) {int len=size();if(index<0||index>len){String msg= constant.INDEX_IS_WRONG+index;throw new IndexException(msg);}if(index==0){addFirst(data);}else if(index==len){addLast(data);}else{ListNode node=new ListNode(data);ListNode cur=findIndex(index);node.next=cur;cur.prev.next=node;node.prev=cur.prev;cur.prev=node;}}//在LinkedList中找到对应的curprivate ListNode findIndex(int index){if(head==null){return null;}else{ListNode cur=head;while(index!=0){cur=cur.next;index--;}return cur;}}@Overridepublic boolean contains(int key) {if(head==null){return false;}else{ListNode cur=head;while(cur!=null){if(cur.val==key){return true;}else{cur=cur.next;}}return false;}}@Overridepublic void remove(int key) {//1.先判断链表是否为空if(head==null){return;}else{ListNode cur=head;while(cur!=null){if(cur.val==key){//1.考虑头删的情况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;}}}@Overridepublic void removeAllKey(int key) {if(head==null){return;}else{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.next;}else{cur.next.prev=cur.prev;}}}cur=cur.next;}}}@Overridepublic int size() {if(head==null){return 0;}else{ListNode cur=head;int count=0;while(cur!=null){cur=cur.next;count++;}return count;}}@Overridepublic void display() {if(head==null){return;}else{ListNode cur=head;while(cur!=null){System.out.print(cur.val+" ");cur=cur.next;}System.out.println();}}@Overridepublic void clear() {if(head==null){return;}else{ListNode cur=head;while(cur!=null){ListNode curN=cur.next;cur.prev=null;cur.next=null;cur=curN;}head=last=null;//最后要把head和last置为null}}
}
import utils.IndexException;public class Test {public static void main(String[] args) {LinkedList linkedList=new LinkedList();linkedList.addLast(1);linkedList.addLast(1);linkedList.addLast(1);linkedList.addLast(2);linkedList.display();
//        linkedList.addFirst(1);
//        linkedList.addFirst(2);
//        linkedList.addFirst(3);
//        linkedList.addFirst(4);
//        linkedList.display();
//        int ret=linkedList.size();
//        System.out.println(ret);
//        try{
//            linkedList.addIndex(2,100);
//
//        }catch (IndexException e){
//            e.printStackTrace();
//        }
//        linkedList.display();
//        linkedList.remove(1);
//        linkedList.display();
//        linkedList.removeAllKey(1);linkedList.clear();linkedList.display();}
}

结语 

本次分享到此结束啦。希望可以帮到有需要的人!

 

 

 

 

 

 

相关文章:

手动实现LinkedList

前言 大家好&#xff0c;我是Maybe。最近在学习数据结构中的链表&#xff0c;自己手动实现了一个LinkedList。我想与大家分享一下。 思维导图 代码部分 package Constant;public class constant {public static final String INDEX_IS_WRONG"输入的下标不合法"; }p…...

maven的安装与配置、IDEA集成maven

一、maven的安装与配置环境变量 maven的下载与安装&#xff0c;配置环境变量与验证【附安装包3.6.1&#xff0c;3.8.8&#xff0c;3.9.9】-CSDN博客 参考资料&#xff1a;黑马程序员 二、IDEA集成 2.1 当前工程设置 1. 打开 Maven 设置路径&#xff1a;在 IDEA 中&#xf…...

Axure中继器表格:实现复杂交互设计的利器

在产品原型设计领域&#xff0c;Axure凭借其强大的元件库和交互功能&#xff0c;成为设计师们手中的得力工具。其中&#xff0c;中继器元件在表格设计方面展现出了独特的优势&#xff0c;结合动态面板等元件&#xff0c;能够打造出功能丰富、交互体验良好的表格原型。本文将深入…...

VR 全景看车的独特优势​

全方位沉浸式体验​ VR 全景看车最显著的优势&#xff0c;就是为用户带来了全方位的沉浸式体验。通过 VR 技术&#xff0c;用户仿佛置身于真实的汽车展厅或试驾场景之中&#xff0c;能够 360 度无死角地观察车辆的外观、内饰、细节等各个方面 。无论是车辆的整体造型&#xff0…...

前端 JavaScript 处理流式响应的坑

给使用 JavaScript 的同学提个醒&#xff01; 浏览器端处理流式响应&#xff0c;想要完美体验 请使用 Fetch API。 Axios 无法使用stream来直接处理真正的流式响应&#xff08;但 Node.js 中可以使用 stream&#xff09;&#xff0c;这与浏览器底层 HTTP 请求实现的限制有关。 …...

AI Agent认知框架(ReAct、函数调用、计划与执行、自问自答、批判修正、思维链、思维树详解和对比,最后表格整理总结

以下是主流AI Agent认知框架的详细说明、对比及表格总结&#xff1a; 1. 各认知框架详解 (1) ReAct (Reasoning Action) 定义&#xff1a;结合推理&#xff08;Reasoning&#xff09;和行动&#xff08;Action&#xff09;的循环过程。核心机制&#xff1a; 模型先推理&…...

springBoot_自定义starter

Spring Boot 自定义 Starter 详解 一、Spring Boot Starter 基础概念 1.1 什么是 Spring Boot Starter Spring Boot Starter 是 Spring Boot 的一个核心概念&#xff0c;它是一种特殊的依赖描述符&#xff0c;包含了一组可以集成到应用中的依赖项。简单来说&#xff0c;Star…...

搭建TypeScript单元测试环境

我们在学习TypeScript的时候如果能够搭建一个单元测试的环境&#xff0c;那写些demo会很简单&#xff0c;下面我们使用jest来搭建一个单元测试环境 Jest 是一个由 Facebook 开发并开源的 JavaScript 测试框架&#xff0c;被广泛应用于前端和 Node.js 项目的单元测试。以下是关…...

第十一届机械工程、材料和自动化技术国际会议(MMEAT 2025)

重要信息 官网&#xff1a;www.mmeat.net 时间&#xff1a;2025年06月23-25日 地点&#xff1a;中国-深圳 部分展示 征稿主题 智能制造和工业自动化 复合材料与高性能材料先进制造技术 自动化机器人系统 云制造与物联网集成 精密制造技术 智能生产线优化 实时数据分析与过…...

leetcode 1143. Longest Common Subsequence

目录 题目描述 第一步&#xff0c;明确并理解dp数组及下标的含义 第二步&#xff0c;分析明确并理解递推公式 第三步&#xff0c;理解dp数组如何初始化 第四步&#xff0c;理解遍历顺序 代码 题目描述 这道题和第718题的区别就是&#xff0c;本题求的是最长公共子序列的长…...

SSH 私钥文件权限控制指南

1. 为什么必须严格控制私钥文件权限&#xff1f; 安全机制&#xff1a;SSH 协议强制要求私钥文件必须仅对所有者可读&#xff0c;防止未授权访问。 风险&#xff1a;若权限过松&#xff08;如其他用户可读&#xff09;&#xff0c;SSH 客户端会拒绝连接&#xff0c;避免私钥泄…...

stack和queue的学习

stack的介绍 stack的文档介绍 stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;…...

微服务Nacos组件的介绍、安装、使用

微服务Nacos组件的介绍、安装、使用 在微服务架构日渐普及的今天&#xff0c;服务注册与配置管理成了系统架构中的关键环节。阿里巴巴开源的 Nacos&#xff08;Naming and Configuration Service&#xff09;正是解决这一问题的利器。本文将为你全面介绍 Nacos 的概念、安装方…...

SpringBoot_为何需要SpringBoot?

Spring Boot 出现前的开发困境 配置繁琐 大量的 XML 配置文件 Spring 是一个非常优秀的轻量级框架&#xff0c;但其配置却是重量级的需要编写大量的 XML 配置文件或注解配置&#xff0c;使项目配置复杂且难以维护配置文件中容易出现错误&#xff0c;且排查问题困难开发过程中…...

格式工厂 v5.18最新免安装绿色便携版

前言 用它来转视频的时候&#xff0c;还能顺便给那些有点小瑕疵的视频修修补补&#xff0c;保证转出来的视频质量杠杠的。更厉害的是&#xff0c;它不只是转换那么简单&#xff0c;还能帮你把PDF合并成一本小册子&#xff0c;视频也能合并成大片&#xff0c;还能随心所欲地裁剪…...

使用logrotate实现日志轮转

logrotate 是一个强大的 Linux 工具&#xff0c;用于自动化管理日志文件的轮转、压缩、删除和归档。它能有效防止日志文件无限增长&#xff0c;节省磁盘空间&#xff0c;同时保持日志的可追溯性。以下是详细讲解 logrotate 的用法&#xff0c;涵盖安装、配置、测试、自动化、常…...

MQTTX + MCP:MQTT 客户端秒变物联网 Agent

引言&#xff1a;MQTTX 与 MCP 的融合 作为最受欢迎的 MQTT 客户端工具&#xff0c;MQTTX 在 1.12.0 beta 版本中集成了模型上下文协议&#xff08;MCP&#xff09;到 Copilot AI 功能中&#xff0c;显著提升了服务能力。这一融合让 MQTTX 转变为 MCP Host&#xff08;也就是发…...

redis close+连接参数设置+并发情况风险分析

1&#xff0c;如下代码 redis 为什么 client.close&#xff0c;不关闭会出现什么问题 public void confirm(String token, MenuHistoryVO menuHistoryVO) {if (StringUtil.isEmptyOrNull(token) || Objects.isNull(menuHistoryVO)) {return;}String key getKey(token);JedisC…...

[密码学实战]GMT 0048-2016智能密码钥匙密码检测规范技术解析与实战指南

GMT 0048-2016智能密码钥匙密码检测规范技术解析与实战指南 引言 随着信息安全需求的升级&#xff0c;智能密码钥匙&#xff08;如USB Key、安全芯片等&#xff09;作为密码运算和密钥管理的核心设备&#xff0c;广泛应用于金融、政务、物联网等领域。中国国家密码管理局发布…...

Android OkHttp 框架的使用与源码、原理解析

一、引言 在如今的移动应用开发领域&#xff0c;网络交互已经成为了绝大多数 Android 应用不可或缺的一部分。无论是获取最新的资讯内容、同步用户数据&#xff0c;还是与后端服务器进行实时通信&#xff0c;高效且稳定的网络请求都是保障应用良好用户体验的基石。而 OkHttp 框…...

Qt C++ 解析和处理 XML 文件示例

使用 Qt C 解析和处理 XML 文件 以下是使用 Qt C 实现 XML 文件处理的几种方法&#xff0c;包括解析、创建和修改 XML 文件。 1. 使用 QXmlStreamReader (推荐方式) #include <QFile> #include <QXmlStreamReader> #include <QDebug>void parseXmlWithStr…...

快手砍掉本地生活的门槛

一场本地商家的效率革命。 作者|景行 编辑|杨舟 “两斤鸡翅根七块九&#xff0c;两盒蓝莓九块钱&#xff0c;两公斤卫生纸十四块九一提。” 这是朝阳佳惠超市&#xff0c;在快手一则普通的短视频内容。 佳惠超市在辽宁省朝阳市有22家分店&#xff0c;打开佳惠超市的相关快手…...

Python基础语法3

目录 1、函数 1.1、语法格式 1.2、函数返回值 1.3、变量作用域 1.4、执行过程 1.5、链式调用 1.6、嵌套调用 1.7、函数递归 1.8、参数默认值 1.9、关键字参数 2、列表 2.1、创建列表 2.2、下标访问 2.3、切片操作 2.4、遍历列表元素 2.5、新增元素 2.6、查找元…...

Vue 3中如何封装API请求:提升开发效率的最佳实践

在现代前端开发中&#xff0c;API请求是不可避免的一部分&#xff0c;尤其是与后端交互时。随着Vue 3的广泛应用&#xff0c;如何高效地封装API请求&#xff0c;既能提升代码的可维护性&#xff0c;又能确保代码的高复用性&#xff0c;成为了很多开发者关注的话题。 在本文中&…...

GitHub 趋势日报 (2025年04月17日)

本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ &#x1f4c8; 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1Anduin2017/HowToCook程序员在家做饭方法指南。Programmer’s guide about how to cook at home (Simplified Chinese onl…⭐ 224…...

第5章-1 优化服务器设置

上一篇&#xff1a;《第4章-5 linux 网络管理》&#xff0c;接着服务器设置 本章我们将解释如何为MySQL服务器创建合适的配置文件。这是一个迂回的旅程&#xff0c;有许多兴趣点和可以俯瞰风景的短途旅程。这些短途旅程是必要的。确定合适配置的最短路径并不是从研究配置选项并…...

【AI】Windows环境安装SPAR3D单图三维重建心得

效果一览 左图为原始单个图像&#xff0c;右图为通过SPAR3D重建后的三维建模&#xff0c;可以看出效果还是不错的。 本地环境配置 系统&#xff1a;Windows 11 专业版CPU&#xff1a;i5-13400F内存&#xff1a;32GBGPU&#xff1a;RTX3060 12GBcuda&#xff1a;11.8conda&…...

桌面应用UI开发方案

一、基于 Web 技术的跨平台方案 Electron Python/Go 特点&#xff1a; 技术栈&#xff1a;前端使用 HTML/CSS/JS&#xff0c;后端通过 Node.js 集成 Python/Go 模块或服务。 跨平台&#xff1a;支持 Windows、macOS、Linux 桌面端&#xff0c;适合开发桌面应用。 生态成熟&…...

使用docker在manjaro linux系统上运行windows和ubuntu

因为最近项目必须要使用指定版本的solidworks和maxwell&#xff08;都只能在win系统上使用&#xff09;, 且目前的ubuntu容器是没有桌面的&#xff0c;导致我运行不了一些带图形的ros2功能。无奈之下&#xff0c;决定使用docker-compose写一下配置文件&#xff0c;彻底解决问题…...

Agent智能体ReAct机制深度解读:推理与行动的完美闭环

一、从Chain-of-Thought到ReAct的范式演进 1.1 传统决策机制的局限 #mermaid-svg-Jf3ygvgHcGciJvX8 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Jf3ygvgHcGciJvX8 .error-icon{fill:#552222;}#mermaid-svg-Jf3y…...