数据结构之Queue | 让我们一块来学习数据结构
前面的两篇文章分别介绍了List和Stack,下面让我们一起来学习Queue
队列的概况
队列是一种列表,不同的是队列只能在队尾插入元素,在队首删除元素。队列用于存储按顺序排列的数据,先进先出,这点和栈不一样,在栈中,最后入栈的元素反而被优先处理。可以将队列想象成在银行前排队的人群,排在最前面的人第一个办理业务,新来的人只能在后面排队,直到轮到他们为止。
队列是一种先进先出(First-In-First-Out,FIFO)的数据结构。队列被用在很多地方,比如提交操作系统执行的一系列进程、打印任务池等,一些仿真系统用队列来模拟银行或杂货店里排队的顾客。
基础队列
队列的两种主要操作是:向队列中插入新元素和删除队列中的元素。插入操作也叫做入队,删除操作也叫做出队。入队操作在队尾插入新元素,出队操作删除队头的元素。下图演示了这两个操作。

队列的另外一项重要操作是读取队头的元素。这个操作叫做 peek()。该操作返回队头元素,但不把它从队列中删除。除了读取队头元素,我们还想知道队列中存储了多少元素,可以使用 length 属性满足该需求;要想清空队列中的所有元素,可以使用 clear() 方法来实现。
使用数组来实现队列看起来顺理成章。JavaScript 中的数组具有其他编程语言中没有的优点,数组的 push() 方法可以在数组末尾加入元素,shift() 方法则可删除数组的第一个元素。
构建Queue类
class Queue {
constructor() {
this.dataStore = [];
}
enqueue(element) {
this.dataStore.push(element);
}
dequeue() {
return this.dataStore.shift();
}
front() {
return this.dataStore[0];
}
back() {
return this.dataStore[this.dataStore.length - 1];
}
empty() {
return this.dataStore.length === 0;
}
toString() {
return this.dataStore.toString();
}
length() {
return this.dataStore.length;
}
}
优先队列
在一般情况下,从队列中删除的元素,一定是率先入队的元素。但是也有一些使用队列的应用,在删除元素时不必遵守先进先出的约定。这种应用,需要使用一个叫做优先队列的数据结构来进行模拟。
从优先队列中删除元素时,需要考虑优先权的限制。比如医院急诊科的候诊室,就是一个采取优先队列的例子。当病人进入候诊室时,分诊护士会评估患者病情的严重程度,然后给一个优先级代码。高优先级的患者先于低优先级的患者就医,同样优先级的患者按照先来先服务的顺序就医。
先来定义存储队列元素的对象,然后再构建我们的优先队列系统:
class Patient {
constructor(name, code) {
this.name = name;
this.code = code;
}
}
变量 code 是一个整数,表示患者的优先级或病情严重程度(code越小代表病情越严重)。
下面需要重新定义Queue类的dequeue方法,使其删除队列中拥有最高优先级的元素。新的 dequeue()方法遍历队列的底层存储数组,从中找出优先码最低的元素,然后使用数组的 splice()方法删除优先级最高的元素。新的dequeue()方法定义如下所示:
dequeue() {
let priority = this.dataStore[0];
for (const i = 0, len = this.dataStore.length; i < len; i++){
if (this.dataStore[i].code < priority) {
priority = i;
}
}
return this.dataStore.splice(priority, 1);
}
最后,需要定义 toString() 方法来显示 Patient 对象。
toString() {
let retStr = "";
for (var i = 0; i < this.dataStore.length; ++i) {
retStr += `${this.dataStore[i].name} code: ${this.dataStore[i].code}\n`;
}
return retStr;
}
测试优先队列

双端队列
双端队列(deque,或称double-ended queue)是一种允许我们同时从前端和后端添加和移除元素的特殊队列。
在计算机科学中,双端队列的一个常见应用是存储一系列的撤销操作。每当用户在软件中进行了一个操作,该操作就会被存在双端队列中。当用户点击撤销按钮时,该操作会从双端队列中弹出,表示它被从后端移除了一个了。在进行了一定数量的操作后,最先进行的操作会被从双端队列的前端移除。由于双端队列同时遵循了先入先出和后入先出的原则,可以说是它是把队列和栈相结合的一种数据结构。
创建Deque类
class Deque {
constructor() {
this.dataStore = [];
}
addFront(element) {
if(this.empty()){
this.addBack(element)
}else{
this.dataStore.unshift(element);
}
}
addBack(element) {
this.dataStore.push(element);
}
removeFront() {
return this.dataStore.shift();
}
removeBack() {
return this.dataStore.pop();
}
front() {
return this.dataStore[0];
}
back() {
return this.dataStore[this.dataStore.length - 1];
}
empty() {
return this.dataStore.length === 0;
}
toString() {
return this.dataStore.toString();
}
length() {
return this.dataStore.length;
}
}
测试Deque类的代码

