Java单链表

news2024/11/22 8:37:04

链表的介绍:

1) 链表是以节点的方式来储存的,是链式存储结构

2)每个节点包含data域和next域,next域指向下一个节点

3)链表内存储的元素不一定连续

4)链表分带头节点的链表和不带头节点的链表
​​​​
​​​​

注:此处head为头节点并不存储数据,仅仅用来标识链表的头

单链表应用实例:

增:

思路分析1:

(1)先创建一个head节点

(2)后面没添加一个节点,就直接加入链表的最后

遍历:

(1)通过一个辅助变量遍历,帮助遍历整个链表

思路分析2:

改:

思路:

(1)先找到该节点,通过遍历

(2)temp.name== newHeroNode.name

        temp.nickname == newHeroNode.name

 

删:

思路分析:

即需要将指针指向新的节点即可

完整代码:

/**
 * 应用实例:
 * 使用带head头的单项链表实现-水浒英雄排行榜管理:
 * 1、完成对英雄任务的增删改查
 * 2、第一种方法在添加英雄时,直接添加到链表的尾部
 * 3、第二种方法在添加英雄时,根据排名将英雄插入到指定位置
 */

public class LinkedDEmo1{
    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.addByOrder(hero1);
          singleLinkedList.addByOrder(hero4);
          singleLinkedList.addByOrder(hero3);
          singleLinkedList.addByOrder(hero2);
 //         singleLinkedList.addByOrder(hero1);

        //显示一把
        singleLinkedList.list();

          //test the code to modify the node
        HeroNode newHeroNode = new HeroNode(2,"小路","玉麒麟??");
        singleLinkedList.update(newHeroNode);

        System.out.println("\n the situation after changing");
        singleLinkedList.list();

        // test to delete a node
        singleLinkedList.del(1);
        singleLinkedList.del(2);
        singleLinkedList.del(3);
        singleLinkedList.del(1);
        singleLinkedList.del(4);

        System.out.println("the situation after delete");
        singleLinkedList.list();

    }
}
//定义一个SingleLinkedlist管理英雄
class SingleLinkedList{
    //先初始化一个头节点,头节点不要动
    private HeroNode head= new HeroNode(0,"","");//头节点不存放具体数据仅仅表示此为链表头
    //添加节点到单向链表
    //当不考虑编号的顺序时候,找到当前链表的最后节点,将最后这个节点的next域指向新的节点
    public void add(HeroNode heroNode){
        //因为head节点不能动,因此我们需要一个辅助便利temp
        HeroNode temp =head;
        //遍历链表,找到最后
        while(true){
            //找到链表的最后
            if (temp.next == null){
                break;
            }
            //如果没找到最后,temp后移
            temp = temp.next;
        }
        //当退出while循环,temp指向链表最后
        //将最后这个节点的next指向新的节点
        temp.next = heroNode;
    }
    //第二种方式在添加英雄时候,根据排名将英雄插入到指定的位置
    //(如果有这个排名,则添加失败,并给出提示)
    public void addByOrder(HeroNode heroNode){
        //头指针不能动,通过辅助指针来遍历
        //因为单链表,因为我们找的temp是位于添加位置的前一个节点,否则插入不了
        HeroNode temp = head;
        boolean flag = false; //标识添加的编号是否存在,默认为false
        while (true) {
            if (temp.next == null) {//说明temp已经在链表最后
                break;
            }
            if (temp.next.no > heroNode.no) {
                //位置找到了,就在temp的后面
                break;
            } else if (temp.next.no == heroNode.no) {
                //说明希望添加的heronode的编号已经存在
                flag = true;  //说明编号存在
                break;
            }
            temp = temp.next;//后移,遍历当前链表
        }
        //判断flag 的值
        if (flag) {//不能添加,说明编号存在
            System.out.printf("准备插入的英雄编号%d已经存在了,不能加入\n",heroNode.no);
        }else{
            //插入到链表中,temp后面
            heroNode.next = temp.next;
            temp.next = heroNode;
        }
    }
//修改节点的信息,根据编号来修改,即no编号不能改
    //1、根据newHeroNode的no来修改即可
    public void update(HeroNode newHeroNode){
        //判断是否为空
        if (head.next == null){
            System.out.println("link is empty");
            return;
        }
        //find the node need to modify, according to the number
        //Define an auxiliary variable
        HeroNode temp = head.next;
        boolean flag = false;
        while(true){
            if (temp.next==null){
                break;// reach the end of the link
            }
            if(temp.no == newHeroNode.no){
                //find it
                flag = true;
                break;
            }
            temp = temp.next;
        }
        //according to the flag to determine whether to find nodes that need to be modified
        if(flag == true){
            temp.name = newHeroNode.name;
            temp.nickname = newHeroNode.nickname;
        }else{
            //did not find it
            System.out.printf("Node with number %d not found",newHeroNode.no);
        }
    }

