数据结构 之 队列(Queue)

​​​​​​​

🎉欢迎大家观看AUGENSTERN_dc的文章(o゜▽゜)o☆✨✨

🎉感谢各位读者在百忙之中抽出时间来垂阅我的文章,我会尽我所能向的大家分享我的知识和经验📖

🎉希望我们在一篇篇的文章中能够共同进步!!!

🌈个人主页:AUGENSTERN_dc

🔥个人专栏:C语言 | Java | 数据结构

⭐个人格言:

一重山有一重山的错落,我有我的平仄

一笔锋有一笔锋的着墨,我有我的舍得

目录

1. 定义:

2. 队列的常用方法和模拟实现:

2.1 常用方法:

2.2 模拟实现:

 3. 队列的模拟实现源码:

4. 循环队列

4.1 模拟实现:

5. 双端队列:


1. 定义:

队列和栈类似,是一种只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表;

进入队列的一端称为队尾,离开队列的一端称为队头

队列这个结构遵循先进先出的原则;

 在日常生活中,例如:

多人在网上对老师提交任务时,会将我们所提交的任务存放到一个队列中,然后队列将这些任务按照先进先出的顺序进行出队和入队的操作,老师看到的任务,也就会按照提交时间的先后来排序;
 

由上图可以看出Queue是一个接口,底层是由链表(LinkedList)实现的;

2. 队列的常用方法和模拟实现:

2.1 常用方法:

方法作用
offer(E e)将e进行入队操作
E poll()

将e进行出队列操作,并且返回e的值

E peek()获取队头元素
int size()获取队列的长度
boolean isEmpty()判断队列是否为空

(在队列的模拟实现中,我们并不使用泛型,而是使用整形来代替泛型) 

以上就是队列的常用方法,接下来我们进行模拟实现:

2.2 模拟实现:

队列的底层是由链表来实现的,我们先创建一个My_Queue类:

public class My_Queue {public static class ListNode {ListNode next;      //节点的后继ListNode prev;      //节点的前驱int value;          //节点的值public ListNode() {//不带参数的构造方法}public ListNode(int value){//带一个参数的构造方法,将节点的值赋为valuethis.value = value;}}ListNode first;         //队头节点ListNode last;          //队尾节点int size = 0;           //队列长度
}

< 1 > offer方法:

offer方法是将指定元素插入到队列的队尾:

与之前的栈和顺序表不同,由于队列的底层是用链表实现的,故不需要判断队列是否满了;

// 入队列---向双向链表位置插入新节点public void offer(int e){ListNode newNode = new ListNode(e);     //实例化一个节点if(first == null){                      //若该队列为空first = newNode;                    //将队头和队尾都更新为newNodelast = newNode;}else{                                  //若队列不为空last.next = newNode;                //将newNode赋值给队尾.nextnewNode.prev = last;                //将newNode的pre赋值为队尾last = newNode;                     //将队尾更新为newNode}last = newNode;                         //更新队尾size++;                                 //队列长度 +1
}

< 2 > poll方法:

poll方法是将队头的元素进行出队操作,并返回队头元素的值:

在进行该操作之前,我们需要判断队列是否为空,若为空,则需抛出异常:

异常代码如下:

public class QueueEmptyException extends RuntimeException {public QueueEmptyException () {super();}public QueueEmptyException (String str) {super(str);}
}

poll方法如下:

public int poll(){// 1. 队列为空// 2. 队列中只有一个元素----链表中只有一个节点---直接删除// 3. 队列中有多个元素---链表中有多个节点----将第一个节点删除int value = 0;if(first == null){      //若为空,则抛出异常throw new QueueEmptyException("队列为空,不能进行poll操作!!!");}else if(first == last){        //若只有一个节点,则直接删除该节点last = null;first = null;}else{value = first.value;        //将队头的元素赋值给valuefirst = first.next;         //将队头更新为队头的下一个节点first.prev.next = null;first.prev = null;}size--;                         //将队列长度 -1return value;                   //返回队头的值
}

< 3 > peek方法:

peek方法是返回队头的节点的值:

// 获取队头元素---获取链表中第一个节点的值域public int peek(){if(first == null){      //若队列为空,则抛出异常throw new QueueEmptyException("队列为空,不能进行peek操作!!!");}return first.value;     //返回队头的值
}

< 4 > size方法:

size方法是返回队列的长度:

public int size() {return size;        //返回队列的长度
}

< 5 > isEmpty方法:

isEmpty是判断队列是否为空:

public boolean isEmpty(){return first == null;       //返回队头是否为空 的值
}

 3. 队列的模拟实现源码:

public class My_Queue {public static class ListNode {ListNode next;      //节点的后继ListNode prev;      //节点的前驱int value;          //节点的值public ListNode() {//不带参数的构造方法}public ListNode(int value){//带一个参数的构造方法,将节点的值赋为valuethis.value = value;}}ListNode first;         //队头节点ListNode last;          //队尾节点int size = 0;           //队列长度// 入队列---向双向链表位置插入新节点public void offer(int e){ListNode newNode = new ListNode(e);     //实例化一个节点if(first == null){                      //若该队列为空first = newNode;                    //将队头和队尾都更新为newNodelast = newNode;}else{                                  //若队列不为空last.next = newNode;                //将newNode赋值给队尾.nextnewNode.prev = last;                //将newNode的pre赋值为队尾last = newNode;                     //将队尾更新为newNode}last = newNode;                         //更新队尾size++;                                 //队列长度 +1}// 出队列---将双向链表第一个节点删除掉public int poll(){// 1. 队列为空// 2. 队列中只有一个元素----链表中只有一个节点---直接删除// 3. 队列中有多个元素---链表中有多个节点----将第一个节点删除int value = 0;if(first == null){      //若为空,则抛出异常throw new QueueEmptyException("队列为空,不能进行poll操作!!!");}else if(first == last){        //若只有一个节点,则直接删除该节点last = null;first = null;}else{value = first.value;        //将队头的元素赋值给valuefirst = first.next;         //将队头更新为队头的下一个节点first.prev.next = null;first.prev = null;}size--;                         //将队列长度 -1return value;                   //返回队头的值}// 获取队头元素---获取链表中第一个节点的值域public int peek(){if(first == null){      //若队列为空,则抛出异常throw new QueueEmptyException("队列为空,不能进行peek操作!!!");}return first.value;     //返回队头的值}public int size() {return size;        //返回队列的长度}public boolean isEmpty(){return first == null;       //返回队头是否为空 的值}
}

4. 循环队列

实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。 环形队列通常使用数组实现。

4.1 模拟实现:

/*解题思路:1. 注意,循环队列底层空间大小是固定的2. 采用计数方式实现队列空或者满的判断3. 入队列时:队列可能满,往队尾插入,注意back在末尾特殊情况4. 出队列时:队列可能空,删除队头元素,注意front可能在队尾5. 获取队头注意空队列时返回-16. 获取队尾时,注意back-1可能为负数,队尾元素下标:(back-1+array.length)%array.length
*/
class MyCircularQueue {int[] array;int front;   // 队头int back;    // 队尾int count;   // 队列中有效元素个数public MyCircularQueue(int k) {array = new int[k];}public boolean enQueue(int value) {if(isFull()){return false;}// 在队尾插入一个元素,然后back往后移动array[back] = value;back++;// back往后移动之后,可能会来到空间末尾// 此时将back挪到空间起始位置if(back == array.length){back = 0;}count++;return true;}public boolean deQueue() {if(isEmpty()){return false;}// 出队列,队头往后移动++front;// 队头往后移动之后也可能会来到空间末尾// 此时需要挪到空间起始位置front %= array.length;--count;return true;}public int Front() {if(isEmpty()){return -1;}// 如果队列不空,说明队列中有元素,队头元素直接返回front即可return array[front];}public int Rear() {if(isEmpty()){return -1;}// 如果队列不空,说明队列中有元素// 队尾元素即:back-1,// 如果back不在0号位置,back-1就是队尾元素下标// 如果back在0号位置,-1之后就是负数,因此需要+数组长度// 两个结合起来:return array[(back - 1 + array.length)%array.length];}public boolean isEmpty() {return 0 == count;}public boolean isFull() {return count == array.length;}
}

5. 双端队列:

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。 那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

Deque是一个接口,使用时必须创建LinkedList的对象。

以上就是队列的全部内容:感谢观看!!!!

制作不易,三连支持

谢谢!!!

以上的模拟实现代码未必是最优解,仅代表本人的思路,望多多理解,谢谢!!

最后送给大家一句话,同时也是对我自己的勉励:

知不足而奋进,望远山而前行!!!!

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

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

相关文章

HTML + CSS 高频考点之 - 定位

简述&#xff1a; 补充固定定位也会脱离文档流、不会占据原先位置 1、什么是文档流 文档流是指HTML文档中元素排列的规律和顺序。在网页中&#xff0c;元素按照其在HTML文档中出现的顺序依次排列&#xff0c;这种排列方式被称为文档流。文档流决定了元素在页面上的位置和互相之…

【Docker】 ubuntu18.04编译时内存不足需要使用临时交换分区解决“c++: internal compiler error“错误

【Docker】 ubuntu18.04编译时内存不足需要使用临时交换分区解决"c: internal compiler error"错误 问题描述 安装独立功能包时编译不成功&#xff0c;出现 “c: internal compiler error: Killed(program cciplus)” 错误。 解决方案 出现这个问题的原因大概率是…

力扣题目训练(21)

2024年2月14日力扣题目训练 2024年2月14日力扣题目训练605. 种花问题617. 合并二叉树628. 三个数的最大乘积289. 生命游戏299. 猜数字游戏149. 直线上最多的点数 2024年2月14日力扣题目训练 2024年2月14日第二十一天编程训练&#xff0c;今天主要是进行一些题训练&#xff0c;…

Docker安装蜜罐Hfish

前言 无意中发现公司的一台服务器被爆破&#xff0c;修改了密码&#xff0c;为了确定内网是否安装需要搭建一个蜜罐来看一下是否存在隐患。 如何安装Docker&#xff0c;请查看我另一篇文章 https://blog.csdn.net/l1677516854/article/details/136751211 一、拉取镜像 dock…

dockers拉取MySQL及Redis并挂载文件

目录 一 . MySQL拉取 1、进入 MySQL 容器内部。 2、登录 MySQL。 3、修改远程连接 4、刷新 二 . Redis拉取 1 . redis/conf中新建文件redis.conf&#xff0c;内容如下&#xff1a; 2 . 容器运行 一 . MySQL拉取 docker run -d --restartalways --name mysql \ -v /…

HTML、XHTML和HTML5系列对比

目录 HTML HTML的优点&#xff1a; HTML的缺点&#xff1a; 应用场景&#xff1a; XHTML XHTML的优点&#xff1a; XHTML的缺点&#xff1a; 应用场景&#xff1a; HTML5 HTML5的优点&#xff1a; HTML5的缺点&#xff1a; 应用场景&#xff1a; 回首发现&#xff0…

算法刷题Day11 | 20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值

目录 0 引言1 有效的括号1.1 我的解题 2 删除字符串中的所有相邻重复项2.1 我的解题 3 逆波兰表达式求值3.1 我的解题 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;❣️ 寄语&#xff1a;书到用时方恨少…

Spring中使用内置的tomcat容器启动后自动退出问题解决方法

在Spring中使用内置的tomcat 启动后自动退出 退出代码为0 且不报任务错误的解决方法. 日志如下: Connected to the target VM, address: 127.0.0.1:51129, transport: socket 三月 15, 2024 11:55:00 下午 org.apache.coyote.AbstractProtocol init 信息: Initializing Proto…

Linux下安装多个nodejs并映射Jenkins

背景 需要Jenkins中切换多个Node&#xff0c;比如nodejs16和nodesjs18,所以在宿主机按照好这两个版本&#xff0c;然后再映射到Jenkins容器中 步骤 1.下载地址 https://nodejs.org/dist/ 放到 cd /opt/soft/2.解压 tar -xzvf node-v16.20.0-linux-x64.tar.gz tar -xzvf n…

【IC设计】Verilog线性序列机点灯案例(一)(小梅哥课程)

文章目录 设计目标思路仿真结果时间点一&#xff1a;201ns时间点二&#xff1a;220ns时间点三&#xff1a;250,000,220ns时间点四&#xff1a;1,000,000,200ns时间点五&#xff1a;1,000,000,220ns 总结&#xff1a; 案例和代码来自小梅哥课程&#xff0c;本人仅对知识点做做笔…

【ansible】ansible的介绍和安装

前言运维自动化 云计算核心职能 搭建平台架构 日常运营保障 性能效率优化 相关工具 代码管理&#xff08;SCM&#xff09;&#xff1a;GitHub、GitLab、BitBucket、SubVersion 构建工具&#xff1a;maven、Ant、Gradle 自动部署&#xff1a;Capistrano、CodeDeploy 持续…

代码+视频,R语言使用BOOT重抽样获取cox回归方程C-index(C指数)可信区间

bootstrap自采样目前广泛应用与统计学中&#xff0c;其原理很简单就是通过自身原始数据抽取一定量的样本&#xff08;也就是取子集&#xff09;&#xff0c;通过对抽取的样本进行统计学分析&#xff0c;然后继续重新抽取样本进行分析&#xff0c;不断的重复这一过程N&#xff0…