【数据结构】队列(Queue)

目录

队列概念

​方法

队列模拟实现

链表实现队列

入队列

出队列

获取队头元素

数组实现队列

入队列

出队列

返回头队列

返回尾队列

完整代码

双链表实现队列

数组实现队列(设计循环队列)


队列概念

队列:只允许在一段进行插入数据操作,在另一端进行删除数据操作的特殊线性表

队列具有先进先出的特点,就像是排队一样,先排队的先出去。

入队列:进行插入操作的一段称为队尾。

出队列:进行删除操作的一段称为队头。

方法

方法功能
boolean offer(E e)入队列
E poll()出队列
peek()获取队头元素
int size()获取队列中有效元素个数
boolean isEmpty()检测队列是否为空

注意:Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。

队列模拟实现

队列可以通过链表和数组实现

链表实现队列

这里实现队列采用的双向链表,所以定义一些基本变量如下,useSize记录队列中数据个数。

public class MyQueue {//双向链表实现static class ListNode{public int val;public ListNode prev;public ListNode next;public ListNode(int val){this.val = val;}}public ListNode first = null; //队头public ListNode last = null;  //队尾public int useSize = 0;
}
入队列

offer方法

在往链表中放数据时,要考虑链表是否为空,当链表为空,队头和队尾都等于这个数据。

