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

Java手写LinkedList和拓展

Java手写LinkedList和拓展

思维导图

LinkedList
Node
add
get
remove
size

实现思路原理

  • 创建一个名为Node的内部类,用于表示链表中的节点。Node类应包含以下属性:

    • data:用于存储节点的数据元素。
    • prev:用于存储指向前一个节点的引用。
    • next:用于存储指向后一个节点的引用。
  • 创建一个名为LinkedList的类,用于表示链表。LinkedList类应包含以下属性:

    • head:用于存储链表的头节点的引用。
    • tail:用于存储链表的尾节点的引用。
    • size:用于存储链表中节点的数量。
  • 实现add方法,用于向链表中添加新的元素。该方法的实现步骤如下:

    • 创建一个新的Node对象,将要添加的数据元素作为参数传入。
    • 如果链表为空(即headnull),则将新节点设置为头节点和尾节点。
    • 否则,将新节点的prev引用设置为当前尾节点,将当前尾节点的next引用设置为新节点,并将新节点设置为新的尾节点。
    • 增加链表的大小。
  • 实现get方法,用于获取指定位置的元素。该方法的实现步骤如下:

    • 检查索引是否越界,如果越界则抛出IndexOutOfBoundsException异常。
    • 从头节点开始,遍历链表,直到找到指定位置的节点。
    • 返回该节点的数据元素。
  • 实现remove方法,用于删除指定位置的元素。该方法的实现步骤如下:

    • 检查索引是否越界,如果越界则抛出IndexOutOfBoundsException异常。
    • 从头节点开始,遍历链表,直到找到指定位置的节点。
    • 如果要删除的节点有前一个节点(即当前节点的prev不为null),则将前一个节点的next引用指向当前节点的下一个节点。
    • 否则,将头节点设置为当前节点的下一个节点。
    • 如果要删除的节点有后一个节点(即当前节点的next不为null),则将后一个节点的prev引用指向当前节点的前一个节点。
    • 否则,将尾节点设置为当前节点的前一个节点。
    • 减少链表的大小。
  • 实现size方法,用于获取链表的长度。该方法的实现步骤如下:

    • 直接返回链表的大小属性。

详细介绍和详细步骤

创建Node类

private class Node {private T data;private Node prev;private Node next;public Node(T data) {this.data = data;this.prev = null;this.next = null;}
}

Node类用于表示链表中的节点,包含数据元素data、指向前一个节点的引用prev和指向后一个节点的引用next。构造函数用于初始化节点的数据元素。

创建LinkedList类

public class LinkedList<T> {private Node head;private Node tail;private int size;// 构造函数public LinkedList() {this.head = null;this.tail = null;this.size = 0;}// 添加元素public void add(T element) {Node newNode = new Node(element);if (head == null) {head = newNode;tail = newNode;} else {newNode.prev = tail;tail.next = newNode;tail = newNode;}size++;}// 获取元素public T get(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("Index out of range");}Node current = head;for (int i = 0; i < index; i++) {current = current.next;}return current.data;}// 删除元素public void remove(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("Index out of range");}Node current = head;for (int i = 0; i < index; i++) {current = current.next;}if (current.prev != null) {current.prev.next = current.next;} else {head = current.next;}if (current.next != null) {current.next.prev = current.prev;} else {tail = current.prev;}size--;}// 获取链表长度public int size() {return size;}
}

LinkedList类用于表示链表,包含头节点head、尾节点tail和链表长度size属性。构造函数用于初始化链表。

add方法用于向链表中添加新的元素。首先创建一个新的Node对象,并将要添加的数据元素作为参数传入。然后根据链表是否为空,将新节点设置为头节点和尾节点,或者将新节点添加到尾节点的后面。最后增加链表的大小。

get方法用于获取指定位置的元素。首先检查索引是否越界,如果越界则抛出IndexOutOfBoundsException异常。然后从头节点开始遍历链表,直到找到指定位置的节点。最后返回该节点的数据元素。

