java复习篇 数据结构:链表第一节

news2024/9/25 2:31:05

目录

单向链表

初始

头插

思路

情况一

情况二

代码

尾插

思路

遍历

优化遍历

遍历验证头插

尾插代码

优化

尾插测试

get

思路

代码

测试

insert

思路

代码

优化

测试

remove

移除头结点

提问

移除指定位置

测试


单向链表

每个元素只知道自己的下一个元素是谁,最后一个元素的下一个元素为null

初始

public class SingleLinkedList {
    
    // 头指针
    private Node head;

    // 节点类      private对外隐藏细节
    @Data
    @AllArgsConstructor
    private static class Node {
        private int value;
        private Node next;
    }

}

将内部类定义为静态主要有两个原因:

  1. 实例化方式:静态内部类的实例化不需要依赖于外部类。而普通的内部类在实例化时会隐含地包含一个对外部类的引用,因此,普通的非静态内部类不能脱离外部类实例而单独存在。
  2. 访问方式:静态内部类可以使用静态方法直接通过类名来访问外部类的静态成员,而不需要创建外部类的实例。而普通的内部类需要先创建外部类的实例,然后通过该实例来访问外部类的静态成员。

头插

思路

对于使用者来说,我给你一个value值,你要将我的这个value值放入到链表头结点处

情况一

一开始,无节点,现在新增一个新节点

head = new Node(value, null);

情况二

一开始,有节点,现在新增一个新节点

head = new Node(value, head);

新节点的next指针指向原来节点,原来节点地址为头指针指向的地址

代码

    public void addFirst(int value) {
        head = new Node(value, head);
    }

为什么没有情况一?

开始时,head为null,情况二包含情况一

尾插

思路

对于使用者来说,我给你一个value值,你要将我的这个value值放入到链表最后面

那我怎么知道你链表什么时候是最后面

遍历

遍历到最后一个节点,此时它的next指针指向null

注意:头指针是为了记录第一个节点地址,不能动,所以我定义一个可以移动的指针开始指向第一个节点

    public void foreach() {
        Node p = head;
        while (p != null) {
            System.out.println(p.value);
            p = p.next;
        }
    }

优化遍历

实际开发中,你可能不是要打印,而是对加进来的值有其他操作,此时,换成函数式编程

    public void foreach(Consumer<Integer> consumer) {
        Node p = head;
        while (p != null) {
            consumer.accept(p.value);
            p = p.next;
        }
    }

遍历验证头插

public class Test {
    public static void main(String[] args) {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.addFirst(8);
        singleLinkedList.addFirst(7);
        singleLinkedList.addFirst(6);
        singleLinkedList.addFirst(5);
        singleLinkedList.foreach(System.out::println);
    }
}

为什么是倒序?

头插,先插的会随着后续插入一次次向后挪动

尾插代码

通过遍历,可以知道指针指向过最后一个节点后,然后指向了null

那让指针一直指,最后一次的下一个节点不为null时,为我们所需要的节点

    public void addLast(int value) {
        Node p = head;
        while (p.next != null) {
            p = p.next;
        }
        p.next = new Node(value, null);
    }

存在问题:如果我链表啥也没有,那么p.next直接空指针

优化

链表什么也没有,此时添加元素不就是头插嘛

    public void addLast(int value) {
        if (head == null) {
            addFirst(value);
            // 不要忘记return,否则会有相同值
            return;
        }
        Node p = head;
        while (p.next != null) {
            p = p.next;
        }
        p.next = new Node(value, null);
    }

尾插测试

public class Test {
    public static void main(String[] args) {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.addLast(8);
        singleLinkedList.addLast(7);
        singleLinkedList.addLast(6);
        singleLinkedList.addLast(5);
        singleLinkedList.foreach(System.out::println);
    }
}

get

思路

list(index)  是通过给一个索引,然后得到该索引对应位置的值。

对于链表,给一个索引,返回该节点的值。

代码

    public int get(int index) {
        int i = 0;
        Node p = head;
        while (p != null) {
            if (i == index) {
                return p.value;
            } else {
                p = p.next;
                i++;
            }
        }
        throw  new IllegalArgumentException("索引越界异常");
    }

也可以用for循环写

public Node findNode(int index) {
    int i = 0;
    for (Node p = head; p != null; p = p.next, i++) {
        if (i == index) {
            return p;
        }
    }
    return null;
}

public int get(int index) {
    Node node = findNode(index);
    if (node == null) {
        throw new IllegalArgumentException(StringUtils.format("索引: {} 不合法", index));
    }
    return node.value;
}

测试

public class Test {
    public static void main(String[] args) {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.addLast(8);
        singleLinkedList.addLast(7);
        singleLinkedList.addLast(6);
        singleLinkedList.addLast(5);
        singleLinkedList.foreach(System.out::println);
        System.out.println("====");
        System.out.println(singleLinkedList.get(0));
    }
}

insert

思路

我要向某个位置插入某个值,那么我需要知道这个位置的前面一个节点(其next 指向当前位置)

