【数据结构】受限制的线性表——队列

news2025/4/15 16:21:15

在这里插入图片描述
🧧🧧🧧🧧🧧个人主页🎈🎈🎈🎈🎈
🧧🧧🧧🧧🧧数据结构专栏🎈🎈🎈🎈🎈
🧧🧧🧧🧧🧧上一篇文章:特殊的线性表——栈🎈🎈🎈🎈🎈

文章目录

  • 前言
    • 1.队列(Queue)
    • 1.1队列的概念
    • 2.2 队列的使用
    • 2.3 队列模拟实现
    • 2.4 循环队列
      • 3. 双端队列 (Deque)

前言

上一章我们讲了一种特殊的线性表只能在表尾进行插入和删除操作,接下来我们讲一个和栈很相似的数据结构,它也是一种特殊且所限制的线性表,它是只能在表头删除操作在表尾进行插入操作。

1.队列(Queue)

1.1队列的概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头

2.2 队列的使用

在Java中,Queue是个接口,底层是通过链表实现的。
在这里插入图片描述
在这里插入图片描述
注意:Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。

2.3 队列模拟实现

我们这里通过链表来实现队列:
1.我们先将链表的框架搭建一下,代码如下:

public class MyQueue {
    static class ListNode {
        public int val;
        public ListNode prev;
        public ListNode next;
        public ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode head;
    public ListNode last;
}

2.方法的实现:

2.1入队(offer)

//offer 入队
    public void offer(int val) {
        ListNode node = new ListNode(val);
        //1.空节点
        if(head == null) {
            head = node;
            last = node;
        } else {
            //2.不为空节点,尾插法。
            last.next = node;
            node.prev = last;
            last = node;
        }
    }

2.2 出队(poll)

   //poll 出队
    public int poll() {
        //1.判断队是否为空
        if(isEmpty()) {
            //1.1队为空,抛出队为空的异常
           throw new QueueEmptyException("队空异常!!!!");
        } else {
            //2.队中是否只有一个元素
            int val = head.val;
            if(head.next == null) {
                //2.1只有一个元素
                head = null;
                last = null;
                return val;
            } else {
                //2.2队中不只一个元素,删头节点
                head = head.next;
                head.prev = null;
                return val;
            }
        }
    }
    public boolean isEmpty() {
        return head == null;
    }

2.3 peek

//peek
    public int peek() {
        //1.判断队是否为空
        if(isEmpty()) {
            //1.1队为空,抛出队为空的异常
            throw new QueueEmptyException("队空异常!!!!");
        } else {
            //1.2队不空,直接返回队头元素
             return head.val;
        }
    }

2.4 判断队列空

public boolean isEmpty() {
        return head == null;
    }

3.我这写一个队满报异常的代码

public class QueueEmptyException extends RuntimeException{
    public QueueEmptyException() {
    }

