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

news2024/11/25 16:46:15
  • 博客主页:誓则盟约
  • 系列专栏: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);  // 初始化头节点,值为 null
    private 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.coloradmin.cn/o/1952779.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SOC 芯片设计 DFT 学习专栏 -- DFT DRC规则检查】

请阅读【嵌入式及芯片开发学必备专栏】 请阅读【芯片设计 DFT 学习系列 】 如有侵权&#xff0c;请联系删除 转自&#xff1a; 芯爵ChipLord 2024年07月10日 12:00 浙江 文章目录 概述DRC的概念Tessent DRC检查的概述时钟相关检查扫描相关检查BIST规则检查预DFT时钟规则检查 …

zh echarts样式

记录一下&#xff1a; 一个图的配置 在echarts官网demo界面 option {title: {text: },legend: {data: [xxx前, xxx后]},radar: {// shape: circle,name: {// 雷达图各类别名称文本颜色textStyle: {color: #000,fontSize: 16}},indicator: [{ name: 完整性, max: 1 },{ name:…

ByteBuffer调试工具类

一个可以形象展示ByteBuffer内容的方法&#xff0c;便于调试 package com.example.netty;import java.nio.ByteBuffer;public class ByteBufferUtil {/*** 打印ByteBuffer的内容&#xff0c;以十六进制和ASCII字符的形式展示。** param buffer 要展示的ByteBuffer*/public sta…

Java全栈课程之Linux——用户组管理

每个用户都有一个用户组&#xff0c;系统可以对一个用户组中的所有用户进行集中管理。不同Linux 系统对用户组的规定有所不同&#xff0c;如Linux下的用户属于与它同名的用户组&#xff0c;这个用户组在创建用户时同时创建。 用户组的管理涉及用户组的添加、删除和修改。组的增…

Jenkins持续集成软件

1.什么是jenkins? jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;提供一个开放易用的软件平台&#xff0c;时软件项目可以进行持续集成。 通俗来说&#xff1a;Jenkins软件就是自动拉取git远程仓库所…

03--KVM虚拟化

前言&#xff1a;这里开始涉及到云计算内容&#xff0c;虚拟化使云计算发展&#xff0c;云计算推动虚拟化进步&#xff0c;两者相辅相成&#xff0c;这一章总结一下kvm虚拟化的解决方案。 1、基础概念 1.1、云计算 以前要完成信息处理, 是需要在一个客观存在的计算机上完成的…

永劫无间游戏辅助攻略:2024阵容搭配攻略大全!云手机辅助!

《永劫无间》是一款备受玩家喜爱的动作类游戏&#xff0c;其丰富的角色选择和多样的技能搭配让玩家在战斗中体验到了极大的乐趣。然而&#xff0c;要在竞争激烈的战场上脱颖而出&#xff0c;仅仅依靠基础的游戏理解是远远不够的。为了帮助广大玩家提升战斗力&#xff0c;本文将…

安防巡检机器人:守护安全的智能卫士

安防巡检机器人&#xff0c;作为机器人技术在安防领域的杰出应用&#xff0c;是一种集自主导航、智能巡检、环境监测、远程监控等多功能于一体的智能装备。这些机器人通过集成先进的传感器、高清摄像头、智能算法和导航系统等模块&#xff0c;实现了全天候、全方位、自主化的安…

芒果TV大模型来袭 | AI如何重塑微短剧制作未来?

在数字化浪潮推动下&#xff0c;7月23日&#xff0c;芒果TV大模型正式通过生成式人工智能大语言模型备案审核&#xff0c;并预计2024年内可应用于微短剧生产&#xff0c;可支撑节目创意策划、内容创作和生成、角色拟人对话、生成式内容推荐等行业应用场景。 市场对高质量内容的…

33.【C语言】实践扫雷游戏

预备知识&#xff1a; 第13篇 一维数组 第13.5篇 二维数组 第28篇 库函数 第29篇 自定义函数 第30篇 函数补充 0x1游戏的运行&#xff1a; 1.随机布置雷 2.排雷 基本规则&#xff1a; 点开一个格子后&#xff0c;显示1&#xff0c;对于9*9&#xff0c;代表以1为中心的去…

vue element-ui日期控件传参

前端&#xff1a;Vue element-ui <el-form-item label"过期时间" :rules"[ { required: true, message: 请选择过期时间, trigger: blur }]"><el-date-picker v-model"form.expireTime" type"date" format"yyyy-MM-dd&…

报错Found dtype Long but expected Float解决办法

Found dtype Long but expected Float错误通常发生在尝试将一个数据类型为Long的张量传递给一个期望数据类型为Float的函数或操作时。 在PyTorch中&#xff0c;Long和Float是两种常见的数据类型&#xff0c;分别对应于64位整数和32位浮点数。某些函数或操作可能只接受特定数据…

一些电脑的操作技巧,你知道吗?

我整理了几个电脑使用的实用技巧&#xff0c;能够帮你提升办公效率&#xff0c;一起来看看吧&#xff01; 技巧一&#xff1a;反方向移动单元格 一般来讲&#xff0c;我们按下【Tab】键、【Enter】键的时候&#xff0c;会切换到右边或者下边的单元格&#xff0c;想要反向移动…

QEMU源码全解析 —— CPU虚拟化(11)

接前一篇文章: 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 《深度探索Linux系统虚拟化原理与实现》—— 王柏生 谢广军, 机械工业出版社 特此致谢! 前边几回又再次讲了一下VMX,本回开始讲解VCPU…

Mybatis(四)特殊SQL的查询:模糊查询、批量删除、动态设置表明、添加功能获取自增的主键

实体类&#xff1a; 数据库&#xff1a; 1、模糊查询 方案一&#xff1a; 不适用#{ }&#xff0c;’%?%‘ 问号是属于字符串的一部分 不会被解析成占位符&#xff0c;会被当作是我们字符串的一部分来解析&#xff0c;所以我们执行的语句中找不到占位符&#xff0c;但是我们却…

论文写作之latex配置(VSCODE+TEXT LIVE)

1.overleaf 初学者学习latex可以用这个练习&#xff0c;可以在线编辑十分方便&#xff0c;但是编译时间受限制 网站&#xff1a;https://www.overleaf.com/project 2.Tex live 选择一个.iso文件下载 网站&#xff1a;Index of /CTAN/systems/texlive/Images/ 下载成功&am…

Tinygrad,llama3,Reward Model

目录 Tinygrad 与其他框架的比较 llama3 Reward Model Tinygrad 是一个轻量级的深度学习框架,由George Hotz(也被称为geohot)开发。以下是对Tinygrad的详细介绍: 与其他框架的比较 与PyTorch、TensorFlow等更全面的深度学习框架相比,Tinygrad在功能上可能有所限制,…

IDEA git配置

1. git下载 您可以从git官方网站下载git。在https://git-scm.com/downloads下载页面上&#xff0c;您可以选择适用于您的操作系统的版本进行下载。 2、idea配置git(version control)

【Java基础】动态代理与代理模式哪些事儿

文章目录 代理静态代理动态代理基于接口的jdk动态的demo源码解析Proxy.newProxyInstancejdk 动态的生成的字节码 基于父类的cglib动态代理源码解析 代理设计模式应用场景 Spring AOP小结 代理 代理其实就是扩展目标对象的功能&#xff0c;比如普通人不具备超人能力&#xff0c…