数据结构与算法—队列

news2024/9/24 7:18:38

队列

队列介绍

有序列表,可以用数组或者链表实现。遵循先进先出原则。

数组实现队列

public class ArrayQueue {

    public static void main(String[] args) {
        ArrayQueue queue = new ArrayQueue(3);
        // 接收用户输入
        char key =' ';
        Scanner sc = new Scanner(System.in);
        boolean loop = true;
        while (loop) {
            System.out.println("s(show): 显示队列");
            System.out.println("e(exit): 退出程序");
            System.out.println("a(add): 添加数据进队列");
            System.out.println("g(get): 从队列取出数据");
            System.out.println("h(head): 队列头数据");
            // 返回输入的第一个字符
            key = sc.next().charAt(0);
            switch (key) {
                case 's':
                    queue.showQueue();
                    break;

                case 'a':
                    System.out.println("输出一个数:");
                    queue.addQueue(sc.nextInt());
                    break;

                case 'g':
                    try {
                        int res = queue.getQueue();
                        System.out.printf("取出的数据是:%d\n", res);
                    } catch (Exception e) {
                        System.out.printf(e.getMessage());
                    }
                    break;

                case 'h':
                    try {
                        int res = queue.head();
                        System.out.printf("头数据是:%d\n", res);
                    } catch (Exception e) {
                        System.out.printf(e.getMessage());
                    }
                    break;
                case 'e':
                    sc.close();
                    loop = false;
                    break;

                default:
                    break;
            }

            System.out.println("程序退出~~");
        }
    }

    // 数组的最大容量
    private int maxSize;
    // 队头
    private int front;
    // 队尾
    private int rear;
    // 存放数据的数组
    private int[] arr;

    // 初始化队列
    public ArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        this.arr = new int[this.maxSize];
        // 让front 指向队列头的前一个位置(队列头数据的前一个位置)
        this.front = -1;
        // 让rear 指向队尾的数据(队列的最后一个数据)
        this.rear = -1;
    }

    // 判断队列是否满
    public boolean isFull() {
        return rear == maxSize - 1;
    }

    // 判断队列是否为空
    public boolean isEmpty() {
        return rear == front;
    }

    public void addQueue(int data) {
        if (isFull()) {
            System.out.println("队列满,不能加数据~");
            return;
        }
        rear++;
        arr[rear] = data;
    }

    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,无法取出数据~");
        }
        front++;
        return arr[front];
    }

    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列空,没有数据~");
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.printf("arr[%d]=%d\n", i, arr[i]);
        }
    }

    public int head() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,没有头数据~");
        }

        return arr[front + 1];

    }
}

通过该方法测试
在这里插入图片描述在这里插入图片描述
添加了:10,20,30
show:arr[0]=10,arr[1]=20,arr[2]=30
在这里插入图片描述
取出10后,头数据是20。这时候show一下,可以看到队列为:arr[0]=10,arr[1]=20,arr[2]=30
在这里插入图片描述
也就是我们通过g获取到了数据,看到队列数据还是一样。

为了可以重新使用已经出队的数据所占用的空间,考虑使用环形队列。

数组环形队列

在这里插入图片描述

public class CircleArrayQueue {

    public static void main(String[] args) {
        CircleArrayQueue queue = new CircleArrayQueue(3);
        // 接收用户输入
        char key =' ';
        Scanner sc = new Scanner(System.in);
        boolean loop = true;
        while (loop) {
            System.out.println("s(show): 显示队列");
            System.out.println("e(exit): 退出程序");
            System.out.println("a(add): 添加数据进队列");
            System.out.println("g(get): 从队列取出数据");
            System.out.println("h(head): 队列头数据");
            // 返回输入的第一个字符
            key = sc.next().charAt(0);
            switch (key) {
                case 's':
                    queue.showQueue();
                    break;

                case 'a':
                    System.out.println("输出一个数:");
                    queue.addQueue(sc.nextInt());
                    break;

                case 'g':
                    try {
                        int res = queue.getQueue();
                        System.out.printf("取出的数据是:%d\n", res);
                    } catch (Exception e) {
                        System.out.printf(e.getMessage());
                    }
                    break;

                case 'h':
                    try {
                        int res = queue.head();
                        System.out.printf("头数据是:%d\n", res);
                    } catch (Exception e) {
                        System.out.printf(e.getMessage());
                    }
                    break;
                case 'e':
                    sc.close();
                    loop = false;
                    break;

                default:
                    break;
            }

            System.out.println("程序退出~~");
        }
    }

    // 数组的最大容量
    private int maxSize;
    // 让front 指向队列的第一个元素
    // front = 0;
    // 让rear 指向队列的最后一个元素的后一个位置,因为希望空出一个空间作为约定
    // rear = 0;
    private int front;
    private int rear;
    // 存放数据的数组
    private int[] arr;

