数据结构之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,数据结构 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成.简单来说,数据结构就是设计数据以何种方式组织并存贮在计算机中.比如:列表,集合与字 ...
随机推荐
- 使用Mongodb设计评论系统
1:如何设计数据存储结构 1.1:mysql 1:评论表 2:回复表(评论的评论) 1.2:mongodb 不需要两张表,一个collection 就可以搞定. 数据结构如图: 通过对象数组中的字段作 ...
- CMD(命令提示符)的基本操作(文件)
打开CMD窗口,接下来将介绍如何使用CMD来创建.删除.修改.查看文件 1.1 使用CMD创建空文件(为了更好的演示,本文皆以D盘为当前路径),命令如下: copy nul xxx.xx(文件名) 命 ...
- kali 下的邮件发送工具 swaks
kali 下的邮件发送工具 swaks Swaks 是一个功能强大,灵活,可编写脚本,面向事务的 SMTP 测试工具,目前 Swaks 托管在私有 svn 存储库中. 官方项目 http://jetm ...
- 【图像处理】使用OpenCV进行图像处理教程(一)
OpenCV是进行图像处理的工具,也是计算机视觉领域近十几年不断发展和完善的产物.面对这个已基本成熟的开源库知识体系,我们新生代有必要不断地总结.回顾,以新的视角快速融入计算机视觉的奥秘世界. 从这篇 ...
- jquery通过live绑定toggle事件
$("a[name=reply]").live("click",function(){ $(this).toggle( function () { var $c ...
- dubbo实战之一:准备和初体验
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- LG gram 双系统全指南
LG gram 双系统全指南 为了和同学联机玩帝国时代2,以及为了下学期的编程课,五年没用过 Windows 的我决定装 Ubuntu20.04 LTS / WIndows 10 双系统了. 我的 L ...
- php伪协议分析与CTF例题讲解
本文大量转载于:https://blog.csdn.net/qq_41289254/article/details/81388343 (感谢博主) 一,php:// 访问输入 ...
- HDU_5414 CRB and String 【字符串】
一.题目 CRB and String 二.分析 对于这题,读懂题意非常重要. 题目的意思是在$s$的基础上,按题目中所描述的步骤,即在$s$中任意选择一个字符$c$,在这个字符后面添加一个不等于$c ...
- html Ajax连接.NET Ashx
Html代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <m ...