    public QueueEmptyException(String message) {
        super(message);
    }
}

2.4 循环队列

在实现队列可以通过链表来实现,还可以通过顺序表来实现,但在用顺序表来实现的时候,我们会发现,当队中在一边出队一边入队,会出现空间浪费的情况。
在这里插入图片描述
那我们怎么解决这个问题? 我们就提出将一个数组围成一个圆圈的样子,那么这么就不会把空间给浪费,像这样似的:
在这里插入图片描述
这时候会出现一个问题那就是怎么去区分这个队中是满还是空,在解决这个问题之前我先分享一个很有趣的方法:关于数组下标在循环的一个小tip 下一个下标等于(此时的下标+1)%数组的长度
用公式表示:index =(rear+1)%elem.length
在这里插入图片描述

我们就这个问题有三种方式去解决分别为:
1.size计数法
我们定义一个变量usedSize来记录队中的元素个数,当usedSize等于0,说明队中为空,当usedSize等于数组的长度,那么队满。
在入队的时候每入队一个元素usedSize就加1,在出队的时候usedSize就减1.
代码实现:

public class CircularQueueSize {
    public int[] elem;
    public int front;
    public int rear;
    public int usedSize;
    public CircularQueueSize() {
       elem = new int[8];
    }
    //入队
    public void offer(int val) {
        if(isFull()) {
            throw new CircularQueueSizeFullException("队满异常!!!");
        } else {
            elem[rear] = val;
            rear = (rear+1) % elem.length;
            usedSize++;
        }
    }
    //出队
    public int poll() {
        //1.判断队空不空
        if(isEmpty()) {
            //1.1队空
            throw new CircularQueueSizeEmptyException("循环队列空异常!!!");
        } else {
            //1.2队不空
            int val = elem[front];
            front = (front+1) % elem.length;
            usedSize--;
            return val;
        }
    }
    //判断队中是否空
    public boolean isEmpty() {
        return usedSize == 0;
    }
    //判断循环队列已满
    public boolean isFull() {
        return usedSize == elem.length;
    }
    //Front 获取队头元素
    public int  Front () {
        if(isEmpty()) {
            return -1;
        }
        return elem[front];
    }
    //Rear 获取队尾元素
    public int Rear() {
        if(isEmpty()) {
            return -1;
        }
        int ret = (rear == 0) ? elem.length : rear-1;
        return elem[ret];
    }
}

2.flg标志法
我们定义一个boolean类型的flg标志位,一开始为false,每入队一个元素flg就置为true,每出队一个元素flg置为false。
判断队满队空的条件
队满:队头等于队尾并且flg等于ture
队空:队头等于队尾并且flg等于false
代码实现:

public class CircularQueueFlg {
    public int[] elem;
    public int front;
    public int rear;
    public boolean flg;
    public int usedSize;
    public CircularQueueFlg() {
        elem = new int[8];
    }
    //入队
    public void offer(int val) {
        if(isFull()) {
            throw new CircularQueueSizeFullException("队满异常!!!");
        }
            elem[rear] = val;
             flg = true;
            rear = (rear+1) % elem.length;
    }
    //出队
    public int poll() {
        //1.判断队空不空
        if(isEmpty()) {
            //1.1队空
            throw new CircularQueueSizeEmptyException("循环队列空异常!!!");
        } else {
            //1.2队不空
            int val = elem[front];
            flg = false;
            front = (front+1) % elem.length;
            return val;
        }
    }
    //判断队中是否空
    public boolean isEmpty() {
        return (front == rear) && (flg == false);
    }
    //判断循环队列已满
    public boolean isFull() {
       return (front == rear) && (flg == true);
    }
    //Front 获取队头元素
    public int  Front () {
        if(isEmpty()) {
            return -1;
        }
        return elem[front];
    }
    //Rear 获取队尾元素
    public int Rear() {
        if(isEmpty()) {
            return -1;
        }
        int ret = (rear == 0) ? elem.length : rear-1;
        return elem[ret];
    }
}

3.空间牺牲法
我们牺牲一个空间来实现循环队列判断队满和队空
队满:index = 队头 index (队尾此刻的下标+1)%数组的长度
队空:队尾等于队头
代码实现:

public class CircularQueueSpace {
    public int[] elem;
    public int front;
    public int rear;
    public  CircularQueueSpace() {
        elem = new int[8];
    }
    //入队
    public void offer(int val) {
        if(isFull()) {
            throw new CircularQueueSizeFullException("队满异常!!!");
        } else {
            elem[rear] = val;
            rear = (rear+1) % elem.length;
        }
    }
    //出队
    public int poll() {
        //1.判断队空不空
        if(isEmpty()) {
            //1.1队空
            throw new CircularQueueSizeEmptyException("循环队列空异常!!!");
        } else {
            //1.2队不空
            int val = elem[front];
            front = (front+1) % elem.length;
            return val;
        }
    }
    //判断队中是否空
    public boolean isEmpty() {
        return front == rear;
    }
    //判断循环队列已满
    public boolean isFull() {
        return front == (rear+1) % elem.length;
    }
    //Front 获取队头元素
    public int  Front () {
        if(isEmpty()) {
            return -1;
        }
        return elem[front];
    }
    //Rear 获取队尾元素
    public int Rear() {
        if(isEmpty()) {
            return -1;
        }
        int ret = (rear == 0) ? elem.length-1 : rear-1;
        return elem[ret];
    }
}

3. 双端队列 (Deque)

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。
在这里插入图片描述
eque是一个接口,使用时必须创建LinkedList的对象。
在实际工程中,使用Deque接口是比较多的,栈和队列均可以使用该接口。

Deque<Integer> stack = new ArrayDeque<>();//双端队列的线性实现
Deque<Integer> queue = new LinkedList<>();//双端队列的链式实现

希望大家可以给我点点关注,点点赞,并且在评论区发表你们的想法和意见,我会认真看每一条评论,你们的支持就是我的最大鼓励。🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹

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

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

相关文章

最新版CleanMyMac X4.15.2有哪些亮眼的更新?

CleanMyMac X是一款专为macOS系统设计的清理和优化工具&#xff0c;它集成了多种功能来帮助用户保持Mac系统的整洁、高效和安全。 首先&#xff0c;CleanMyMac X具备智能扫描和清理功能&#xff0c;能够自动识别并清理Mac上的各种垃圾文件&#xff0c;包括重复文件、无用的语言…

《AI绘画与修图实战:Photoshop+Firefly从入门到精通》

关键点 1.自学教程&#xff1a;内容安排由浅入深、循序渐进&#xff0c;130多个经典AI案例案例助你在实战中掌握技巧 2.技术手册&#xff1a;透彻讲解PSAI、Firefly&#xff0b;AI的绘画和修图实战技巧&#xff0c;高效率学习 3.老师讲解&#xff1a;赠送170分钟频教程和数百个…

企业内推平台招聘信息采集与分析在线项目实习

师傅带练 项目背景 为了实现有效的招聘&#xff0c;企业需要制定明确的招聘需求&#xff0c;根据业务发展需求和市场变化&#xff0c;精准定位所需人才的类型和层次&#xff0c;提高招聘效率和质量。而招聘网站需要积极满足企业的需求&#xff0c;提供针对性的服务&#xff0…

c语言--跳出continue、break

C 语言中的 continue 语句有点像 break 语句。但它不是强制终止&#xff0c;continue 会跳过当前循环中的代码&#xff0c;强迫开始下一次循环。 对于 for 循环&#xff0c;continue 语句执行后自增语句仍然会执行。对于 while 和 do…while 循环&#xff0c;continue 语句重新…

【面试题】数据底层原理:Elasticsearch写入流程解析

前言&#xff1a;本篇博客将介绍Elasticsearch的数据底层原理&#xff0c;涉及数据写入的过程以及相关概念。我们将深入探讨buffer、translog、refresh、commit、flush和merge等核心概念&#xff0c;帮助您更好地理解Elasticsearch的数据存储机制。 写入数据的基本过程 Elast…

【牛客】【刷题节】美团2024届秋招笔试第一场编程真题

1.小美的外卖订单【简单题】 题意理解&#xff1a; 这道题是简单题&#xff0c;主要是一个逻辑实现和判断的问题。但是简单题一般喜欢加一点小障碍&#xff0c;所以读题的时候就要比较注意一些约束条件。就比如这道题&#xff1a;过了15/20个测试用例&#xff0c;出现error, 当…

蓝桥杯小白月赛3.23

题目描述&#xff1a; AC代码&#xff1a; #include <iostream> #include<cstring> #include<algorithm>using namespace std;const int N 2e510; string str[N]; //写上&会速度更快一些 bool cmp(const string &s1,const string &s2) {//例…

金色传说:SAP-PP-CO01/CO02生产订单释放时增强:检查并显示下层组件在不合格库存地库存

文章目录 需求场景一、实现的效果二、实现步骤1.创建自建表2.增强代码 三、重磅福利 需求场景 计划员释放订单时,如果下层组件在不合格库存中有库存时,应先确认不合格库存地库存是否可用,已避免重复生产和库存积压. 因此,提出此需求: 在生产订单下达(释放)时,要提示下层组件在…

七段码(蓝桥杯)

文章目录 七段码题目描述答案&#xff1a;80分析编程求解&#xff1a;有多种方法方法一&#xff1a;状态压缩枚举构图&#xff08;以二极管为顶点&#xff09;DFS判断连通代码方法二&#xff1a;bfs 七段码 题目描述 小蓝要用七段码数码管来表示一种特殊的文字。 上图给出了…

python和Vue开发的RBAC用户角色权限管理系统

后端框架&#xff1a;python的FastAPI作为后端服务和python-jose作为JWT认证 前端框架&#xff1a;Vue3构建页面和Vue Router作为路由管理&#xff0c;Pinia作为数据存储&#xff0c;Vite作为打包工具 可以实现菜单控制和路由控制&#xff0c;页面里面有按钮权限控制&#xf…

css预处理器scss的使用如何全局引入

目录 scss 基本功能 1、嵌套 2、变量 $ 3、mixin 和 include 4、extend 5、import scss 在项目中的使用 1、存放 scss 文件 2、引入 variables 和 mixins 2-1、局部引入 2-2、全局引入 3、入口文件中引入其他文件 项目中使用 css 预处理器&#xff0c;可以提高 cs…

输入与输出

输入(Scanner类) Scanner是java5的新特性&#xff0c;在java.util包里&#xff0c;可以完成用户输入。步骤&#xff1a; 导入java.util包&#xff1b;构造Scanner对象&#xff0c;参数为u标准输入流System.in&#xff1b;使用next()方法系列接收数据 nextBoolean()接收一个布…

P6学习:解析P6 WBS-工作分解结构的原则

前言 WBS&#xff0c;及Work Breakdown Structure&#xff0c;中文工作分解结构&#xff0c;是总结工作阶段的项目的层次结构分解。 WBS 就像项目的大纲——它将项目分解为特定的可交付成果或阶段。 然后将活动添加到这些层中以创建项目计划的时间表。 WBS 使用流程会有所不…

【SpringBoot整合系列】SpringBoot3.x整合Swagger

目录 产生背景官方解释&#xff1a;作用SpringBoot3整合Swagger注意事项swagger3 常用注解SpringBoot3.x整合Swagger1.创建工程(jdk:17,boot:3.2.4)2.引入pom依赖3.application.yml添加配置4.添加swagger3.0配置5.控制器层(Controller)6.模型层(Model)7.启动并测试【Get请求接口…

任务管理工具Trello体验如何?一文揭秘

Trello是一款高效的协作与工作管理应用&#xff0c;这里我们将详细介绍Trello的功能、特点、优劣势、价格、定价、发展历程、使用场景以及使用技巧等等。 一、Trello 是什么 Trello是一款高效的协作与工作管理应用&#xff0c;设计用于跟踪团队项目、凸显当前活动任务、指派责…

IHO S-100系列产品标准

1 什么是S-100? S-100《通用海道测量数据模型》是国际海道测量组织(IHO)推出的新一代海上空间地理信息国际标准,旨在克服传统S-57数字海道测量数据传输标准的局限。这一标准不仅兼容了更为丰富的数据类型,如影像与栅格数据、时变数据等,还摒弃了固定的编码格式要求,采用…

推荐5款测试数据生成工具!

一个成功、有效的测试策略由下面几个基本部分组成&#xff1a;完整的测试覆盖率、最小化的环境影响和健壮的测试数据。 其中测试数据尤其重要&#xff0c;其质量直接关系到测试的有效性。可以把测试数据看作是保持测试引擎运行的燃料——高质量的测试数据有助于确保测试执行的…

苹果App Store上架工具介绍

文章目录 摘要引言正文1. Xcode2. [appuploder](https://www.applicationloader.net/)3. [克魔助手](https://keymob.com/) 4.[ipa guard](https://www.ipaguard.com/)总结参考资料 摘要 苹果App Store作为iOS应用程序的主要分发渠道&#xff0c;上架应用程序需要遵守规定和通…

2024消息预知在线客服系统

新增消息预知&#xff0c;消息撤回&#xff0c;消息已读未读&#xff0c; 修复需要刷新才能收到消息 修复客户来源地址 修复消息提示音 修复桌面推送提醒 要求服务器环境&#xff1a; 宝塔面板 &#xff0c;Nginx1.16-1.18&#xff0c;7.2.23<php<7.3&#xff08;因…

Python神器!WEB自动化测试集成工具 DrissionPage

案例 跟踪商品价格&#xff0c;降价自动推送消息到微信 咱买不起还等不起吗&#xff1f; from DrissionPage import * import re from time import sleep import csv import os import datetime#写入时间 p MixPage() p.get(http://xxxxxxx) #快快买网址 p.to_ifram…