数据结构-列表LinkedList

news2024/10/6 12:35:52

一,链表的简单的认识.

    数组,栈,队列是线性数据结构,但都算不上是动态数据结构,底层都是依托静态数组,但是链表是确实真正意义上的动态数组.

为什么要学习链表?

   1,链表时最简单的动态数据结构

   2,掌握链表有助于学习更复杂的数据结构,例如,二叉树,trie.

   3,学习链表有助于更深入的理解引用和递归,

1,链表

2,创建Node

二,链表的方法

1,对链表添加操作

 (1)链表头添加元素

(2)链表中间添加元素

关键点:找到要待添加位置的前一个结点
(3)向链表尾部添加元素

添加完成后

总结:

1,先创建节点node

2,找到最后一个节点pre

3,pre.next=node

2,使用虚拟头结点(解决在头部添加结点的特殊处理)

(注意:添加完成之后需要更新头节点)

3,链表的遍历,查询和更新操作

addHead() 向头部添加节点

addTail()  向尾部添加节点

add() 添加节点,默认头结点

get(index) 获取指定位置的节点

getFirst() 获取头节点

getLast() 获取尾节点

getSize() 获取索引

isEmpty() 判断链表是否为空

contains(val) 判断链表是否存在给定节点

toString() 遍历链表

4,从链表中删除元素

5,链表的时间复杂度分析

(1) 添加元素
(2) 删除操作
(4)修改操作
(5)查找操作

三,用代码实现链表

(需要注意的是用内部类,解决链表的数据类型(节点--Node))

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 链表:真正的动态数据结构
 */
public class LinkedList<T> {
    // 定义结点
    private class Node {
        T val; // 结点的值
        Node next; // 表示下一个结点

        public Node(T val) {
            this.val = val;
        }

        public Node(T val, Node next) {
            this.val = val;
            this.next = next;
        }
    }


    // 链表的头结点
    private Node header;
    private int size;

    // 构造链表
    public LinkedList() {
        this.header = null;
        this.size = 0;
    }

    // 判断链表是否为空
    public boolean isEmpty() {
        return this.size == 0;
    }

    // 获取链表中元素的个数
    public int getSize() {
        return this.size;
    }

    // 向链表中添加元素

    /**
     * 在链表的头部添加
     */
    public void addHeader(T val) {
        add(0, val);
    }

    /**
     * 在链表的尾部添加
     */
    public void addTail(T val) {
        add(this.size, val);
    }

    // 在任意位置添加
    /*public void add(int index, T val) {
        if (index < 0 || index > this.size) {
            throw new IllegalArgumentException("index is invalid!");
        }

        // 1、创建结点
        Node node = new Node(val);
        // 特殊处理:头结点,为啥?头结点没有前驱
        if (index == 0) {
            this.header = node;
            this.size++;
            return;
        }
        // 2、找到插入位置的前驱pre
        Node pre = this.header;
        int count = 1;
        while (count < index) {
            pre = pre.next;
            count++;
        }
        // 3、改变索引的指向
        node.next = pre.next;
        pre.next = node;
        // 4、更新size
        this.size++;
    }*/

    public void add(int index, T val) {
        if (index < 0 || index > this.size) {
            throw new IllegalArgumentException("index is invalid!");
        }
        // 0、创建结点,作为头结点的前驱
        Node dummyHead = new Node(null);
        dummyHead.next = this.header;
        // 1、创建结点
        Node node = new Node(val);
        // 2、找前驱结点
        Node pre = dummyHead;
        int count = 1;
        while (count <= index) {
            pre = pre.next;
            count++;
        }
        // 3、改变索引的指向
        node.next = pre.next;
        pre.next = node;
        // 4、更新size
        this.size++;
        // 5、更新头结点
        this.header = dummyHead.next;
    }

    @Override
    public String toString() {
        List<String> result = new ArrayList<>();
        // 遍历链表
        Node cur = this.header;
        while (cur != null) {
            result.add(cur.val.toString() + "----->");
            cur = cur.next;
        }
        return result.stream().collect(Collectors.joining());
    }

    public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int i = 1; i <= 10; i++) {
            Random random = new Random();
            int val = random.nextInt(1000) + 1;
            System.out.println(val);
            linkedList.addHeader(val);
            System.out.println(linkedList);
        }
        linkedList.add(10,249);
        System.out.println(linkedList);
    }
}

四,使用链表实现队列

基本掌握链表的功能,就可以尝试着用链表实现栈或者队列,我们之前用的底层数据类型时数组.

// 定义节点类
class Node {
    int data;
    Node next;

    public Node(int data) {
        this.data = data;
        this.next = null;
    }
}

// 定义栈类
class Stack {
    private Node top;

    public Stack() {
        this.top = null;
    }

    public void push(int data) {
        Node newNode = new Node(data);
        if (top == null) {
            top = newNode;
        } else {
            newNode.next = top;
            top = newNode;
        }
    }

