【尚硅谷】Java数据结构与算法笔记02 - 队列

简介: 【尚硅谷】Java数据结构与算法笔记02 - 队列

@[toc]


一、使用场景

  • 银行排队,先到先得
  • 测核酸,先到先测

在这里插入图片描述

二、队列介绍

1) 队列是一个有序列表, 可以用数组或是链表来实现。
2) 遵循先入先出的原则。即: 先存入队列的数据, 要先取出。后存入的要后取出
3) 示意图: (使用数组模拟队列示意图)
在这里插入图片描述

三、数组模拟队列

3.1 思路分析

  • 队列本身是有序列表, 若使用数组的结构来存储队列的数据, 则队列数组的声明如下图, 其中 maxSize 是该队 列的最大容量。
  • 因为队列的输出、输入是分别从前后端来处理, 因此需要两个变量 front 及 rear 分别记录队列前后端的下标, front 会随着数据输出而改变, 而 rear则是随着数据输入而改变, 如图所示:

在这里插入图片描述

当我们将数据存入队列时称为” addQueue”, addQueue 的处理需要有两个步骤: 思路分析
1)将尾指针往后移: rear $+1$, 当 front $==$ rear 【空】
2)若尾指针 rear 小于队列的最大下标 maxSize-1, 则将数据存入 rear 所指的数组元素中, 否则无法存入数据。 rear $==\max$ Size $-1$ [队列满]

3.2 Java代码实现

public class ArrayQueue {
    public static void main(String[] args) {
        // 1. 声明数组模拟的队列,设置maxSize为4
        ArrayQueue arrayQueue = new ArrayQueue(4);
        // 2. 开始测试
        arrayQueue.add(1);
        arrayQueue.add(3);
        arrayQueue.add(4);
        arrayQueue.add(2);
        arrayQueue.add(5);
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
        System.out.println(arrayQueue.poll());
    }

    // 数组长度(队列的最大容量)
    int maxSize;
    // 当前队列长度
    int curSize;
    // 数组
    int[] arr;
    // 当前指向的元素
    int curIndex;

    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        arr = new int[maxSize];
        curIndex = 0;
        curSize = 0;
    }

    // 添加元素到队列
    public void add(int num) {
        if (curSize >= maxSize) {
            System.err.println("队列容量不足,无法添加元素");
        }else{
            arr[curSize++] = num;
        }
    }

    // 从队列取出头元素
    public int poll() {
        if (curIndex >= curSize) {
            throw new RuntimeException("当前队列为空,无法取出元素");
        }else if (curIndex >= maxSize) {
            throw new RuntimeException("超出队列长度");
        }else{
            return arr[curIndex++];
        }
    }

}

输出:

队列容量不足,无法添加元素
1
3
4
2
Exception in thread "main" java.lang.RuntimeException: 当前队列为空,无法取出元素
    at com.wskh.DataStructures.Queue.ArrayQueue.poll(ArrayQueue.java:57)
    at com.wskh.DataStructures.Queue.ArrayQueue.main(ArrayQueue.java:26)

3.3 问题分析与优化

1) 目前数组使用一次就不能用, 没有达到复用的效果
2) 将这个数组使用算法, 改进成一个环形的队列 取模:%

四、数组模拟环形队列

4.1 思路分析

对前面的数组模拟队列的优化, 充分利用数组. 因此将数组看做是一个环形的。(通过取模的方式来实现即可)
分析说明:
1) 尾索引的下一个为头索引时表示队列满, 即将队列容量空出一个作为约定, 这个在做判断队列满的 时候需要注意 $($ rear $+1) \%$ maxSize $=$ front 满]
2) rear $==$ front $[$ 空 $]$
3) 分析示意图:

在这里插入图片描述

4.2 Java代码实现

public class CircleArrayQueue {
    public static void main(String[] args) {
        // 1. 声明数组模拟的队列,设置maxSize为4
        CircleArrayQueue circleArrayQueue = new CircleArrayQueue(4);
        // 2. 开始测试
        circleArrayQueue.add(1);
        circleArrayQueue.add(3);
        circleArrayQueue.add(4);
        System.out.println(circleArrayQueue.poll());
        System.out.println(circleArrayQueue.poll());
        circleArrayQueue.add(2);
        circleArrayQueue.add(5);
        System.out.println(circleArrayQueue.poll());
        System.out.println(circleArrayQueue.poll());
        System.out.println(circleArrayQueue.poll());
    }

    // 数组长度(队列的最大容量)
    int maxSize;
    // 当前队列长度
    int curSize;
    // 当前追加的指针
    int addIndex;
    // 数组
    Integer[] arr;
    // 当前指向的元素
    int curIndex;

    public CircleArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        arr = new Integer[maxSize];
        curIndex = 0;
        curSize = 0;
        addIndex = 0;
    }

    // 添加元素到队列
    public void add(int num) {
        if (curSize >= maxSize) {
            System.err.println("队列容量不足,无法添加元素");
        } else {
            arr[(addIndex++) % maxSize] = num;
        }
    }

    // 从队列取出头元素
    public int poll() {
        if (arr[curIndex % maxSize] == null) {
            throw new RuntimeException("当前队列为空,无法取出元素");
        } else {
            curSize--;
            Integer integer = arr[curIndex % maxSize];
            arr[curIndex % maxSize] = null;
            curIndex++;
            return integer;
        }
    }

}

输出:

1
3
4
2
5
目录
相关文章
|
30天前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
255 35
|
1月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
1月前
|
存储 算法 搜索推荐
《数据之美》:Java数据结构与算法精要
本系列深入探讨数据结构与算法的核心原理及Java实现,涵盖线性与非线性结构、常用算法分类、复杂度分析及集合框架应用,助你提升程序效率,掌握编程底层逻辑。
|
3月前
|
运维 监控 算法
基于 Java 滑动窗口算法的局域网内部监控软件流量异常检测技术研究
本文探讨了滑动窗口算法在局域网流量监控中的应用,分析其在实时性、资源控制和多维分析等方面的优势,并提出优化策略,结合Java编程实现高效流量异常检测。
141 0
|
4月前
|
机器学习/深度学习 算法 Java
Java实现林火蔓延路径算法
记录正在进行的森林防火项目中林火蔓延功能,本篇文章可以较好的实现森林防火蔓延,但还存在很多不足,如:很多参数只能使用默认值,所以蔓延范围仅供参考。(如果底层设备获取的数据充足,那当我没说)。注:因林火蔓延涉及因素太多,如静可燃物载量、矿质阻尼系数等存在估值,所以得出的结果仅供参考。
71 4
|
4月前
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
173 0
|
4月前
|
存储 负载均衡 算法
我们来说一说 Java 的一致性 Hash 算法
我是小假 期待与你的下一次相遇 ~
163 1
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
135 2
|
1月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
157 1
|
2月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案

热门文章

最新文章