remove方法用于删除指定位置的元素。首先检查索引是否越界,如果越界则抛出IndexOutOfBoundsException异常。然后从头节点开始遍历链表,直到找到指定位置的节点。如果要删除的节点有前一个节点,则将前一个节点的next引用指向当前节点的下一个节点;否则,将头节点设置为当前节点的下一个节点。如果要删除的节点有后一个节点,则将后一个节点的prev引用指向当前节点的前一个节点;否则,将尾节点设置为当前节点的前一个节点。最后减少链表的大小。

size方法用于获取链表的长度,直接返回链表的大小属性。

总结

通过手写LinkedList的实现,我们深入理解了链表的数据结构和原理,并且加深了对Java语言的熟悉程度。我们学习了如何创建链表、添加元素、获取元素、删除元素和获取链表长度的基本功能。通过实践,我们对链表的操作和链表节点的关系有了更深入的理解。

拓展

除了基本的添加、获取和删除功能,我们还可以对LinkedList进行一些拓展,例如:

  • 实现反转链表的功能,将链表中的节点顺序颠倒。
  • 实现查找链表中的环,并返回环的起始节点。
  • 实现合并两个有序链表的功能,将两个有序链表合并为一个有序链表。
    具体如下:

反转链表

public void reverse() {Node current = head;Node prev = null;while (current != null) {Node next = current.next;current.next = prev;prev = current;current = next;}tail = head;head = prev;
}

reverse方法用于将链表中的节点顺序颠倒。首先定义一个当前节点current和一个前一个节点prev,并将它们都初始化为null。然后使用一个循环,遍历链表中的每个节点。在循环中,首先将当前节点的下一个节点保存到一个临时变量next中,然后将当前节点的next引用指向前一个节点prev,然后将前一个节点prev更新为当前节点current,最后将当前节点current更新为下一个节点next。循环结束后,将尾节点tail更新为原来的头节点head,将头节点head更新为反转后的链表的头节点prev

查找链表中的环

public Node findCycle() {Node slow = head;Node fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;if (slow == fast) {break;}}if (fast == null || fast.next == null) {return null;}slow = head;while (slow != fast) {slow = slow.next;fast = fast.next;}return slow;
}

findCycle方法用于查找链表中的环,并返回环的起始节点。首先定义一个慢指针slow和一个快指针fast,并将它们都初始化为头节点head。然后使用一个循环,慢指针每次移动一步,快指针每次移动两步,直到快指针追上慢指针或者快指针到达链表的末尾。如果快指针追上慢指针,则说明链表中存在环。在循环结束后,如果快指针为null或者快指针的下一个节点为null,则说明链表中不存在环,返回null。否则,将慢指针重新设置为头节点head,然后使用两个指针同时移动,每次移动一步,直到两个指针相遇。相遇的节点即为环的起始节点。

合并两个有序链表

public static LinkedList<Integer> merge(LinkedList<Integer> list1, LinkedList<Integer> list2) {LinkedList<Integer> mergedList = new LinkedList<>();Node node1 = list1.head;Node node2 = list2.head;while (node1 != null && node2 != null) {if (node1.data <= node2.data) {mergedList.add(node1.data);node1 = node1.next;} else {mergedList.add(node2.data);node2 = node2.next;}}while (node1 != null) {mergedList.add(node1.data);node1 = node1.next;}while (node2 != null) {mergedList.add(node2.data);node2 = node2.next;}return mergedList;
}

merge方法用于合并两个有序链表,并返回合并后的有序链表。首先创建一个新的空链表mergedList作为合并后的链表。然后使用两个指针node1node2分别指向两个链表的头节点。使用一个循环,比较node1node2指向的节点的数据元素大小,将较小的数据元素添加到mergedList中,并将对应的指针向后移动一步。循环结束后,如果链表list1还有剩余的节点,则将剩余的节点添加到mergedList中。如果链表list2还有剩余的节点,则将剩余的节点添加到mergedList中。最后返回合并后的链表mergedList

拓展总结

