Java单链表的应用实例

简介: Java单链表的应用实例

链表是有序的列表,它在内存中的实际结构如下


20210703154418457.png

小结:

  1. 链表是以节点的方式来存储,是链式存储。
  2. 每个节点包含 data 域,next 域指向下一个节点。
  3. 如图:发现链表的各个节点不一定是连续存放.
  1. 链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定。
  • 单链表(带头节点)逻辑结构示意图如下

20210703155930776.png

单链表的应用实例

  • 使用带head头的单项链表实现,水浒英雄排行榜管理

image.png

需求:

  1. 完成对英雄人物的增删改查操作
  2. 第一种方法在添加英雄时,直接添加到链表的尾部(不考虑排序)
  3. 第二种方式在添加英雄时,根据排名将英雄插入到指定位置(如果有这个排名,则添加失败,并给出提示)

直接添加到链表的尾部(不考虑排序)

思路分析:

20210704142544856.png

添加:

  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;
    }
    //为了显示方便,我们重写toString方法
    @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节点不能动,因此我们需要一个辅助变量 temp
        HeroNode temp = head;
        //遍历链表找到最后
        while (true){
            //找到链表的最后
            if (temp.next == null){
                break;
            }
            //如果没有找到最后,将temp后移
            temp = temp.next;
        }
        //当退出while循环时,temp就指向了链表的最后,将最后这个节点的next 指向新的节点
        temp.next = heroNode;
    }
    /**
     * 显示链表[遍历]
     */
    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;
        }
    }
}

初始化并测试

    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, "鲁智深", "花和尚");
        HeroNode hero5 = new HeroNode(5, "杨志", "青面兽");
        HeroNode hero6 = new HeroNode(6, "林冲", "豹子头");
        //创建链表
        SingleLinkedList singleLinkedList =new SingleLinkedList();
        singleLinkedList.add(hero1);
        singleLinkedList.add(hero2);
        singleLinkedList.add(hero3);
        singleLinkedList.add(hero4);
        singleLinkedList.add(hero5);
        singleLinkedList.add(hero6);
        //显示
        singleLinkedList.list();
    }

20210704143648679.png

根据排名将英雄插入到指定位置

(按照编号的顺序添加)思路分析:


202107042005391.png

  1. 首先找到新添加的节点的位置,是通过辅助变量(指针),通过遍历来搞定
  2. 新的节点.next = temp.next
  3. 将 temp.next = 新的节点

代码实现:

在 SingleLinkedList 类中重新定义一个增加方法

    public void addByOrder(HeroNode heroNode){
        //因为头节点不能动,因此我们仍然通过一个辅助指针(变量)来帮助找到添加的位置,因为是单链表,因此我们找的temp是位于 添加位置的前一个节点,否则插入不了。
        HeroNode temp = head;
        boolean flag = false; //flag表示添加的编号是否存在,默认为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;
        }
    }

初始化并测试 注意:这里不按照顺序插入,我们看结果是否会自动排序

    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, "鲁智深", "花和尚");
        HeroNode hero5 = new HeroNode(5, "杨志", "青面兽");
        HeroNode hero6 = new HeroNode(6, "林冲", "豹子头");
        //创建链表
        SingleLinkedList singleLinkedList =new SingleLinkedList();
        singleLinkedList.addByOrder(hero3);
        singleLinkedList.addByOrder(hero1);
        singleLinkedList.addByOrder(hero2);
        singleLinkedList.addByOrder(hero4);
        singleLinkedList.addByOrder(hero5);
        singleLinkedList.addByOrder(hero6);
        //显示
        singleLinkedList.list();
    }

20210704201343349.png

测试 2 加入重复的节点

    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, "鲁智深", "花和尚");
        HeroNode hero5 = new HeroNode(5, "杨志", "青面兽");
        HeroNode hero6 = new HeroNode(6, "林冲", "豹子头");
        //创建链表
        SingleLinkedList singleLinkedList =new SingleLinkedList();
        singleLinkedList.addByOrder(hero3);
        singleLinkedList.addByOrder(hero1);
        singleLinkedList.addByOrder(hero2);
        singleLinkedList.addByOrder(hero4);
        singleLinkedList.addByOrder(hero5);
        singleLinkedList.addByOrder(hero6);
        //重复节点
        singleLinkedList.addByOrder(hero1);
        //显示
        singleLinkedList.list();
    }

