Java数据结构与算法--链表(Linked List)

  • 博客主页:誓则盟约
  • 系列专栏:Java SE
  • 关注博主,后期持续更新系列文章
  • 如果有错误感谢请大家批评指出,及时修改
  • 感谢大家点赞👍收藏⭐评论✍ 

深入了解链表:

        链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的链接(指针),但是在Java中没有指针这个说法,我们称其为引用

链表的主要特点包括:

  1. 动态性

    • 可以在运行时方便地添加或删除节点,无需事先确定链表的大小。
    • 例如,在需要不断添加新用户信息的场景中,链表能够灵活适应数据量的变化。
  2. 内存分配

    • 节点在内存中可以不连续存储,这与数组不同。
    • 使得链表能够更有效地利用内存空间。

链表分为多种类型,常见的有:

   1.单链表

  • 每个节点只有一个指向下一个节点的指针。
  • 从头到尾进行遍历。
  • 例如,实现一个简单的任务队列,新任务添加到链表尾部,处理任务从头部开始。

    2.双向链表

  • 节点既有指向前一个节点的指针,也有指向下一个节点的指针。
  • 可以双向遍历,在查找特定节点时可能更高效。

    3.循环链表

  • 尾节点的指针指向头节点,形成一个环。

链表的操作主要包括:

1.插入节点

  • 可以在头部、尾部或中间位置插入。

2.删除节点

  • 根据特定条件删除指定节点。

3.查找节点

  • 通常需要从链表的头部或尾部开始逐个遍历。

链表的一些缺点:

1.访问效率低

  • 要访问特定位置的节点,需要从头开始遍历,时间复杂度较高。

2.额外的指针存储空间

  • 每个节点都需要存储指针,增加了存储开销。

        总之,链表在许多场景中发挥着重要作用,特别是当需要频繁进行插入和删除操作,且对随机访问要求不高时,链表是一种非常合适的数据结构选择。下面主要介绍的是单链表:


链表的节点类设计:

      这里采用私密的静态类方法定义Node,由于不知道element是什么类型,这里照样使用泛型,代码实现如下: 

    private static class Node<E> {private E e;private Node<E> next;public Node(E e) {this.e = e;}}

        定义一个链表对象:

public class LinkedList<E> {private Node<E> head = new Node<>(null) ;private  int size;

链表的添加方法:

在指定位置(index)处插入一个结点(node),只需要两步即可:

  • 可以先修改插入的结点的后继结点(也就是下一个结点)指向,指向原本在这个位置的结点:

  • 接着我们可以将前驱结点(也就是上一个结点)的后继结点指向修改为我们新插入的结点:

这样,我们就成功的插入了一个新的结点,现在新插入的结点到达了原本的第二个位置上:

按照这个思路,我们只需要找到index指向的这个节点,即可完成插入,代码实现如下:

public class LinkedList<E> {private Node<E> head = new Node<>(null);  // 初始化头节点,值为 nullprivate int size;  // 记录链表中元素的数量/*** 在指定索引处添加元素* @param e 要添加的元素* @param index 元素要添加的索引位置*/public void add(E e, int index) {if (index < 0 || index > size) throw new IndexOutOfBoundsException();  // 检查索引是否越界,越界则抛出异常Node<E> prev = head;  // 从头部开始for (int i = 0; i < index; i++) {  // 找到指定索引位置的前一个节点prev = prev.next;}Node<E> node = new Node<>(e);  // 创建新节点node.next = prev.next;  // 新节点的 next 指向原索引位置的节点prev.next = node;  // 前一个节点的 next 指向新节点size++;  // 链表元素数量加 1}
}

链表的删除方法:

        插入操作完成之后,我们接着来看删除操作,删除操作就更简单了,可以直接将待删除的结点的前驱结点指向修改为待删除节点的下一个:

        这样,理论上来说,待删除结点就已经不在链表中了,所以我们只需要释放掉结点所占用的内存空间(JVM会自动回收)就可以了:

代码实现:

public E remove(int index) {if (index <0 || index > size-1) throw new IndexOutOfBoundsException();Node<E> prev = head;for (int i = 0; i < index; i++) {prev = prev.next;}E e = prev.next.e;prev.next = prev.next.next;return e;}

链表的get方法:

        要像列表一样访问指定的index下标的元素,在单链表中只能一个一个往后找(时间复杂度O(n)),会比顺序表(O(1))复杂度高很多。代码实现:

  public E get(int index) {if (index <0 || index > size-1) throw new IndexOutOfBoundsException();Node<E> node = head;for (int i = 0; i < index; i++) {node = node.next;}return node.e;}public int size() {return size;}

链表的转字符串输出方法:

        链表本身不能直接输出,要想以特定的方式输出一个链表,就需要去定义一个toString方法,下面是一个简单的代码示例:

public String toString() {StringBuilder sb = new StringBuilder();Node<E> node = head.next;while (node != null) {sb.append(node.e).append("  ");node = node.next;}return sb.toString();
}

完整代码实现单链表:

import org.w3c.dom.Node;public class LinkedList<E> {private Node<E> head = new Node<>(null) ;private  int size;public void add(E e,int index) {if (index <0 || index > size) throw new IndexOutOfBoundsException();Node<E> prev = head;for (int i = 0; i < index; i++) {prev = prev.next;}Node<E> node = new Node<>(e);node.next = prev.next;prev.next = node;size++;}private static class Node<E> {private E e;private Node<E> next;public Node(E e) {this.e = e;}}public E remove(int index) {if (index <0 || index > size-1) throw new IndexOutOfBoundsException();Node<E> prev = head;for (int i = 0; i < index; i++) {prev = prev.next;}E e = prev.next.e;prev.next = prev.next.next;return e;}public E get(int index) {if (index <0 || index > size-1) throw new IndexOutOfBoundsException();Node<E> node = head;for (int i = 0; i < index; i++) {node = node.next;}return node.e;}public int size() {return size;}
public String toString() {StringBuilder sb = new StringBuilder();Node<E> node = head.next;while (node != null) {sb.append(node.e).append("  ");node = node.next;}return sb.toString();
}
}

“戒除欲望,控制行为,充实生活,美好的世界。”——《yuanziyu》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/384682.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !

目录 C语言指针精讲1. 什么是指针&#xff1f;1.1 指针的内存模型1.1.1 指针演示输出 1.2 指针运算1.2.1 指针算术运算输出1.2.2 指针与数组的关系输出 1.3 指针类型1.3.1 不同类型的指针示例输出1.3.2 void 指针输出 1.4 指针与内存管理动态内存分配输出 1.5 指针与内存泄漏1.…

Android进阶之NDK开发,保姆级教程

目录 前言NDK下载CMake文件创建指定ABI架构编写CMake文件编写JNI方法Java调用CC调用Java 生成JNI头文件实现对应C方法编译so文件编写demo验证运行效果总结 前言 作为Android应用开发从业者来说&#xff0c;掌握NDK开发是必备技能之一&#xff0c;本文将从NDK环境下载&#xff…

均匀圆形阵列原理及MATLAB仿真

均匀圆形阵列原理及MATLAB仿真 目录 前言 一、均匀圆阵原理 二、圆心不存在阵元方向图仿真 三、圆心存在阵元方向图仿真 四、MATLAB仿真代码 总结 前言 本文详细推导了均匀圆形阵列的方向图函数&#xff0c;对圆心不放置阵元和圆心放置阵元的均匀圆形阵列方向图都进行了仿…

PySide(PyQt)的QPropertyAnimation(属性动画)

学不完&#xff0c;根本学不完:(&#xff0c;感觉逐渐陷入了学习深渊。。。 QPropertyAnimation 是 PySide(PyQt) 中一个用于在时间轴上平滑地改变对象属性的类。它常用于制作动画效果&#xff0c;比如移动、缩放或改变透明度等。 基本概念 QPropertyAnimation 是 Qt …

03。正式拿捏ArkTS语言第一天

1, 打印日志命令 &#xff1a; console.log() 2, 三种基本数据类型&#xff1a; number 数字类型 &#xff08;数字&#xff09; string 字符串类型&#xff08;例如&#xff1a;“我是字符串”&#xff09; boolean 布尔类型 (true 或者 false) ***…

昇思25天学习打卡营第24天|RNN实现情感分类

RNN实现情感分类学习总结 概述 情感分类是自然语言处理领域的重要任务&#xff0c;主要用于识别文本中表达的情绪。本文使用MindSpore框架实现基于RNN的情感分类模型&#xff0c;示例包括&#xff1a; 输入: “This film is terrible” -> 标签: Negative输入: “This fi…

飞牛爬虫FlyBullSpider 一款简单方便强大的爬虫,限时免费 特别适合小白!用它爬下Boss的2024年7月底Java岗位,分析一下程序员就业市场行情

一、下载安装FlyBullSpider 暂时支持Window,现在只在Win11上做过测试 1 百度 点击百度网盘 下载 链接&#xff1a;https://pan.baidu.com/s/1gSLKYuezaZgd8iqrXhk8Kg 提取码&#xff1a;Fly6 2 csdn https://download.csdn.net/download/fencer911/89584687 二、体验初…

Linux shell编程学习笔记66:ping命令 超详细的选项说明

0 前言 网络信息是电脑网络信息安全检查中的一块重要内容&#xff0c;Linux和基于Linux的操作系统&#xff0c;提供了很多的网络命令&#xff0c;今天我们研究最常用的ping命令。 1 ping命令 的功能、格式和选项说明 1.1 ping命令 的功能 简单来说&#xff0c; ping 命令 会…

Linus: vim编辑器的使用,快捷键及配置等周边知识详解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 vim的安装创建新用户 adduser 用户名Linus是个多用户的操作系统是否有创建用户的权限查看当前用户身份:whoami** 怎么创建设置密码passwdsudo提权(sudo输入的是用户…

日记审计遵守合规安全要求

一、什么是日志审计系统 日记审计系统是一种用于记录、监视和分析系统日志的工具或系统。它主要用于帮助组织实时监控与分析各种事件和行为的日志记录&#xff0c;以便检测潜在的安全威胁&#xff0c;了解系统性能和进行故障排除。日志审计系统通常能够收集、存储和分析来自各…

.env.local 配置本地环境变量 用于团队开发

.env.local 用途&#xff1a;.env.local 通常用于存储本地开发环境中的环境变量。这些变量可能包括敏感数据或特定于单个开发者的设置&#xff0c;不应该被提交到版本控制系统中。优先级&#xff1a;在大多数框架中&#xff0c;.env.local 文件中的变量会覆盖其他 .env 文件中…

vite环境下使用bootstrap

环境 nodejs 18 pnpm 初始化 pnpm init pnpm add -D vite --registry http://registry.npm.taobao.org pnpm add bootstrap popperjs/core --registry http://registry.npm.taobao.org pnpm add -D sass --registry http://registry.npm.taobao.org新建vite.config.js cons…

opencv 按键开启连续截图,并加载提示图片

背景图小图 键盘监听使用的是pynput 库 保存图片时使用了年月日时分秒命名 原图&#xff1a; from pynput import keyboard import cv2 import time# 键盘监听 def on_press(key):global jieglobal guanif key.char a:jie Trueelif key.char d:jie Falseelif key.char…

SpringBoot启动命令过长

Error running DromaraApplication: Command line is too long. Shorten command line for DromaraApplication or also for Spring Boot default configuration?

LeetCode 热题 HOT 100 (010/100)【宇宙最简单版】

【链表】No. 0206 反转链表 【简单】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#xf…

轻松学EntityFramework Core--模型创建

一、使用代码优先&#xff08;Code-First&#xff09;创建模型 Code-First 方法是 EF Core 提供的一种用于定义模型的方式&#xff0c;它允许开发人员通过编写 C# 类来定义数据库模式&#xff0c;再通过迁移命令生成数据库表。下面我们来一起看一下代码优先如何使用。 1.1、创…

问题记录-SpringBoot 2.7.2 整合 Swagger 报错

详细报错如下 报错背景&#xff0c;我将springboot从2.3.3升级到了2.7.2&#xff0c;报了下面的错误&#xff1a; org.springframework.context.ApplicationContextException: Failed to start bean documentationPluginsBootstrapper; nested exception is java.lang.NullPo…

MySQL练手 --- 1789. 员工的直属部门

题目链接&#xff1a;1789. 员工的直属部门 这道题虽然是个简单题&#xff0c;但是"坑"倒是不少&#xff0c;所以记录一下 思路&#xff1a; 题目要干&#xff1a; 一个员工可以属于多个部门。当一个员工加入超过一个部门的时候&#xff0c;他需要决定哪个部门是…

导航网站WP主题/WP黑格导航主题BlackCandy-简约酷黑色高逼格+焕然一新的UI设计

源码简介&#xff1a; 导航网站WP主题-WP黑格导航主题BlackCandy&#xff0c;它有着简约酷黑色高逼格&#xff0c;而且有焕然一新的UI设计。它是一个简约漂亮的 WordPress 自媒体主题。黑格网址导航主题&#xff0c;自适应电脑端和手机端。 BlackCandy-V2.0这次全新升级了&am…

mac M1安装Roop教程及所遇到的问题

1.安装miniconda&#xff0c;下载地址&#xff1a; 按 Python 版本划分的最新 Miniconda 安装程序链接&#xff1a;https://docs.anaconda.com/miniconda/miniconda-other-installer-links/ 下载后直接默认安装即可。 我用的是&#xff1a;Python3.10对应的Miniconda 2.下载…