    //显示链表遍历
    public void list(){
        //判断链表是否为空
        if(head.next == null){
            System.out.println("链表为空");
            return;
        }
        //因为头节点不能动,因此通过一个辅助变量遍历
        HeroNode temp = head.next;
        while(true){
            //判断是否到链表最后
            if(temp == null){
                break;
            }
            //输出节点信息
            System.out.println(temp);
            //将temp后移
            temp = temp.next;

        }
    }

    /**
     * delete the node
     * 1、we should try to find the node before the node to be deleted:temp
     * 2、temp.next = temp.next.next(The pointer needs to be redirected to the next node of the node to be deleted )
     *3、The deleted node will not have any other references and will be recycled by the garbage collection mechanism
     */

     // 1、The head node cannot be moved, so we need a temp auxiliary node to locate the previous node of the node to be deleted
     // 2、s说明,我们在比较时,是temp。next。no 和需要删除的节点的no进行比较
     public void del(int no){
         HeroNode temp=head;
         boolean flag = false;
         while(true){
             if (temp.next==null){
                 break;// reach the end of the link
             }
             if(temp.next.no == no){
             //找到了待删除节点的前一个节点temp
                 flag =true;
                 break;
             }
             temp = temp.next;//temp后移,遍历
         }
         //判断flag
         if(flag){
         //可以删除
             temp.next =temp.next.next;
         }else{
             System.out.printf("要删除的%d节点不存在\n" ,no);
         }
     }
     }

//定义一个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;
    }
    //为了显示方法,我们重写toString(toString方法是Java中的一个方法,它用于将一个对象转换成字符串表示形式。这个方法通常被用于调试或者打印对象的时候,
    // 它可以返回对象的内容或者状态信息。默认情况下,toString方法返回的是对象的类名和内存地址,但是我们可以根据需要重写这个方法来返回自定义的字符串。)
    /**
     * toString重写和不重写的区别
     * 1、当不重写toString方法时,当直接输入一个对象时,是调用Object.toString方法,默认的返回结果是:全类名+@+哈希值的十六进制
     * 2、当重写toString方法时,打印对象或者拼接对象时,都会调用该对象声名好的toString形式,返回返回结果和声明结果保持一致
     */

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                "}";
    }
}

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

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

相关文章

[论文笔记]UNILM

引言 今天带来论文Unified Language Model Pre-training for Natural Language Understanding and Generation的笔记,论文标题是 统一预训练语言模型用于自然语言理解和生成。 本篇工作提出了一个新的统一预训练语言模型(Unifield pre-trained Language Model,UniLM),可以同…

中间件漏洞靶场复现

一、简介 1.tomcat弱口令复现 通过弱口令复现的靶场复现,进一步熟悉了burpsuite的使用,冰蝎的使用以及爆破和木马生成waf上传的技术。 登陆到页面,先使用burpsuite对登陆进行拦截抓包,对参数进行修改破解爆破出密码。接着使用冰蝎…

【新书推荐】人工智能的当下,测试团队如何敏捷转型 —— 无测试组织

文章目录 〇、引子一、什么是“无测试组织”?二、无测试组织适用于哪些场景?三、无测试组织还有哪些优势或特点?新书推荐 —— 《**无测试组织:测试团队的敏捷转型** 》 〇、引子 初次看到“无测试组织”的朋友可能会觉得有标题党…

picoctf_2018_can_you_gets_me

picoctf_2018_can_you_gets_me Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)32位,只开了NX 拿到这么大的程序,直接ROPchain看看 #!/usr/bin/env python2# execve …

基于SpringBoot的校园点餐系统

基于SpringBoot的校园点餐系统的设计与实现,前后端分离 开发语言:Java数据库:MySQL技术:SpringBootMyBatisVue工具:IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色:用户、管理员 用户前台:…

直播协议 python 常见直播协议

1. 推流、直播 和 点播分别是什么意思? 推流 主播将本地视频源和音频源推送到云服务器,也被称为“RTMP发布”。 直播 即直接观看主播实时推送过来的音视频数据。 点播 视频源已经事先存储于云服务器之上的音视频文件,观众随时可以观看。 目…

手机投屏到笔记本电脑小方法

1、我们可以开启Windows自带的投影功能,将我们的手机和电脑连接同一个无线网络。 2、在电脑开始菜单栏里找到设置选项并打开。 3、我们进入之后找到系统选项,点击进去之后找到点击投影到这台电脑,接下来我们将默认的始终关闭的下拉选项更改为…

【ShaderLab罪恶装备卡通角色_二次元风格_“Sol Badguy“_角色渲染(第二篇)】