    // 初始化队列
    public CircleArrayQueue(int maxSize) {
        this.maxSize = maxSize;
        this.arr = new int[maxSize];
    }

    // 判断队列是否满
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    // 判断队列是否为空
    public boolean isEmpty() {
        return rear == front;
    }

    // 添加数据
    public void addQueue(int data) {
        if (isFull()) {
            System.out.println("队列满,不能加数据~");
            return;
        }
        arr[rear] = data;
        // rear 后移,因为是环形,考虑取模
        rear = (rear + 1) % maxSize;
    }

    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,无法取出数据~");
        }
        // 因为front 是队列第一个元素,也会后移,考虑取模,以免越界
        // 1.先保存front 指向的值到value
        int value = arr[front];
        // 2.front 后移,并返回value
        front = (front + 1) % maxSize;
        return value;
    }

    public void showQueue() {
        if (isEmpty()) {
            System.out.println("队列空,没有数据~");
            return;
        }
        // 因为是环形队列,需要考虑从front 开始遍历,遍历队列的有效数据个数
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
        }
    }

    // 当前队列的有效数据个数
    public int size() {
        return (rear + maxSize - front) % maxSize;
    }

    public int head() {
        if (isEmpty()) {
            throw new RuntimeException("队列空,没有头数据~");
        }

        return arr[front];

    }
}

测试:
添加数据10,20,30,show一下,添加40提示队列满
在这里插入图片描述
在这里插入图片描述
取出arr[0] 后,show一下,可以看到队列还剩两个数据
在这里插入图片描述
这时,又可以在arr[0] 的位置插入新数据。
在这里插入图片描述
在这里插入图片描述
这样,就可以利用好了数组空间。

最近学习的数据结构与算法主要都是根据尚硅谷的学习:
https://www.bilibili.com/video/BV1E4411H73v/?p=18&vd_source=8e23c01ff3b88e176530ca2e0f4f18fe

可以看看我的个人博客:
网站:https://www.fuzm.wang / https://liwangc.gitee.io
—————————————————————————

作为初学者,很多知识都没有掌握,见谅,如有错误请指出,以期进步,感谢!。后续有新的学习,继续补充上来。

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

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

相关文章

PyQt5 自定义富文本编辑器

介绍 一款使用PyQt5和网页端框架wangEditor集成的富文本编辑器 代码片段 PyQt5客户端 与网页端建立连接def create_connect(self):self.web_view QWebEngineView()self.bridge JSBridge(self.web_view.page())self.web_view.load(QUrl.fromLocalFile(self.editor_path))w…

现代卷积神经网络经典架构图

卷积神经网络&#xff08;LeNet&#xff09; LeNet 的简化版深层卷积神经网络&#xff08;AlexNet&#xff09; 从LeNet&#xff08;左&#xff09;到AlexNet&#xff08;右&#xff09;改进&#xff1a; dropOut层 - 不改变期望但是改变方差ReLU层 - 减缓梯度消失MaxPooling数…

2.18 设置language和中文输入法

文章目录一&#xff1a;设置language二&#xff1a;设置中文输入法一&#xff1a;设置language nvidia的开发板上默认只有English&#xff0c;需要点击如下管理&#xff1a; 接着进入如下界面&#xff1a; 此时图中的“汉语&#xff08;中国&#xff09;”应该是没有的&…

Kubernetes是个什么东东?

Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态&#xff0c;其服务、支持和工具的使用范围相当广泛。 Kubernetes 这个名字源于希腊语&#xff0c;意…

NoMachine 输入用户名密码后 闪断 解决办法

大家好&#xff0c;我是虎哥&#xff0c;最近工作忙&#xff0c;好长时间没有继续套件的深度学习&#xff0c;今天周六&#xff0c;难得有空&#xff0c;泡好茶&#xff0c;打开电脑&#xff0c;链接套件桌面&#xff0c;得&#xff0c;出问题了&#xff0c;一个很奇怪的问题&a…

[教你传话,表白,写信]

第一步 关注飞鸽传话助手 第二部 点击链接进入 第三步 点击发送,输入内容 第四步 就可以收到了

Simulink 自动代码生成电机控制:STM32 Encoder编码器使用总结

目录 Encoder 原理 STM32 Encoder 计数原理 模型仿真 模拟Encoder 基于Encoder计算角度和速度 关于启动的仿真 代码生成 运行演示 总结 总结一下基于STM32的Encoder接口的电机运行&#xff0c;相应的仿真和实验都是基于一个1024脉冲的增量式光电编码器&#xff0c;关于…

23年校招DL/NLP/推荐系统/ML/算法基础面试必看300问及答案

2020年校招已经开始了&#xff0c;在疫情全球肆虐的背景下&#xff0c;全球就业情况异常艰难&#xff0c;加上美国对中国企业打压持续升级&#xff0c;对于马上开始秋招找工作的毕业生而言&#xff0c;更是难上加难。我们不能凭一己之力改变现状&#xff0c;但我们可以凭借自己…

