链表(LinkedList)

news2024/9/29 3:23:25

链表(LinkedList)

链表是有序的列表,但是其在内存的存储不一定连续

由这张图我们可以看出

  1. 链表是以节点的方式来存储的,是链式存储

  2. 每个节点包含data域,next域:指向下一个节点

  3. 我们可以发现链表的各个节点不一定是连续存储的

  4. 链表分为带头节点的链表和没有头节点的链表

单链表创建思路分析

  1. 先创建一个head头节点,作用就是表示单链表的头

  2. 然后我们每添加一个节点,就直接加入到链表的最后

遍历

我们可以声明一个变量,让他帮助我们遍历完该链表

代码实现

//定义HeroNode,每个HeroNode对象就是一个节点
class HeroNode {
    public int no;
    public String name;
    public String nickname;
    public HeroNode next;// 指向下一个节点
​
    // 构造器
    public HeroNode(int no, String name, String nickname) {
        this.no = no;
        this.name = name;
        this.nickname = nickname;
    }
​
    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

实现我们的链表

// 定义SingleLinkedList管理我们的英雄
class SingleLinkedList {
    // 先初始化一个头节点,头节点不要动
    private HeroNode head = new HeroNode(0, "", "");
​
    /* 添加节点到单向链表
     思路:当不考虑编号顺序时
     1. 找到当前链表的最后一个节点
     2.将最后的这个节点的next指向新的节点*/
    public void add(HeroNode heroNode) {
        // 因为head节点不能动 所以我们要声明一个变量帮助遍历
        HeroNode cur = head;
        // 遍历链表 找到最后
        while (true) {
            // 找到链表的最后
            if (cur.next == null) {
                break;
            }
            // 如果没有找到最后,将cur后移
            cur = cur.next;
        }
        // 当退出while循环时,cur指向最后
        cur.next = heroNode;
    }
​
    // 显示链表[遍历]
    public void show() {
        // 判断链表是否为空
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        HeroNode cur = head.next;
        while (true) {
            if (cur == null) {
                break;
            }
            // 输出节点信息
            System.out.println(cur);
            // 将cur后移,否则会出现死循环
            cur = cur.next;
        }
    }
}

对以上方法进行测试

public static void main(String[] args) {
    HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
    HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
    HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
    HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
    // 创建单链表
    SingleLinkedList singleLinkedList = new SingleLinkedList();
    singleLinkedList.add(hero1);
    singleLinkedList.add(hero2);
    singleLinkedList.add(hero3);
    singleLinkedList.add(hero4);
    singleLinkedList.show();
}

这里如果我们改变添加的顺序,我们会发现,输出的结果是按照我们添加的顺序显现出来的而不是按照编号的顺序显现的

按照编号的顺序添加(链表的插入)

思路:

  1. 首先找到新添加的节点的位置,是通过辅助变量,通过遍历来搞定的

  2. 新的节点.next=temp.next