通过拓展部分的代码,我们实现了链表的反转、查找环和合并有序链表等功能。这些功能都是基于链表的基本操作进行实现的,通过实践我们不仅加深了对链表的理解,而且提高了编程能力。链表作为一种常用的数据结构,对于解决一些特定的问题非常有用,因此掌握链表的基本操作和常见的拓展功能对于编程能力的提升是非常有帮助的。

相关文章:

Java手写LinkedList和拓展

Java手写LinkedList和拓展 思维导图 #mermaid-svg-K0RTlFFvnikDRvqp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-K0RTlFFvnikDRvqp .error-icon{fill:#552222;}#mermaid-svg-K0RTlFFvnikDRvqp .error-text{fill…...

机器学习(14)---逻辑回归(含手写公式、推导过程和手写例题)

逻辑回归 一、逻辑回归概述二、模型、策略和优化&#xff08;手写&#xff09;三、w和b的梯度下降公式推导四、例题分析4.1 题目4.2 解答 一、逻辑回归概述 1. 逻辑回归也称作logistic回归分析&#xff0c;是一种广义的线性回归分析模型&#xff0c;属于机器学习中的监督学习。…...

LLFormer 论文阅读笔记

Ultra-High-Definition Low-Light Image Enhancement: A Benchmark and Transformer-Based Method 这是南京大学在AAAI 2023发表的一篇AAAI2023 超高清图像暗图增强的工作。提出了一个超高清暗图增强数据集&#xff0c;提供了4K和8K的图片&#xff0c;同时提出了一个可用于暗图…...

JSP语法基础习题

目录 简答题&#xff1a;jsp中静态include和动态include的区别是什么&#xff1f; 简答题&#xff1a;jsp有哪些内置对象&#xff0c;作用分别是什么&#xff1f; 简答题&#xff1a;Request对象的主要方法有哪些&#xff1f; 代码题&#xff1a; 简答题&#xff1a;jsp中静态…...

vue类与样式的绑定列表渲染

目录 1.类与样式的绑定 1.1绑定 HTML class 1.2绑定数组 1.3绑定内联样式 绑定数组 2.列表渲染 2.1v-for​ 2.2v-for 与对象 2.3在 v-for 里使用范围值​ 1.类与样式的绑定 1.1绑定 HTML class 我们可以给 :class (v-bind:class 的缩写) 传递一个对象来动态切换 class…...

vue3+element-plus权限控制实现(el-tree父子级不关联情况处理)

文章目录 前言一、遇到的交互场景el-tree 中 check-strictly 属性 二、处理父级的半选中以及选中交互el-treecheck&#xff0c;check-change 事件编辑进来&#xff0c;父级的半选状态处理 总结 前言 在开发后台管理系统的时候&#xff0c;用户的权限控制是一个常见的需求。这里…...

js中事件委托和事件绑定之间的区别

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 事件绑定&#xff08;Event Binding&#xff09;⭐事件委托&#xff08;Event Delegation&#xff09;⭐ 选择事件绑定或事件委托⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本…...

Android 11.0 系统system模块开启禁用adb push和adb pull传输文件功能

1.使用场景 在进行11.0的系统定制化开发中,在一些产品中由于一些开发的功能比较重要,防止技术点外泄在出货产品中,禁用 adb pull 和adb push等命令 来获取系统system下的jar 和apk 等文件,所以需要禁用这些命令 2.系统system模块开启禁用adb push和adb pull传输文件功能的…...

实战经验分享:如何通过HTTP代理解决频繁封IP问题

在网络爬虫和数据采集等应用中&#xff0c;频繁遇到目标网站封锁或限制IP的情况是非常常见的。为了解决这个问题&#xff0c;使用HTTP代理是一种有效的方法。本文将与您分享一些实战经验&#xff0c;帮助您通过HTTP代理解决频繁封IP问题&#xff0c;确保您的数据采集工作顺利进…...

通讯网关软件001——利用CommGate X2Access-U实现OPC UA数据转储Access