实际应用-->回文字符串的判断
回文是指这样一种现象:一个单词、短语或数字,从前往后写和从后往前写都是一样的。 比如,单词“dad”、“racecar”就是回文;如果忽略空格和标点符号,下面这个句子也是回 文,“A man, a plan, a canal: Panama”;数字 1001 也是回文。
在之前的文章中是使用栈(Stack)这一数据结构,其实回文字符串字号的判断方法是使用双端队列(Deque)来实现。
function isPalindrome(word) {
if (typeof word !== "string") {
throw TypeError(`参数不是string类型`);
}
let tmp = new Deque();
for (let element of word) {
tmp.addBack(element);
}
while (tmp.length() > 1) {
if (tmp.removeFront() !== tmp.removeBack()) {
return false;
}
}
return true;
}
console.log(isPalindrome("racecar")) // true
console.log(isPalindrome("hello")) // false
参考资料
- 数据结构与算法JavaScript描述
- 学习JavaScript数据结构与算法 第3版
数据结构之Queue | 让我们一块来学习数据结构的更多相关文章
- 数据结构之LinkedList | 让我们一块来学习数据结构
highlight: monokai theme: vue-pro 上一篇文章中使用列表(List)对数据排序,当时底层储存数据的数据结构是数组.本文将讨论另外一种列表:链表.我们会解释为什么有时链表 ...
- 数据结构之Set | 让我们一块来学习数据结构
数组(列表).栈.队列和链表这些顺序数据结构对你来说应该不陌生了.现在我们要学习集合,这是一种不允许值重复的顺序数据结构.我们将要学到如何创建集合这种数据结构,如何添加和移除值,如何搜索值是否存在.你 ...
- 数据结构之Stack | 让我们一块来学习数据结构
栈的介绍 栈就是和列表类似的一种数据结构,它可用来解决计算机世界里的很多问题.栈是一种高 效的数据结构,因为数据只能在栈顶添加或删除,所以这样的操作很快,而且容易实现. 栈的使用遍布程序语言实现的方方 ...
- 数据结构之List | 让我们一块来学习数据结构
列表[List]的定义 列表是一组有序的数据.每个列表中的数据项称为元素.在 JavaScript 中,列表中的元素 可以是任意数据类型.列表中可以保存多少元素并没有事先限定,实际使用时元素的数量 受 ...
- 《Java程序设计与数据结构教程(第二版)》学习指导
<Java程序设计与数据结构教程(第二版)>学习指导 欢迎关注"rocedu"微信公众号(手机上长按二维码) 做中教,做中学,实践中共同进步! 原文地址:http:// ...
- SqList *L 和 SqList * &L的区别/学习数据结构突然发现不太懂 小祥我查找总结了一下
小祥在学习李春葆的数据结构教程时发现一个小问题,建立顺序表和输出线性表,这两个函数的形参是不一样的. 代码在这里↓↓↓ //定义顺序表L的结构体 typedef struct { Elemtype d ...
- 在Object-C中学习数据结构与算法之排序算法
笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...
- 【数据结构】 Queue 的简单实现
[数据结构] Queue 的简单实现 public class XQueue<T> { /// <summary> /// 第一个元素 /// </summary> ...
- python学习——数据结构
数据结构简介 1,数据结构 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成.简单来说,数据结构就是设计数据以何种方式组织并存贮在计算机中.比如:列表,集合与字 ...
随机推荐
- 2021-2-25:对于 Java MMAP,如何查看文件映射脏页,如何统计MMAP的内存大小?
我们写一个测试程序: public static void main(String[] args) throws Exception { RandomAccessFile randomAccessFi ...
- 使用gitlab构建基于docker的持续集成(一)
使用gitlab构建基于docker的持续集成(一) gitlab docker aspnetcore 持续集成 开篇 整体环境规划 准备工作 CA证书 虚拟机系统:安装Centos7.3 3.设置C ...
- 关于 JMeter 5.4.1 的一点记录
APACHE JMeter table { border: 0; border-collapse: collapse; background-color: rgba(255, 245, 218, 1) ...
- 【图像处理】使用OpenCV+Python进行图像处理入门教程(三)色彩空间
这篇随笔介绍使用OpenCV进行图像处理的第三章 色彩空间. 3 色彩空间 之前的介绍,大多是基于BGR色彩空间进行的,但针对不同的实际情况,研究人员提出了许多色彩空间,它们都有各自擅长处理的领域. ...
- 分布式session实现方式
一.背景 在搭建完集群环境后,不得不考虑的一个问题就是用户访问产生的session如何处理. 如果不做任何处理的话,用户将出现频繁登录的现象,比如集群中存在A.B两台服务器,用户在第一次访问网站时,N ...
- axios之增删查改操作
一.get方法获取数据 axios.get('url') .then(function (res) { console.log(res); }).catch(function (error) { co ...
- YoloV3 记录
常用于目标检测,因为最近要从目标分类问题转到目标检测中去. tensoflow.Keras(大公司一般都用这个).pytorch(本次学习)------------------主要框架 程序设计模块规 ...
- Redis的常用淘汰策略以及算法实现
一.Redis的内存配置 1,Redis配置内存为多少合适? 默认:如果不设置最大内存大小或者设置最大内存大小为0,在64为操作系统下不限制内存大小,在32位操作系统下最多使用3GB内存. 极限情况: ...
- P1962 斐波那契数列 【矩阵快速幂】
一.题目 P1962 斐波那契数列 二.分析 比较基础的递推式转换为矩阵递推,这里因为$n$会超出$int$类型,所以需要用矩阵快速幂加快递推. 三.AC代码 1 #include <bits/ ...
- 攻防世界 reverse 进阶 -gametime
19.gametime csaw-ctf-2016-quals 这是一个小游戏,挺有意思的 's'-->' ' 'x'-->'x' 'm'-->'m' 观察流程,发现检验函 ...