    public int pop() {
        if (top == null) {
            throw new EmptyStackException();
        } else {
            int data = top.data;
            top = top.next;
            return data;
        }
    }
}

// 定义队列类
class Queue {
    private Node front;
    private Node rear;

    public Queue() {
        this.front = null;
        this.rear = null;
    }

    public void enqueue(int data) {
        Node newNode = new Node(data);
        if (rear == null) {
            front = newNode;
            rear = newNode;
        } else {
            rear.next = newNode;
            rear = newNode;
        }
    }

    public int dequeue() {
        if (front == null) {
            throw new NoSuchElementException();
        } else {
            int data = front.data;
            front = front.next;
            if (front == null) {
                rear = null;
            }
            return data;
        }
    }
}

上面代码演示了如何用链表实现栈和队列,分别通过Stack类和Queue类来实现。可以根据自己的需要进一步扩展这两个类的功能,以满足具体的需求。

五,链表的用处

链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。

  1. 动态内存分配:链表允许在运行时动态地分配和释放内存,相比数组,不需要提前指定数据容量。

  2. 插入和删除节点:链表的插入和删除操作非常高效,只需要修改节点的指针即可,不需要移动其他元素。

  3. 不连续存储:链表的节点可以在内存中的任意位置,它们通过指针进行连接,可以灵活地利用内存空间。

  4. 可变长度:链表的长度可以根据需要进行动态调整,可以方便地增加或减少节点。

  5. 实现其他数据结构:链表可以作为其他数据结构的基础,例如栈、队列、哈希表等。

需要注意的是,链表在访问节点时需要遍历整个链表,因此随机访问效率较低,不适合频繁的随机访问操作。同时,链表需要额外的空间存储指针,因此相比数组会有一定的空间开销。根据具体问题的需求和场景,选择合适的数据结构非常重要。

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

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

相关文章

fpga_硬件加速引擎

一 什么是硬件加速引擎 硬件加速引擎&#xff0c;也称硬件加速器&#xff0c;是一种采用专用加速芯片/模块替代cpu完成复杂耗时的大算力操作&#xff0c;其过程不需要或者仅需要少量cpu参与。 二 典型的硬件加速引擎 典型的硬件加速引擎有GPU&#xff0c;DSP&#xff0c;ISP&a…

【Web】CTFSHOW 常用姿势刷题记录(全)

目录 web801 web802 web803 web804 web805 web806 web807 法一&#xff1a;反弹shell 法二&#xff1a;vps外带 web808 web809 web810 web811 web812 web813 web814 web815 web816 web817 web818 web819 web820 web821 web822 web823 web824 web825…

python统计分析——单因素方差分析

参考资料&#xff1a;用python动手学统计学 方差分析&#xff1a;analysis of variance&#xff0c;缩写为ANOVA 1、背景知识 1.1 要使用方差分析&#xff0c;数据的总体必须服从正态分布&#xff0c;而且各个水平内部的方差必须相等。 1.2 反复检验导致显著性结果更易出现…

专业130+总分410+上海交通大学819信号系统与信号处理考研上交电子信息通信生医电科,真题,大纲,参考书。

今年考研顺利结束&#xff0c;我也完成了目前人生最大的逆袭&#xff0c;跨了两个层级跨入c9&#xff0c;专业课819信号系统与信息处理135&#xff0c;数一130总分410&#xff0c;考上上海交大&#xff0c;回想这一年经历了很多&#xff0c;也成长了很多。从周围朋友&#xff0…

Mysql数据库学习之范式

范式 范式简介 在关系型数据库中&#xff0c;关于数据表设计的基本原则、规则称为范式。可以理解为&#xff0c;一张数据表的设计结构需要满足的某种设计标准的级别&#xff0c;要想设计一个结构合理的关系型数据库&#xff0c;必须满足一定的范式。 范式都包含哪些 6种范式…

在当前源文件的目录或生成系统路径中未找到文件

vsqt中增加&#xff0c;减少文件&#xff0c;都必须要动一下cmakelist.txt,点一下换行或者保存 因为vsqt反应不过来 1。都必须要动一下cmakelist.txt,点一下换行或者保存 2.然后全部重新生成&#xff0c;或者重新扫描解决方案&#xff08;多扫几次&#xff09;

SSM项目集成Spring Security 4.X版本 之 加入DWZ,J-UI框架实现登录和主页菜单显示

目录 前言 一、加入DWZ J-UI框架 二、实现登录页面 三、实现主页面菜单显示 前言 大家好&#xff01;写文章之前先列出几篇相关文章。本文内容也在其项目中接续实现。 一. SSM项目集成Spring Security 4.X版本&#xff08;使用spring-security.xml 配置文件方式&#xff…

IDEA中Vue的安装和使用【window10】