本文介绍利用CommGate X2ACCESS-U实现从OPC UA Server读取数据并同步转储至ACCESS数据库。CommGate X2ACCESS-U是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;实现从OPC UA Server实时读取…...

Mybatis sql参数自动填充

问题描述 在日常开发中&#xff0c;经常会遇到Mybatis sql语句的操作问题&#xff0c;由于Mybatis实现sql的动态拼接&#xff0c;开发过程中&#xff0c;为了验证sql是否书写正确&#xff0c;通常需要获取的控制台打印的sql语句来检查是否拼接正确。如下图所示&#xff1a; 那…...

亚马逊云科技面向游戏运营活动的AI生图解决方案

随着Stable Diffusion等AI生图方案逐步普及&#xff0c;越来越多的场景被开发和落地。其中面向游戏C端玩家的AI生图营销活动场景正在被逐步验证&#xff1a;在某个游戏社区中&#xff0c;玩家一键从手机上传一张照片&#xff0c;AI会将自动识别该照片中的元素并替换成游戏中相应…...

腾讯mini项目-【指标监控服务重构】2023-07-30

今日已办 调研 CPU & Memory Cadivisor &#xff23;adivisor -> Prometheus -> (Grafana / SigNoz Web) google/cadvisor: Analyzes resource usage and performance characteristics of running containers. (github.com) services:cadvisor:image: gcr.io/ca…...

Windows 下 MySQL 8.1 图形化界面安装、配置详解

首先我们下载安装包 官方下载链接&#xff1a; MySQL :: Begin Your Download 网盘链接: https://pan.baidu.com/s/1FOew6-93XpknB-bYDhDYPw 提取码: brys 外网下载慢的同学可以使用上述网盘链接 下载完成后我们双击安装包即可进入安装界面 点击next 勾选同意协议&#…...

WebRTC 源码 编译 iOS端

1. 获取依赖工具 首先&#xff0c;确保你已经安装了以下工具&#xff1a; GitDepot ToolsXcode&#xff08;确保已安装命令行工具&#xff09; 2. 下载 depot_tools 使用 git 克隆 depot_tools 并将其添加到你的 PATH 中&#xff1a; /path/to/depot_tools 替换为自己的路径…...

Python编程指南:利用HTTP和HTTPS适配器实现智能路由

嗨&#xff0c;爬虫大佬们&#xff01;今天我要为大家分享一篇关于如何利用HTTP和HTTPS适配器来实现智能路由的Python编程指南。在现代互联网应用中&#xff0c;路由功能起着至关重要的作用&#xff0c;而利用Python编程语言实现智能路由则可以为我们的应用带来更高的灵活性和性…...

MySQL 权限分配

有时候&#xff0c;您需要查看某个用户被授予的权限以便复核。 MySQL 允许您使用 SHOW GRANTS 语句来显示分配给用户帐户或角色的权限。 MySQL SHOW GRANTS 语句介绍 以下是 SHOW GRANTS 语句的基本语法&#xff1a; SHOW GRANTS [FOR {user | role} [USING role [, role] .…...

基于PHP的医药博客管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的医药博客管理系统 一 介绍 此医药博客系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。用户可注册登录&#xff0c;查看/评论/搜索博客&#xff0c;建议留言。管理员可对用户&a…...

spark SQLQueryTestSuite sql 自动化测试用例

把SQL 添加到自动化测试用例。 ./sql/core/src/test/resources/sql-tests/inputs 目录存放原始的SQL. ./sql/core/src/test/resources/sql-tests/results存放SQL的执行结果。在执行测试时&#xff0c;根据最新生成的结果和 ./sql/core/src/test/resources/sql-tests/results 进…...

Taro小程序隐私协议开发指南填坑

一. 配置文件app.config.js export default {...__usePrivacyCheck__: true,... }二. 开发者工具基础库修改 原因&#xff1a;从基础库 2.32.3 开始支持 修改路径&#xff1a;详情->本地设置->调试基础库 三. 用户隐私保护指引更新 修改路径&#xff1a;mp后台->设…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

篇章二 论坛系统——系统设计

目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…...