代码

    public void insert(int index, int value) {
        Node 前节点 = findNode(index - 1);
        if (前节点 == null) throw new IllegalArgumentException("索引越界异常");
        前节点.next = new Node(value, 前节点.next);
    }
    private Node findNode(int index) {
        int i = 0;
        Node p = head;
        while (p != null) {
            if (i == index) {
                return p;
            } else {
                p = p.next;
                i++;
            }
        }
        return null;
    }

index = 0时,此时返回null,抛出异常,显然不对

优化

index=0时插入,即头插

    public void insert(int index, int value) {
        if (index == 0) {
            addFirst(value);
            return;
        }
        Node 前节点 = findNode(index - 1);
        if (前节点 == null) throw new IllegalArgumentException("索引越界异常");
        前节点.next = new Node(value, 前节点.next);
    }

测试

public class Test {
    public static void main(String[] args) {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.addLast(8);
        singleLinkedList.addLast(7);
        singleLinkedList.addLast(6);
        singleLinkedList.addLast(5);
        singleLinkedList.foreach(System.out::println);
        System.out.println("====");
        singleLinkedList.insert(2, 100);
        singleLinkedList.foreach(System.out::println);
    }
}

remove

移除头结点

    public void removeFirst() {
        if (head == null) {
            return;
        }
        head = head.next;
    }

提问

1这个节点还存在,有没有因此而造成内存泄露?

不会,1节点无引用指向他,JVM垃圾回收会处理

移除指定位置

    public void remove(int index) {
        if (index == 0) {
            removeFirst();
            return;
        }
        Node 前节点 = findNode(index - 1);
        if (前节点 == null) throw new IllegalArgumentException("索引越界异常");
        前节点.next = 前节点.next.next;
    }

测试

public class Test {
    public static void main(String[] args) {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.addLast(8);
        singleLinkedList.addLast(7);
        singleLinkedList.addLast(6);
        singleLinkedList.addLast(5);
        singleLinkedList.foreach(System.out::println);
        System.out.println("====");
        singleLinkedList.insert(2, 100);
        singleLinkedList.foreach(System.out::println);
        System.out.println("====");
        singleLinkedList.remove(4);
        singleLinkedList.foreach(System.out::println);
    }
}

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

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

相关文章

大模型相关学习资料整理【长久更新】

笔者学习和收集大模型相关资料&#xff0c;只收集&#xff1a;官方 OR 易懂 OR 全面。 且后续我会针对大模型的名词和新机制做专门易懂的博客讲解&#xff0c;可以点个关注。等待后续更新。 目前整理资料如下&#xff1a; 1. 核心应用开发框架 1. semantic-kernel【微软】 …

DocsOpenApi自动化校验

一、背景 生产环境的文档中心的OpenApi和Kong服务配置的OpenApi可能存在不一致的情况&#xff0c;比如生产环境的文档中心有某个OpenApi&#xff0c;但是Kong服务没有配置到&#xff0c;那客户使用就会有问题。所以&#xff0c;前段时间&#xff08;M09版本&#xff09;花了4个…

2017年认证杯SPSSPRO杯数学建模C题(第二阶段)移动端考研产品的春天真的到来了吗全过程文档及程序

2017年认证杯SPSSPRO杯数学建模 C题 移动端考研产品的春天真的到来了吗 原题再现&#xff1a; 2017 年的全国硕士研究生招生考试共有 201 万人报名参加&#xff0c;比去年增加了 24 万名考生&#xff0c;增加 13.56%。看起来新一轮的考研热潮即将到来&#xff0c;而考研教学和…

Springboot+vue的科研工作量管理系统的设计与实现(有报告),Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的科研工作量管理系统的设计与实现&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的科研工作量管理系统的设计与实现…

【RT-DETR有效改进】FasterNet一种跑起来的主干网络( 提高FPS和检测效率)

前言 大家好&#xff0c;这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进&#xff0c;内容持续更新&#xff0c;每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本&#xff0c;同时修改内容也支持ResNet32、ResNet101和PP…

WhatsApp怎么营销引流?

随着移动互联网的普及&#xff0c;越来越多的企业开始利用社交媒体平台来进行推广和营销。其中&#xff0c;全球最流行的即时通讯软件之一 WhatsApp&#xff0c;为企业提供了一个新的营销渠道。但是&#xff0c;许多企业不知道如何利用 WhatsApp 进行营销引流。今天&#xff0c…

scrapy框架核心知识Spider,Middleware,Item Pipeline,scrapy项目创建与启动,Scrapy-redis与分布式

scrapy项目创建与启动 创建项目 在你的工作目录下直接使用命令: scrapy startproject scrapytutorial运行后创建了一个名为scrapytutorial的爬虫工程 创建spider 在爬虫工程文件内&#xff0c;运行以下命令&#xff1a; scrapy genspider quotes创建了名为quotes的爬虫 …

【计算机网络】【练习题】【新加坡南洋理工大学】【Computer Control Network】