这时可以写一个isEmpty方法来判断,对于判断是否为空的条件,可以看useSize是否为0,也可以时first是否为0。

    public boolean isEmpty(){return useSize == 0;//return first == 0;}

当链表不为空时,这时实现的是尾插,所以offer方法完整部分为:

    public void offer(int val){ListNode node = new ListNode(val);if(isEmpty()){first = last = node;}else{last.next = node;node.prev = last;last = last.next;}useSize++;}
出队列

poll方法
出队列时也要考虑是否为空,用链表实现出队列要做的是把头节点往后挪一个位置。

当链表中只有一个节点,就没有必要再空置前一个结点了。

    public int poll(){if(isEmpty()){return -1;}int val = first.val;first = first.next;//一个节点,就没必要再置空前一个节点if(first != null){first.prev = null;}useSize--;return val;}
获取队头元素

peek方法

获取队头元素思路很清晰,只要返回first对应的值即可。也要进行是否为空的判断。

    public int peek(){if(isEmpty()){return -1;}return first.val;}

数组实现队列

这里主要做得是:设计循环队列,我们可以把循环队列设想成一个环,在一个有限的环里实现队列。设定front为头位置,rear为尾位置。

 判断数组是否为满有三种方法:

  1. 定义size
  2. 添加标记 定义boolean类型
  3. 浪费一个空间,即:确保一个空间里面不放元素,判断:rear下一个是不是front

这里我们采用的是最后一种方法:浪费一个空间。

不过还要解决一个问题: rear或者front 下标如何从 7位置 到 0位置?

对应的解决方案为:(rear +1)% 数组长度,front同理。

因为采用数组来实现循环队列,所以第一步是定义基础变量。

class MyCircularQueue {public int front;public int rear;public int[] elem;public MyCircularQueue(int k) {this.elem = new int[k+1];}
}

因为需要浪费一个位置,所以申请 k+1个位置。 

入队列

enQueue方法

主要的思路是把数据放到rear位置,然后rear后移一个位置。

不过要考虑数组是否为满,这是可以写一个isFull方法。

判断的条件是:rear 的下一个位置 是否是 front

    public boolean isFull() {return (rear+1) % elem.length == front;}

enQueue方法完整为下:

    //入队列public boolean enQueue(int value) {if(isFull()){return false;}elem[rear] = value;rear = (rear+1) % elem.length;return true;}

注意:rear后移一个位置不是rear++,而是(rear+1) % elem.length

出队列

deQueue方法

出队列的主要思路是:把front后移一个位置,前面的数据会被后面逐渐放进去的rear覆盖。

此时还要考虑数组是否为空,写一个isEmpty方法。判断条件是:front和rear是否相等。

    public boolean isEmpty() {return front == rear;}

出队列的完整代码为:

    //出队列public boolean deQueue() {if(isEmpty()){return false;}front = (front+1) % elem.length;return true;}
返回头队列

Front方法

  • 判断是否为空
  • 返回front位置的数据
    //返回头队列public int Front() {if(isEmpty()){return -1;}return elem[front];}
返回尾队列

Rear方法

  • 判断是否为空
  • 判断rear 是否为 0

之所以要判断rear == 0,是因为当rear == 0时,返回的是elem.length - 1,而rear != 0时,返回rear - 1;

完整代码为:

    public int Rear() {if(isEmpty()){return -1;}int index = (rear == 0) ? elem.length - 1 : rear-1;return elem[index];}

完整代码

双链表实现队列

public class MyQueue {//双向链表实现static class ListNode{public int val;public ListNode prev;public ListNode next;public ListNode(int val){this.val = val;}}public ListNode first = null;public ListNode last = null;public int useSize = 0;public void offer(int val){ListNode node = new ListNode(val);if(isEmpty()){first = last = node;}else{last.next = node;node.prev = last;last = last.next;}useSize++;}public int poll(){if(isEmpty()){return -1;}int val = first.val;first = first.next;//一个节点,就没必要再置空前一个节点if(first != null){first.prev = null;}useSize--;return val;}public int peek(){if(isEmpty()){return -1;}return first.val;}public boolean isEmpty(){return useSize == 0;//return first == 0;}
}

数组实现队列(设计循环队列)

class MyCircularQueue {public int front;public int rear;public int[] elem;public MyCircularQueue(int k) {this.elem = new int[k+1];}//入队列public boolean enQueue(int value) {if(isFull()){return false;}elem[rear] = value;rear = (rear+1) % elem.length;return true;}//出队列public boolean deQueue() {if(isEmpty()){return false;}front = (front+1) % elem.length;return true;}//返回头队列public int Front() {if(isEmpty()){return -1;}return elem[front];}//返回尾队列public int Rear() {if(isEmpty()){return -1;}int index = (rear == 0) ? elem.length - 1 : rear-1;return elem[index];}public boolean isEmpty() {return front == rear;}public boolean isFull() {return (rear+1) % elem.length == front;}
}

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

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

相关文章

鸿蒙HarmonyOS开发:如何灵活运用服务卡片提升用户体验

文章目录 一、ArkTS卡片相关模块二、卡片事件能力说明三、卡片事件的主要使用场景3.1、使用router事件跳转到指定UIAbility3.1.1、卡片内按钮跳转到应用的不同页面3.1.2、服务卡片的点击跳转事件 3.2、通过message事件刷新卡片内容3.2.1、在卡片页面调用postCardAction接口触发…

Linux 背景、命令

一、嵌入式、Linux背景 1、嵌入式: 硬件与软件相结合 定制、为硬件设计相关代码来进行操作,代码测试,烧进板子,通过语音、图像、按钮等操作方式来调用。 2、操作系统种类: Dos,Windows,Uni…

数据分析处理库(pandas)

目录 数据预处理 数据读取 DataFrame结构 数据索引 创建DataFrame Series操作 数据分析 统计分析 pivot数据透视表 groupby操作 常用函数操作 Merge操作 排序操作 缺失值处理 apply自定义函数 时间操作 绘图操作 大数据处理技巧 数值类型转换 属性类型转换…

51单片机——实时时钟

1、DS1302介绍 DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,且具有闰年补偿等多种功能 RTC(Real Time Clock):实时时钟,是一种集成电路,通常称为时钟…

2024年国家自然科学基金即将公布,如何第一时间知道评审结果?

公众号:生信漫谈,获取最新科研信息! 2024年国家自然科学基金即将公布,如何第一时间知道评审结果?https://mp.weixin.qq.com/s?__bizMzkwNjQyNTUwMw&mid2247486995&idx1&snd3f8a1fe0f5d210db2048ca1b3933…

【开发笔记】Notepad++配置

Notepad配置 Notepad保护色配置 settings --> Style Configurator 选择 Enable olobal foreground colourEnable global background colour 设置背景色 点击 Save & Close按钮,完成保存。 设置 Unix换行符

算法day08 链表

4.链表_哔哩哔哩_bilibili 一、判断链表为回文 暴力方式: 从链表头开始将链表每一个元素值依次放入数组中,按下标比较值。 从链表尾开始将链表一半元素值放入stack栈中;每次弹栈比较 弹出的值和 链表值。 快慢指针: 假设有这样一个…

【Threejs进阶教程-着色器篇】6. 2D SDF(三) 移动图形,限制图形,绘制多个图形

2D SDF 移动与合并图形 前五篇地址,建议按顺序学习本篇使用到的初始代码减小扩散范围clamp函数修改maxDistance来修改扩散范围 移动扩散中心添加第二个扩散点降低点的同步率调整参数来优化效果添加更多扩散点 完整源码如有不明白的,可以在下方留言或者加…

【GIT】Idea中的git命令使用-全网最新详细(包括现象含义)

原文网址:【GIT】Idea中的git命令使用-全网最新详细(包括现象含义) 文章目录 **命令1:查看当前所处分支:****命令2:拉取最新代码:****命令3:切换分支:****命令4&#xff…

MAC 、 IP ARP

MAC地址 基本概念 MAC地址是以太网的MAC子层所使用的地址——数据链路层 使用点对点信道的数据链路层不需要使用地址 使用广播信道的数据链路层必须使用地址来区分各主机 实现同一个广播信道上的不同主机之间的通信 每个主机都必须要有一个唯一的表示——一个数据链路层地址…

基于Java+SpringBoot+Vue的学生评奖评优管理系统的设计与实现

基于JavaSpringBootVue的学生评奖评优管理系统的设计与实现 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅 某信 gzh 搜索【智…

2024 年的 Web3 游戏:演变、趋势和市场动态

Web3 游戏行业在经历了多年的快速发展和变革之后,正在2024年迎来全新的阶段。这个行业从最初的边玩边赚(Play-to-Earn, P2E)模式出发,如今正在向更为平衡的“边玩边赚”模式转型。这种转型不仅解决了早期 P2E 模式下存在的可持续性…

EmguCV学习笔记 VB.Net 9.1 VideoCapture类

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

编译LineageOS模拟器镜像,导出到AndroidStudio

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 源码下载 LineageOS官网:https://lineageos.org/ LineageOS源码 github 地址:https://github.com/LineageOS/android LineageOS源码国…

编写一个每次随机生成 10个 0(包括) 到 100 之间的随机正整数。

编写一个每次随机生成 10个 0(包括) 到 100 之间的随机正整数。 package cn.itcast.example;import java.util.Iterator; import java.util.Random; public class example {public static void main (String[] arge) {System.out.println("Math.ra…

QNN:基于QNN+example重构之后的yolov8det部署

QNN是高通发布的神经网络推理引擎,是SNPE的升级版,其主要功能是: 完成从Pytorch/TensorFlow/Keras/Onnx等神经网络框架到高通计算平台的模型转换; 完成模型的低比特量化(int8),使其能够运行在高…

超长二进制利用Integer转换

1.Integer缺点 目前测试Integer只能一次性转4*7位二进制数,也就是7位16进制,故进行改进 2.改进 操作:每四位二进制一转换,以免到上限报错 注解格式:序号(代码顺序)解释 public class Main {…

《PCI Express体系结构导读》随记 —— 第II篇 第7章 PCIe总线的数据链路层与物理层(2)

接前一篇文章:《PCI Express体系结构导读》随记 —— 第II篇 第7章 PCIe总线的数据链路层与物理层(1) 7.1 数据链路层的组成结构 数据链路层使用ACK/NAK协议发送和接收TLP,由发送部件和接收部件组成。其中,发送部件由…

Springboot里集成Mybatis-plus、ClickHouse

🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 Springboot里集成Mybati…

基于Java+SpringBoot+Vue的汽车销售网站

基于JavaSpringBootVue的汽车销售网站 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅 某信 gzh 搜索【智能编程小助手】获取项…