罪恶装备背德之炎卡通角色_二次元风格_Unity 角色渲染 角色初始效果:基础渲染SimpleBas 资源分析模型顶点颜色: 贴图资源SOL_base_基础色块效果:其中SOL_base_A通道的效果: SOL_ilm:如下SOL_ilm模型上区域分布- 左到右…

【Axure】元件库和母版、常见的原型规范、静态原型页面制作

添加现有元件库 点击元件库——载入 当然也可以创建元件库,自己画自己保存 建立京东秒杀母版 静态原型页面的制作 框架 选择以iphone8的界面大小为例,顶部状态栏高度为20 左侧类似于标尺,因为图标、文字离最左侧的间距是不一样的 信…

开绕组电机零序Bakc EMF-based无感控制以及正交锁相环inverse Park-based

前言 最近看论文遇到了基于反Park变换的锁相环,用于从开绕组永磁同步电机零序电压信号中提取转子速度与位置信息,实现无感控制。在此记录 基于零序Back EMF的转子估算 开绕组电机的零序反电动势 e 0 − 3 ω e ψ 0 s i n 3 θ e e_0-3\omega_e\psi_…

C++-哈希Hash

本期我们来学习哈希 目录 unordered系列关联式容器 unordered_map unordered_set 性能比较 哈希概念 哈希冲突 哈希函数 哈希冲突解决 闭散列 模拟实现 开散列 模拟实现 全部代码 unordered系列关联式容器 在 C98 中, STL 提供了底层为红黑树结构的一…

知识图谱小白入门(1):neo4j的安装与CQL的使用

文章目录 序一、安装neo4j1.1 下载neo4j1.2 安装JDK1.3 BUG:dbms failed to start 二、CQL语法2.1 CQL语法2.2 习题 习题答案 序 知识图谱,是一种实体间的信息与关系知识的网状结构,借用图论中点与边的概念进行组建,易于结构化和…

生信教程:ABBA-BABA分析之滑动窗口

简介 ABBA BABA 统计(也称为 D 统计)为偏离严格的分叉进化历史提供了简单而有力的检验。因此,它们经常用于使用基因组规模的 SNP 数据测试基因渗入。 虽然最初开发用于基因渗入的全基因组测试,但它们也可以应用于较小的窗口&#…

Qt地铁智慧换乘系统浅学(四 )实现添加线路,添加站点,添加边 并且存储到本地txt文件

玩的就是添加 添加前的构思界面设计tabWidget添加线路界面添加站点界面添加边界面 代码实现添加线路思路连接槽函数槽函数 添加站点思路连接槽函数初始化combox槽函数更新容器函数 添加边思路槽函数 和代码 注意 添加前的构思 假设 现要添加一个线路 : 9号线 如果…

[H5动画制作系列 ]帧代码运行顺序测试

刚开始接触Animate CC(过去叫:Flash),对于帧代码的执行顺序十分迷惑。所以,专门做一个简单代码顺序测试. 准备工作: 代码图层actions,第1帧和第10帧为关键帧。 背景图层bg,就一个字符串红色Test.界面如下: 代码测试步…

八个不可不知的SQL高级方法

结构化查询语言(SQL)是一种广泛使用的工具,用于管理和操作数据库。基本的SQL查询简单易学,但掌握高级SQL技术可以将您的数据分析和管理能力提升到新的高度。 高级SQL技术是指一系列功能和函数,使您能够对数据执行复杂…

Zero-Shot Learning by Harnessing Adversarial Samples 理论 代码解读

《Zero-Shot Learning by Harnessing Adversarial Samples》基于对抗样本的零样本学习 该论文要解决的问题: 减轻了传统图像增强技术中固有的语义失真问题。我们希望我们的实验研究将有助于理解单标签监督和语义属性监督在模型行为上的差异,并为开发更…

10.01

服务器 #include<myhead.h> //键盘输入事件 int keybord_events(fd_set readfds) {char buf[128] "";int sndfd -1; //从终端获取一个文件描述符&#xff0c;发送数据给该文件描述符对应的客户端bzero(buf, sizeof(buf));int res scanf("…

Junit的常用操作

注:本篇文章讲解的是junit5 目录 Juint是什么 Juint需要导入的依赖 Juint常用注解 Junit执行顺序 参数化 断言 测试套件 Juint是什么 Juint 是 Java 的一个单元测试框架. 也是回归测试框架. 使用 Junit 能让我们快速的完成单元测试。 注意&#xff1a;Junit 测试也是程序…

网络安全渗透测试工具之skipfish

网络安全渗透测试工具skipfish介绍 在数字化的时代,Web 应用程序安全成为了首要任务。想象一下,您是一位勇敢的安全冒险家,迎接着那些隐藏在 Web 应用程序中的未知风险。而在这个冒险之旅中,您需要一款强大的工具来帮助您发现漏洞,揭示弱点。而这个工具就是 Skipfish。 …