说明&#xff1a; 仅供学习使用。 一、题目描述 该题目描述一个网络中传播时延&#xff08;Transmission Delay&#xff09;的例子。题目如下&#xff1a; 二、问题解答&#xff08;个人&#xff09; 笔者第3问采用均值不等式求解。标答中采用求导数的方法求极值。似乎均值…

多流转换 (分流,合流,基于时间的合流——双流联结 )

目录 一&#xff0c;分流 1.实现分流 2.使用侧输出流 二&#xff0c;合流 1&#xff0c;联合 2&#xff0c;连接 三&#xff0c;基于时间的合流——双流联结 1&#xff0c;窗口联结 1.1 窗口联结的调用 1.2 窗口联结的处理流程 2&#xff0c;间隔联结 2.1 间隔联…

线程、进程、多线程

什么是线程&#xff1f; 当我们用bilibili看电影&#xff0c;我们会看到画面、听到声音、看到弹幕&#xff0c;这三个功能每一个就是一个线程 什么是进程&#xff1f; 当我们打开bilibili软件或者网站&#xff0c;就算什么都不干&#xff0c;计算机就已经形成了一个进程 学术…

网络组件、设备和关系网络图【推荐】

目录 网络上的设备&#xff1a; 设备和台式计算机&#xff1a; 防火墙&#xff1a; 服务器&#xff1a; 集线器和交换机&#xff1a; 路由器&#xff1a; 调制解调器和无线接入点调制解调器&#xff1a; 无线接入点&#xff1a; 网络架构&#xff08;有时称为网络设计&…

[UI5 常用控件] 02.Title,Link,Label

文章目录 前言1. Title1.1 结合Panel1.2 结合Table1.3 Title里嵌套Link 2. Link3. Label3.1 普通用法3.2 在Form里使用 前言 本章节记录常用控件Title,Link,Label。 其路径分别是&#xff1a; sap.m.Titlesap.m.Linksap.m.Label 1. Title Title可以结合其他控件一起使用 1.…

2. figure 常见属性

2. figure 常见属性 一 figsize二 dpi三 facecolor四 edgecolor五 frameon 数据可视化是数据分析中不可或缺的一环&#xff0c;而Matplotlib作为Python中最流行的绘图库之一&#xff0c;扮演着重要的角色。在Matplotlib中&#xff0c;matplotlib.figure.Figure对象是构建图形的…

Spring5系列学习文章分享---第四篇(JdbcTemplate+概念配置+增删改查数据+批量操作 )

目录 JdbcTemplateJdbcTemplate&#xff08;概念和准备&#xff09;JdbcTemplate 操作数据库&#xff08;新增update&#xff09;JdbcTemplate 操作数据库&#xff08;修改和删除update&#xff09;JdbcTemplate 操作数据库&#xff08;查询返回某个值queryForObject&#xff0…

深入浅出AI落地应用分析:AI视频生成Top 5应用

接下俩会每周集中体验一些通用或者垂直的AI落地应用&#xff0c;主要以一些全球或者国外国内排行较前的产品为研究对象&#xff0c;「AI 产品榜&#xff1a; aicpb.com」以专题的方式在博客进行分享。 一、Loom 二、Runway 产品链接&#xff1a;https://app.runwayml.com/ …

防御实验:(部分)

步骤一&#xff1a;了解前提&#xff1a; 1.1 题目要求&#xff1a; 需求一&#xff1a;DMZ区存在两台服务器&#xff0c;现在要求生产区的设备仅能在办公时间&#xff08;9&#xff1a;00 - 18&#xff1a;00&#xff09;访问&#xff0c;办公区的设备全天都可以访问。 需求二…

记录centos安装nginx过程和问题

今天在centos上安装了nginx&#xff0c;遇到了些问题&#xff0c;记录一下。 使用yum直接安装的话安装的版本是1.20.1&#xff0c;使用源码包安装可以装到1.25.0&#xff08;最新稳定版&#xff09;。很有意思的一点是两种安装方法下安装的路径是不同的&#xff0c;且源码安装…

ASP.NET Core基础之用扩展方法封装服务配置

阅读本文你的收获 了解C#中的扩展方法机制学会在ASP.NET Core 中&#xff0c;用扩展方法封装服务配置&#xff0c;使得代码更加简洁 一、什么是扩展方法 扩展方法使能够向现有类型添加方法&#xff0c;而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法…

Go实现LRU算法

LRU是什么&#xff1f; LRU是内存淘汰策略&#xff0c;LRU &#xff08;Least recently used&#xff1a;最近最少使用&#xff09;算法在缓存写满的时候&#xff0c;会根据所有数据的访问记录&#xff0c;淘汰掉未来被访问几率最低的数据。也就是说该算法认为&#xff0c;最近…

惠普战66笔记本进PE系统无硬盘解决方法

1 问题描述 针对惠普战66笔记本&#xff0c;在使用优启通进行系统重装时&#xff0c;当进人 PE 系统后&#xff0c;看不到笔记本自带的固态硬盘&#xff0c;因而无法将系统重装到笔记本中。 现在&#xff0c;介绍一种方法&#xff0c;各位读者可以尝试&#xff0c;博主已经尝试…