前言

队列和栈非常类似,前面已经讲过了栈的实现与用法,现在我们来说说队列。

队列介绍

队列遵循FIFO(First In First Out,先进先出)原则的一组有序的项。

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

队列有顺序队列,还有其他修改版本的队列,比如:优先队列、循环队列。

顺序队列

顺序队列是队列的顺序存储结构,它是运算受限制的顺序表(线性表)。建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间,并设置两个指针进行管理。一个是队头指针front,它指向队头元素;另一个是队尾指针rear,它指向下一个入队元素的存储位置,如图所示。

生活中,各种排队现象。例如:排队买票,新来的人,排在队尾,相当于添加操作。队头的人先买票,买完票离开队列,相当于删除操作。而添加的操作却只能在队列的尾部进行,因此新来的人就只能排在队列的最后。

创建队列

队列中的元素,可以使用链表存储,也可以使用数组存储。我们使用数组来存储队列中的元素。


/** * 队列 * 我们使用数组来存储队列中的元素 * *=====队列的入队、出队示意图======== * * 出队 ----------------- 入队 * <--- A1,A2,A3,...,An <--- * ----------------- * *================================ */ export default class Queue { constructor() { this.items = []; } /** * 向队尾添加一个(或多个)新的元素 * @param {*} element 新元素 */ enqueue(element) { this.items.push(element) } /** * 移除队列的第一(即排在队列最前面的)项,并返回被移除的元素 */ dequeue() { // 根据队列的先进先出原则,使用shift方法 // shift方法会从数组中移除存储在索引为0的元素 return this.items.shift() } /** * 返回队列中的第一个元素--最先被添加,也将是最先被移除的元素。 * 队列不做任何变动(不移除元素,只返回元素信息) */
front() { return this.items[0] } /** * 清除队列中的所有元素 */ clear() { this.items = [] } /** * 如果队列中不包含任何元素,返回true,否则返回false */ isEmpty() { return this.items.length === 0 } /** * 返回队列包含的元素个数,与数组length属性类似 */ size() { return this.items.length } /** * 队列内容字符串化 */ toString() { return this.items.toString() } }

顺序队列应用

打印机,有一个打印队列,谁先进入队列,谁就先打印。


/** * 打印队列的内容 * @param {Array} queueArr 需要打印的数组 */ function print(queueArr) { let queue = new Queue() let s = '' /** * 检查参数类型是否为数组 */ if (queueArr instanceof Array) { /** * 将需要打印内容添加到队列 */ for (let i = 0; i < queueArr.length; i++) { queue.enqueue(queueArr[i]) } /** * 将队头的数据取出 */ while (!queue.isEmpty()) { s += queue.dequeue() + ', ' } s = s.substr(0, s.length - 2) } return s; }

更多内容请查看源码

优先队列

队列有顺序队列,还有其他修改版本的队列,比如:循环队列、优先队列

优先队列是顺序队列的修改版本,元素的添加和移除是基于优先级的。一个现实例子是,在银行排队办业务的顺序。VIP客户的优先级要高于普通客户的。另一个例子是医院的急诊科候诊室。医生会优先处理病情比较严重的患者。通常,护士会鉴别分类,根据患者病情的严重程度放号。

实现一个优先队列,有两种选项:

  1. 设置优先级,然后在正确的位置添加元素。(优先添加,正常出队)

  2. 用入列操作添加元素,然后按照优先级移除它们。(正常添加,优先出队)

优先队列的实现

我们在这里将会使用第一种方式,在正确的位置添加元素,因此可以对它们使用默认的出列操作。

queueElement.js 文件


// queueElement.js /** * 优先队列中的元素,包含元素和优先级 */ export default class QueueElement { /** * * @param {*} element 队列的元素 * @param {*} priority 优先级 */ constructor(element, priority) { this.element = element this.priority = priority } }

priorityQueue.js文件


// priorityQueue.js import QueueElement from "./queueElement"; /** * 最小优先队列 */ export default class PriorityQueue { constructor() { this.items = [] } /** * 在正确的位置添加元素 * @param {*} element 要添加的元素 * @param {Int32Array} priority 优先级 */ enqueue(element, priority) { let queueElement = new QueueElement(element, priority) let added = false for (let i = 0; i < this.items.length; i++) { // 当找到一个比要添加的元素的优先级更高的项时,将新元素插入到它之前。 if (queueElement.priority < this.items[i].priority) { this.items.splice(i, 0, queueElement) // 插入新元素 added = true break // 终止队列循环 } } // 当需要添加的元素优先级大于队列中的任何一个元素的时候,把该元素添加到队尾。 if (!added) { this.items.push(queueElement) } } /** * 打印队列中的元素(包含优先级) */ print() { for (let i = 0; i < this.items.length; i++) { console.log(`${i + 1} - ${this.items[i].element} - ${this.items[i].priority}`) } } /** * 移除队列的第一(即排在队列最前面的)项,并返回被移除的元素 */ dequeue() { // 根据队列的先进先出原则,使用shift方法 // shift方法会从数组中移除存储在索引为0的元素 return this.items.shift() } /** * 返回队列中的第一个元素--最先被添加,也将是最先被移除的元素。 * 队列不做任何变动(不移除元素,只返回元素信息) */ front() { return this.items[0] } /** * 清除队列中的所有元素 */ clear() { this.items = [] } /** * 如果队列中不包含任何元素,返回true,否则返回false */ isEmpty() { return this.items.length === 0 } /** * 返回队列包含的元素个数,与数组length属性类似 */ size() { return this.items.length } /** * 队列内容字符串化 */ toString() { return this.items.toString() } }

优先队列的应用


let priorityQueue = new PriorityQueue() priorityQueue.enqueue('wei', 2) priorityQueue.enqueue('qin', 3) priorityQueue.enqueue('world', 1) priorityQueue.enqueue('china', 1) priorityQueue.print()

输出结果


1 - wei - 1 2 - world - 1 3 - china - 1 4 - qin - 2

查看源码详情

循环队列

循环队列的一个例子就是击鼓传花的游戏。在这个游戏中,孩子们围成一个圆圈,把花尽快的传递给旁边的人。某一时刻传花停止,这个时候花在谁手里,谁就退出圆圈结束游戏。重复这个过程,直到只剩一个孩子(胜者)。

另一个类似的案例是,约瑟夫环问题

下面,我们以击鼓传花游戏来分析。

import Queue from "./queue-array";

export default class CircleQueue {

  constructor() {}

  hotPotato(nameList, num) {
// 利用顺序队列创建的队列,来完成循环队列
let queue = new Queue() for (let i = 0; i < nameList.length; i++) {
queue.enqueue(nameList[i])
} let eliminated = '';
while (queue.size() > 1) {
// 此过程将队列变成循环队列
for (let i = 0; i < num; i++) {
queue.enqueue(queue.dequeue());
}
eliminated = queue.dequeue();
console.log(eliminated + '在击鼓传花游戏中被淘汰')
}
// 返回最后胜利者
return queue.dequeue() } }

查看源码详情

以上所有的队列,都是在数组结构的基础上创建和应用的。

[完]

Javascript数据结构与算法--队列(顺序队列、优先队列、循环队列)的实现与用法的更多相关文章

  1. 为什么我要放弃javaScript数据结构与算法(第四章)—— 队列

    有两种结构类似于数组,但在添加和删除元素时更加可控,它们就是栈和队列. 第四章 队列 队列数据结构 队列是遵循FIFO(First In First Out,先进先出,也称为先来先服务)原则的一组有序 ...

  2. javascript 数据结构和算法读书笔记 > 第五章 队列

    队列是一种列表,但是它只能够在队尾插入元素,在队首删除元素.队列用于存储按照顺序排列的数据,先进先出.而栈则是后入栈的元素反而被优先处理. 实际中一般被应用在进程池.排队操作上面. 1. 队列的操作 ...

  3. JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)

    前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...

  4. javascript数据结构与算法---队列

    javascript数据结构与算法---队列 队列是一种列表,不同的是队列只能在队尾插入元素,在队首删除元素.队列用于存储按顺序排列的数据,先进先出,这点和栈不一样(后入先出).在栈中,最后入栈的元素 ...

  5. 重读《学习JavaScript数据结构与算法-第三版》- 第5章 队列

    定场诗 马瘦毛长蹄子肥,儿子偷爹不算贼,瞎大爷娶个瞎大奶奶,老两口过了多半辈,谁也没看见谁! 前言 本章为重读<学习JavaScript数据结构与算法-第三版>的系列文章,主要讲述队列数据 ...

  6. JavaScript数据结构与算法-队列练习

    队列的实现 // 队列类 function Deque () { this.dataStore = []; this.enqueueFront = enqueueFront; this.enqueue ...

  7. javascript数据结构与算法---检索算法(顺序查找、最大最小值、自组织查询)

    javascript数据结构与算法---检索算法(顺序查找.最大最小值.自组织查询) 一.顺序查找法 /* * 顺序查找法 * * 顺序查找法只要从列表的第一个元素开始循环,然后逐个与要查找的数据进行 ...

  8. 前端开发周报: CSS 布局方式方式与JavaScript数据结构和算法

    前端开发周报:CSS 布局方式与JavaScript动画库 1.常见 CSS 布局方式详见: 一些常见的 CSS 布局方式梳理,涉及 Flex 布局.Grid 布局.圣杯布局.双飞翼布局等.http: ...

  9. 为什么我要放弃javaScript数据结构与算法(第九章)—— 图

    本章中,将学习另外一种非线性数据结构--图.这是学习的最后一种数据结构,后面将学习排序和搜索算法. 第九章 图 图的相关术语 图是网络结构的抽象模型.图是一组由边连接的节点(或顶点).学习图是重要的, ...

随机推荐

  1. 数论ex

    数论ex 数学学得太差了补补知识点or复习 Miller-Rabin 和 Pollard Rho Miller-Rabin 前置知识: 费马小定理 \[ a^{p-1}\equiv 1\pmod p, ...

  2. [NOI2017]游戏

    题目描述 http://www.lydsy.com/JudgeOnline/upload/Noi2017D2.pdf 题解 如果说没有x的话,那么每一局只能有两种选择,可以描述为是/非,每条限制也可以 ...

  3. php 两个数组,若键相同,则值合并

    <?php $arr1 = array('9' => '4.08', '10' => '0.10', '11' => '4.08', '12' => '0.01'); $ ...

  4. Linux环境配置错误记录

    1.  pip install --special_version  pip10. 版本. 使用命令: python -m pip install pip== 其中, -m 参数的意思是将库中的pyt ...

  5. Day053--MySQL

    MySQL安装和基本管理https://www.cnblogs.com/majj/p/9160383.html 管理员模式运行cmd 打开终端,输入mysqld,打开服务端. 打开终端,输入mysql ...

  6. 第三周java学习总结

    学号 20175206 <Java程序设计>第三周学习总结 教材学习内容总结 本周为第四章的学习,分为以下几个方面: 1.包与代码组织 2.String类 3.对象创建 4.包装类 经过代 ...

  7. 转载:Linux命令之查看文件占用空间大小-du,df

    转载自:<du命令>-linux命令五分钟系列之三 du(disk usage),顾名思义,查看目录/文件占用空间大小 #查看当前目录下的所有目录以及子目录的大小$ du -h $ du ...

  8. Windows10搭建FTP服务

    1.启用Windows10 Ftp服务 打开控制面板->程序和功能->启用或关闭windows功能然后如图: 2.配置FTP用户 我的电脑->右击点击管理->本地用户和组 在A ...

  9. java基于redis事务的秒杀实现

    package com.vian.user.service; import org.junit.Test; import org.springframework.util.CollectionUtil ...

  10. js中对cookie的操作及json数据与cookie结合的用法

    cookie的使用 添加cookie 添加cookie:document.cookie = “key=value”; // 一次写入一个键值对 document.cookie = 'test1=hel ...