20210704201504558.png


相关文章
|
11月前
|
人工智能 算法 Java
Java与AI驱动区块链:构建智能合约与去中心化AI应用
区块链技术和人工智能的融合正在开创去中心化智能应用的新纪元。本文深入探讨如何使用Java构建AI驱动的区块链应用,涵盖智能合约开发、去中心化AI模型训练与推理、数据隐私保护以及通证经济激励等核心主题。我们将完整展示从区块链基础集成、智能合约编写、AI模型上链到去中心化应用(DApp)开发的全流程,为构建下一代可信、透明的智能去中心化系统提供完整技术方案。
617 3
|
存储 数据采集 搜索推荐
Java 大视界 -- Java 大数据在智慧文旅旅游景区游客情感分析与服务改进中的应用实践(226)
本篇文章探讨了 Java 大数据在智慧文旅景区中的创新应用,重点分析了如何通过数据采集、情感分析与可视化等技术,挖掘游客情感需求,进而优化景区服务。文章结合实际案例,展示了 Java 在数据处理与智能推荐等方面的强大能力,为文旅行业的智慧化升级提供了可行路径。
Java 大视界 -- Java 大数据在智慧文旅旅游景区游客情感分析与服务改进中的应用实践(226)
|
机器学习/深度学习 数据采集 数据可视化
Java 大视界 -- 基于 Java 的大数据可视化在城市空气质量监测与污染溯源中的应用(216)
本文探讨Java大数据可视化在城市空气质量监测与污染溯源中的创新应用,结合多源数据采集、实时分析与GIS技术,助力环保决策,提升城市空气质量管理水平。
Java 大视界 -- 基于 Java 的大数据可视化在城市空气质量监测与污染溯源中的应用(216)
|
存储 监控 数据可视化
Java 大视界 -- 基于 Java 的大数据可视化在企业生产运营监控与决策支持中的应用(228)
本文探讨了基于 Java 的大数据可视化技术在企业生产运营监控与决策支持中的关键应用。面对数据爆炸、信息孤岛和实时性不足等挑战,Java 通过高效数据采集、清洗与可视化引擎,助力企业构建实时监控与智能决策系统,显著提升运营效率与竞争力。
|
Java 大数据 数据处理
Java 大视界 -- 基于 Java 的大数据实时数据处理在工业互联网设备协同制造中的应用与挑战(222)
本文探讨了基于 Java 的大数据实时数据处理在工业互联网设备协同制造中的应用与挑战。文章分析了传统制造模式的局限性,介绍了工业互联网带来的机遇,并结合实际案例展示了 Java 在多源数据采集、实时处理及设备协同优化中的关键技术应用。同时,也深入讨论了数据安全、技术架构等挑战及应对策略。
|
数据采集 搜索推荐 Java
Java 大视界 -- Java 大数据在智能教育虚拟学习环境构建与用户体验优化中的应用(221)
本文探讨 Java 大数据在智能教育虚拟学习环境中的应用,涵盖多源数据采集、个性化推荐、实时互动优化等核心技术,结合实际案例分析其在提升学习体验与教学质量中的成效,并展望未来发展方向与技术挑战。
|
11月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
902 8
|
12月前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
1658 12
|
12月前
|
安全 Java API
Java SE 与 Java EE 区别解析及应用场景对比
在Java编程世界中,Java SE(Java Standard Edition)和Java EE(Java Enterprise Edition)是两个重要的平台版本,它们各自有着独特的定位和应用场景。理解它们之间的差异,对于开发者选择合适的技术栈进行项目开发至关重要。
1663 1
|
设计模式 XML 安全
Java枚举(Enum)与设计模式应用
Java枚举不仅是类型安全的常量,还具备面向对象能力,可添加属性与方法,实现接口。通过枚举能优雅实现单例、策略、状态等设计模式,具备线程安全、序列化安全等特性,是编写高效、安全代码的利器。