一.准备工作 Vue是前端开发框架。搭建框架&#xff0c;首先要搭建环境。搭建Vue的环境工具&#xff1a;node.js&#xff08;JavaScript的运行环境&#xff09;&#xff0c;然后再用nodejs里面的npm&#xff08;包管理和分发工具&#xff09;来安装依赖包。二.安装node.js 下载…

【办公类-22-07】周计划系列(2)“主题知识” (2024年调整版本)

作品展示 调用原来的主题知识素材&#xff0c;制作下学期的19周的主题知识word 背景需求&#xff1a; 开学了&#xff0c;继续做周计划系列&#xff0c;在原有基础上&#xff0c;进行进一步代码优化 【办公类-22-02】周计划系列&#xff08;2&#xff09;-生成“主题知识”&…

【Android】View 与 ViewGroup

View 是 Android 所有控件的基类&#xff0c;我们平常所用的 TextView 和 ImageView 都是继承自 View 的&#xff0c;源码如下&#xff1a; public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {... }public class ImageView extends View {.…

升级加薪聊绩效过程中,如果我觉得自己受到了老板“不公正”的对待,该如何“怼”回去?...

老板与员工谈绩效 今天分享的主题是「职场的向上管理」 什么是向上管理&#xff1f; 向上管理是一种有自主意识的方法 通过与你的老板在目标上达成共识&#xff0c;并最终用这个目标满足你、你的老板、你的组织的最大利益 向上管理与你的老板无关&#xff0c;老板都没得选的&am…

Java JDK 下载和配置

Java JDK 下载 下载网址&#xff1a;https://www.oracle.com/java/technologies/javase/jdk21-archive-downloads.html jdk文件夹的目录介绍 bin: 主要存放的是Java的编译器、解析器等工具。 jre&#xff1a;Java runtime environment, Java 运行时环境。 jre/bin:Java平台…

RuntimeError: CUDNN_STATUS_EXECUTION_FAILED

问题描述&#xff1a; 运行代码时候报错&#xff1a; 原因&#xff1a;pytorch与cuda版本不对&#xff0c;需要重新安装。不过我在复现代码的时候一般是要求特定的环境&#xff0c;不然会有其他错误&#xff0c;所以选择其他解决办法。 解决方案&#xff1a; 在train.py开头…

【图论】【堆优化的单源路径】LCP 20. 快速公交

作者推荐 【广度优先搜索】【网格】【割点】【 推荐】1263. 推箱子 LCP 20. 快速公交 小扣打算去秋日市集&#xff0c;由于游客较多&#xff0c;小扣的移动速度受到了人流影响&#xff1a; 小扣从 x 号站点移动至 x 1 号站点需要花费的时间为 inc&#xff1b; 小扣从 x 号站…

MySQL--索引结构

索引-索引结构 1. 概述2. 二叉树3. B-Tree4. BTree5. Hash 1. 概述 MySQL的索引是在存储引擎层实现的&#xff0c;不同的存储引擎有不同的索引结构&#xff0c;主要包含以下几种&#xff1a; 上述是MySQL中所支持的所有的索引结构&#xff0c;下面展示不同的存储引擎对于索引…

如何连接ACL认证的Redis

点击上方蓝字关注我 应用程序连接开启了ACL认证的Redis时与原先的方式有差别&#xff0c;本文介绍几种连接开启ACL认证的Redis的Redis的方法。 对于RedisACL认证相关内容&#xff0c;可以参考历史文章&#xff1a; Redis权限管理体系(一&#xff09;&#xff1a;客户端名及用户…

计算机网络-网络互联

文章目录 网络互联网络互联方法LAN-LAN&#xff1a;网桥及其互连原理使用网桥实现LAN-LAN使用交换机扩展局域网使用路由器连接局域网 LAN-WANWAN-WAN路由选择算法非自适应路由选择算法自适应路由选择算法广播路由选择算法&#xff1a;分层路由选择算法 网络互联 网络互联是指利…

设备树详解

设备树(Device Tree)基本概念及作用 设备树(Device Tree)基本概念 在内核源码中,存在大量对板级细节信息描述的代码。这些代码充斥在/arch/arm/plat-xxx和/arch/arm/mach-xxx目录,对内核而言这些platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的…

神经网络系列---分类度量

文章目录 分类度量混淆矩阵&#xff08;Confusion Matrix&#xff09;&#xff1a;二分类问题二分类代码多分类问题多分类宏平均法:多分类代码多分类微平均法&#xff1a; 准确率&#xff08;Accuracy&#xff09;&#xff1a;精确率&#xff08;Precision&#xff09;&#xf…

EasyRecovery2024免费不要钱的电脑数据恢复软件下载

EasyRecovery 2024易恢复软件在数据恢复方面的表现评价&#xff0c;EasyRecovery 2024易恢复软件在数据恢复领域享有良好的声誉&#xff0c;它提供了全面的功能&#xff0c;易于使用的界面以及可靠的数据恢复效果。以下是对该软件在数据恢复方面的详细评价&#xff1a; EasyRec…