  3. 将temp.next=新的节点s

代码实现

/*
* 第二种方式在添加英雄时,根据排名将英雄插入到指定位置
* (如果这个排名已经存在了,则添加失败,并给出提示)
* */
public void insert(HeroNode heroNode){
    // 头节点不能动,需要辅助变量
    // 因为单链表,我们找到的temp是位于添加位置的前一个节点,否则插入不了
    HeroNode temp = head;
    boolean flag  = false;// flag标志添加的编号已经存在 无法添加
    while (true){
        if (temp.next==null){// 说明temp已经在链表的最后了
            break;
        }
        if (temp.next.no>heroNode.no){// 说明已经找到了要插入的位置,就在temp后面插入
            break;
        }else if (temp.next.no==heroNode.no){// 说明需要添加的节点点已经存在了
            flag=true;// 说明编号存在
            break;
        }
        temp=temp.next;
    }
    if (flag){
        System.out.println("编号已经存在 不能加入:"+heroNode.no);
    }else {
        // 插入到链表,temp的后面
        heroNode.next=temp.next;
        temp.next=heroNode;
    }
}

对以上代码的测试

singleLinkedList.insert(hero1);
singleLinkedList.insert(hero4);
singleLinkedList.insert(hero3);
singleLinkedList.insert(hero2);
singleLinkedList.show();

这样写出的代码,最终经过我们的测试,其是按照我们的编号进行升序排列的,也就是实现了我们链表的插入

ps: heroNode.next=temp.next; temp.next=heroNode;

这两处的代码顺序一定不能改变,否则就形成了一个死循环,具体我们可以通过debug来发现这个问题

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

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

相关文章

再见了HDMI Alt

点击上方“LiveVideoStack”关注我们▲扫描图中二维码或点击阅读原文▲了解音视频技术大会更多信息编者按:其实在未能推出配套线缆和适配器的那一刻,HDMI Alt模式就已经没有未来了。HDMI已全面落后DisplayPort。本文来自Arstechnica。文/Scharon Hardin…

【SpringCloud】Nacos的安装与启动

【SpringCloud】Nacos的安装与启动 一、下载安装包 二、解压 三、端口配置 四、启动 五、访问 【SpringCloud】Nacos的安装与启动 一、下载安装包 在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码: GitHu…

分享149个PHP源码,总有一款适合您

PHP源码 分享149个PHP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 149个PHP源码下载链接:https://pan.baidu.com/s/1RKnEbbhpfUndnMrxG8rSIQ?pwd0nqp 提取码&#x…

LINUX学习之文本编辑器VIM/VI(八)

简介 VI 是 Unix 操作系统和类 Unix 操作系统中最通用的文本编辑器 VIM 编辑器是从 VI 发展出来的一个性能更强大的文本编辑器。可以主动的以字体颜色辨别语法的正确性,方便程序设计 VIM 与 VI 编辑器完全兼容 模式转换 如下图所示,一般模式下输入i、…

选出相似的文本按照相似度排序difflib.get_close_matches

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 选出相似的文本 按照相似度排序 difflib.get_close_matches 选择题 对于以下python代码表述错误的是? from difflib import get_close_matches myText"python" myList[&…

23种设计模式(十六)——备忘录模式【状态变化】

备忘录模式 文章目录 备忘录模式意图什么时候使用备忘录真实世界类比备忘录模式的实现备忘录模式的优缺点亦称:调解人、控制器、Intermediary、Controller、Mediator 意图 在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将这个对…

穿越万年的轮回[期望dp]

首先我们设置dpi,0/1,0/1dp_{i,0/1,0/1}dpi,0/1,0/1​表示经过iii次操作之后开头为red/edrred/edrred/edr,结尾为red/edrred/edrred/edr的串的期望redredred字符串个数。 然后我们考虑转移: 首先我们要来思考一下期望的本质,这样一个状态&…

「Python|VS Code」如何在VS Code中使用Jupyter Notebook运行Python代码

本文主要介绍如何在VS Code安装Jupyter Notebook的扩展并创建notebook文件,并在notebook中运行python代码。同时,介绍使用Jupyter notebook运行python代码的好处。 文章目录安装Jupyter notebook扩展并运行代码Jupyter notebook的好处安装Jupyter notebo…

第十章 STM32F103+ESP8266接入机智云 实现小型IOT智能家居项目

前言 最近有不少小伙伴私信留言,想要我推出一章能够通过APP进行远程控制并获取传感器信息的实验教程。说实话在嵌入式毕设里边,这算是中等偏上水平的了。刚好我也有兴趣写写。全篇4700多字,我写的很详细,按着文章一步一步操作即可…

RabbitMQ的基础学习(上)

前言: RabbitMQ是一个基于AMQP规范实现的消息队列。它具有性能好、高可用、跨平台性、社区活跃等优点,比较适合中小型公司使用。掌握RabbitMQ相关知识,对工作和学习都有帮助。下面我讲详细介绍一下Rabbit的相关知识。 正文: 一、…

【机器学习】缺失值的处理方法总结

目录:缺失值的处理一、总录二、引言三、数据缺失的原因四、数据缺失的类型五、数据缺失的处理方法5.1 删除记录5.2 数据填充5.2.1 替换缺失值5.2.2 拟合缺失值5.2.3 虚拟变量5.3 不处理六、实证演练七、小结一、总录 二、引言 业界广泛流传这样一句话:数…

java构造器2023021

构造器: 构造器是一个特殊的方法,用于创建实例时执行初始化。构造器是创建对象的重要途径(即使使用工厂模式、反射等方式创建对象,其实质依然是依赖于构造器),因此Java类必须包含一个或一个以上的构造器。 …

23种设计模式(十五)——适配器模式【接口隔离】

文章目录 意图什么时候使用适配器真实世界类比适配器模式的实现适配器模式的优缺点亦称:封装器模式、Wrapper、Adapter 意图 将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器。 什么时候使用适配器 1、系统需要使用现有的类,而这…

软件设计到底是什么?

软件设计是什么: 就是讨论要用什么技术实现功能?就是要考虑选择哪些框架和中间件?设计就是设计模式?设计就是Controller、Service加Model?…… 一百个程序员,就有一百种理解。若按照这些方式去了解“软件…

Java设计模式中状态模式介绍/状态模式怎么使用

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用! 6.6 状态模式 6.6.1定义 对有状态的对象,把复杂的"判断逻辑"提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变…

【C++】哈希表 | 闭散列 | 开散列 | unordered_map 和 unordered_set 的模拟实现

​🌠 作者:阿亮joy. 🎆专栏:《吃透西嘎嘎》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉unordere…

Ubuntu20.04/22.04 安装 Arduino IDE 2.x

这周收到两片基于LGT8F328P LQFP32的Arduino Mini EVB, 机器上没有 Arduino 环境需要新安装, 正好感受一下新出的 Arduino IDE 2.x, 记录一下 Ubuntu 20.04/22.04 下安装 Arduino IDE 2.x 的过程. 下载解压 下载 访问 Arduino 的官网下载 https://www.arduino.cc/en/softwar…

2021-04-12

今天在练习自定义标题栏(Android初级开发(四)——补充3)的过程中遇到了隐藏系统自带标题栏的问题,现将几种去掉系统自带标题栏的方式做一总结。大体上可以分为两种方式,一种是修改xml文件(这种方…

第六层:继承

文章目录前情回顾继承继承的作用继承的基本语法继承方式公共继承保护继承私有继承继承中的对象模型继承中的构造和析构顺序继承中同名成员访问非静态成员静态成员多继承语法注意多继承中的对象模型多继承父类成员名相同菱形继承概念菱形继承出现的问题虚继承步入第七层本章知识…

【数据分析】(task3)数据重构

note 数据的合并:df自带的join方法是横向合并,append方法是纵向(上下)合并拼接;pd的merge方法是横向合并,然后用刚才的apend进行纵向合并。数据的重构:stack函数的主要作用是将原来的列转成最内…