第七讲---贪心(上课)

1.股票买卖 一、贪心 考虑一种方案&#xff0c;在每次上升的前一天购入股票&#xff0c;并在上升后的当天卖出的方案 if (w[i] > w[i - 1])res w[i] - w[i - 1];接下来证明该贪心思路得出的方案即是最优解。 &#xff08;1&#xff09;证明贪心解 ≥ 最优解&#xff1a; …

剑指 Offer 39. 数组中出现次数超过一半的数字

摘要 剑指 Offer 39. 数组中出现次数超过一半的数字 一、摩尔投票法 核心理念票数正负抵消 。此方法时间和空间复杂度分别为 O(N)和 O(1) &#xff0c;为本题的最佳解法。 摩尔投票法&#xff1a;设输入数组 nums 的众数为 x &#xff0c;数组长度为 n 。 若记 众数 的票数…

面试知识点准备与总结——(并发篇)

目录线程有哪些状态线程池的核心参数sleep和wait的区别lock 与 synchronized 的异同volatile能否保证线程安全悲观锁和乐观锁的区别Hashtable 与 ConcurrentHashMap 的区别ConcurrentHashMap1.7和1.8的区别ThreadLocal的理解ThreadLocalMap中的key为何要设置为弱引用线程有哪些…

【Java】线程的死锁和释放锁

线程死锁是线程同步的时候可能出现的一种问题 文章目录1. 线程的死锁1.1 基本介绍1.2 应用案例2. 释放锁2.1 下面的操作会释放锁2.2 下面的操作不会释放锁1. 线程的死锁 1.1 基本介绍 多个线程都占用了对方的锁资源&#xff0c;但不肯相让&#xff0c;导致了死锁&#xff0c;…

第46章 自定义静态与数据库动态授权依赖注入的定义实现

1 数据库动态授权表授权原理 2 准备工作 2.1 重构Program.cs using Framework.Infrastructure.Extensions; var builder WebApplication.CreateBuilder(args); //如果启动项中不存在“appsettings.json”文件&#xff0c;则通过.Net(Core)的内置方法自动新建“appsettings.…

作为初学者必须要了解的几种常用数据库!

现在已经存在了很多优秀的商业数据库&#xff0c;如甲骨文&#xff08;Oracle&#xff09;公司的 Oracle 数据库、IBM 公司的 DB2 数据库、微软公司的 SQL Server 数据库和 Access 数据库。同时&#xff0c;还有很多优秀的开源数据库&#xff0c;如 MySQL 数据库&#xff0c;Po…

Django框架之模型视图-使用 PostMan 对请求进行测试

使用 PostMan 对请求进行测试 PostMan 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件&#xff0c;可以直接去对我们写出来的路由和视图函数进行调试&#xff0c;作为后端程序员是必须要知道的一个工具。 安装方式1&#xff1a;去 Chrome 商店直接搜索 PostMan…

链表OJ(四)链表排序合集

目录 合并两个排序的链表 合并k个已排序的链表 单链表的排序 链表的奇偶重排 链表的奇偶重排扩展 合并两个排序的链表 描述 输入两个递增的链表&#xff0c;单个链表的长度为n&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 数据范围&#xff1a; 0≤n≤…

Spark12: SparkSQL入门

一、SparkSQL Spark SQL和我们之前讲Hive的时候说的hive on spark是不一样的。hive on spark是表示把底层的mapreduce引擎替换为spark引擎。而Spark SQL是Spark自己实现的一套SQL处理引擎。Spark SQL是Spark中的一个模块&#xff0c;主要用于进行结构化数据的处理。它提供的最核…

Kubernetes入门级教程

Kubernetes入门级教程1. Introduction1.1 概述1.2 关键字介绍2. Cluster Install2.1 Big Data -- Postgres3. 基础知识3.1 Pod3.2 控制器3.3 通讯模式3.4 服务发现4. Command4.0 编辑文件4.1 在宿主机执行命令4.2 创建资源对象4.3 查询资源对象4.4 查询资源描述4.5 修改资源4.6…

Linux 交换分区与链接文件

目录 SWAP交换分区扩展 fdisk 创建分区 mkswap 将逻辑分区/主分区格式化为交换分区&#xff08;make swap&#xff09; swapon 交换分区挂载 swapoff 卸载交换分区 vim /etc/fstab 永久挂载 将文件设置为交换分区 链接文件 软链接 硬链接 SWAP交换分区扩展 交换分区…

量子力学奇妙之旅-双态系统(后)

专栏: 高质量文章导航-持续更新中 引子: 感慨:对于还原论,物质深层结构的物理定律如此的复杂,求解一个简单的双态系统已经如此困难,运用了大量的近视方法,在宇宙真理面前,我们只是虫子啊,我们固有的概念里面对逻辑自洽性,对事物发展的可预测性必然性,真实世界的有…