数据结构(队列实现篇)

news/2024/7/5 2:12:20

在数据结构与算法中,队列queue是一种受限的线性储存结构,特殊之处在于它只允许在表的前端front进行删除操作,而在表的后端rear进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。遵循先进先出FIFO的规则。

队列结构示意图

队列结构使用

生活中很多地方使用到队列,例如医院门诊看病就是按挂号的号数来排队就诊;公司里面的打印机是按文件发送的顺序进行打印。

在编程中,队列常用作消息发送。例如消息发送队列。待发送的消息依次入队列,待一个消息出队列发送完毕,才会进行下一个消息出队列进行发送。

实现普通队列结构的功能

  • push(element):push是入队列操作,其中element是需要进队列的元素,返回操作成功与否布尔值。
  • shift():shift移除队列front元素操作,返回移除的移除元素。
  • size():获取栈中的队列元素数量,返回一个数字。
  • isEmpty():判断队列是否为空,返回一个布尔值。
  • peek():返回队头元素,但不移除栈顶元素。
  • bottom():返回队尾元素。
  • clear():清除所有队列元素,返回操作成功与否布尔值。

进队列与出队列流程

ES6 队列结构代码

    class Queue{constructor(){this.lists = [];}size(){return this.lists.length;}isEmpty(){return this.lists.length === 0;}peek(){return this.lists[0];}bottom(){const topIndex = this.size() -1;return this.lists[topIndex];}push(element){this.lists.push(element);return true;}shift(){return this.lists.shift();}clear(){this.lists = [];return true;}toString(){let result = "";this.lists.forEach(value=>{result = result + ""+value;});return result;}}
复制代码

ES5 队列结构代码

通过ES5把功能函数可以绑定在对象的实例上,也可以把功能函数加在函数的原型链上

    function Queue(){this.lists = [];}Queue.prototype.push = function(element){this.lists.push(element);return true;}Queue.prototype.shift = function(){return this.lists.shift();}Queue.prototype.clear = function(){this.lists = [];return true;}// 返回队头元素Queue.prototype.peek = function(){return this.lists[0];}Queue.prototype.size = function(){return this.lists.length;}Queue.prototype.isEmpty = function(){return this.lists.length === 0;}Queue.prototype.bottom = function(){var topIndex = this.size() -1;return this.lists[topIndex];}Queue.prototype.toString = function(){var result = "";for(var i=0;i<this.lists.length;i++){result = result + '' +this.lists[i];}return result;}
复制代码

实现优先队列结构的功能

上面实现的是普通队列情况,在日常生活中总遇到需要紧急处理的情况,例如银行VIP客户,急诊室危急病人,紧急文件。这时候需要优先处理这种情况。

优先队列和普通队列的不同主要在优先队列的每一个元素都具有一个权值,代表该元素的优先权大小。还有就是根据权值大小插入队列之中。

ES6 最大优先队列结构代码

    class Node {constructor(element, prority) {this.element = element;this.prority = prority;}}class Queue {constructor() {this.lists = [];}size() {return this.lists.length;}isEmpty() {return this.lists.length === 0;}peek() {return this.list[0];}bottom() {const topIndex = this.size() - 1;return this.lists[topIndex];}//插入队列append(node) {//当队列为空时if (!this.lists.length) {this.lists.push(node);return true;} else {for(let i=0;i<this.lists.length;i++){if(this.lists[i]["prority"] < node.prority){this.lists.splice(i,0,node);return true;}}this.lists.push(node);}}shift() {return this.lists.shift();}clear() {this.lists = [];return true;}toString() {let result = "";this.lists.forEach(value => {result = result + "" + value;});return result;}}const q = new Queue();q.append(new Node(1, 1));q.append(new Node(2, 2));q.append(new Node(5, 3));q.append(new Node(4, 2));console.log(JSON.stringify(q));
复制代码

ES5 最大优先队列结构代码

通过ES5把功能函数可以绑定在对象的实例上,也可以把功能函数加在函数的原型链上

    function Node(element,prority){this.element = element;this.prority = prority;}function Queue(){this.lists = [];}Queue.prototype.append = function(node){//当队列为空时if(this.lists.length == 0){this.lists.push(node);return true;}for(var i=0;i<this.lists.length;i++){if(node.prority > this.lists[i]["prority"]){this.lists.splice(i,0,node);return true;}}this.lists.push(node);}Queue.prototype.shift = function(){return this.lists.shift();}Queue.prototype.clear = function(){this.lists = [];return true;}// 返回队头元素Queue.prototype.peek = function(){return this.lists[0];}Queue.prototype.size = function(){return this.lists.length;}Queue.prototype.isEmpty = function(){return this.lists.length === 0;}Queue.prototype.bottom = function(){var topIndex = this.size() -1;return this.lists[topIndex];}Queue.prototype.toString = function(){var result = "";for(var i=0;i<this.lists.length;i++){result = result + '' +this.lists[i];}return result;}
复制代码

循环队列结构图

循环队列就是把队头元素出队列后,再入队列。击鼓传花就是用到了循环队列的原理

循环队列代码

循环队列主要实现代码如下

  class SqQueue {constructor(length) {this.queue = new Array(length + 1)// 队头this.first = 0// 队尾this.last = 0// 当前队列大小this.size = 0}enQueue(item) {// 判断队尾 + 1 是否为队头// 如果是就代表需要扩容数组// % this.queue.length 是为了防止数组越界if (this.first === (this.last + 1) % this.queue.length) {this.resize(this.getLength() * 2 + 1)}this.queue[this.last] = itemthis.size++this.last = (this.last + 1) % this.queue.length}deQueue() {if (this.isEmpty()) {throw Error('Queue is empty')}let r = this.queue[this.first]this.queue[this.first] = nullthis.first = (this.first + 1) % this.queue.lengththis.size--// 判断当前队列大小是否过小// 为了保证不浪费空间,在队列空间等于总长度四分之一时// 且不为 2 时缩小总长度为当前的一半if (this.size === this.getLength() / 4 && this.getLength() / 2 !== 0) {this.resize(this.getLength() / 2)}return r}getHeader() {if (this.isEmpty()) {throw Error('Queue is empty')}return this.queue[this.first]}getLength() {return this.queue.length - 1}isEmpty() {return this.first === this.last}resize(length) {let q = new Array(length)for (let i = 0; i < length; i++) {q[i] = this.queue[(i + this.first) % this.queue.length]}this.queue = qthis.first = 0this.last = this.size}
}
复制代码

终于水完这篇数据结构队列

Github地址: github.com/Harhao


http://lihuaxi.xjx100.cn/news/243929.html

相关文章

2016.01.04 论文改重

今天的任务是修改查重的问题&#xff0c;另外加入参考文献。 其中&#xff0c;上午的时间完成论文查重。 下午的时间完成参考文献的丰富和标记。 晚上的时间完成DOM基础&#xff08;李炎恢&#xff09;的学习 预计晚上八点到晚上十点 优先级&#xff1a;论文查重&#xff0c;参…

java连接mysql数据库(jsp显示和控制台显示)

很多事情&#xff0c;在我们没有做之前我们觉得好难&#xff0c;但是只要你静下心来&#xff0c;毕竟这些都是人搞出来的&#xff0c;只要你是人&#xff0c;那就一定可以明白。 配置&#xff1a;JDK1.8&#xff0c;MySQL5.7&#xff0c;eclipse&#xff1a;Neon Release (4.6.…

汇编与反汇编

本来是打算学习linux的&#xff0c;然后做运维。可是在学习的过程中总是感觉不痛快&#xff0c;抓不住重点&#xff0c;就向下学c语言&#xff1b;学习c语言又发现有许多知识点抓不住重点&#xff0c;就向下学习汇编、学习微机原理&#xff0c;发现汇编与反汇编才是学习计算机科…

Tslib移植与分析【转】

转自&#xff1a;http://blog.csdn.net/water_cow/article/details/7215308 目标平台&#xff1a;LOONGSON-1B开发板&#xff08;mips32指令集&#xff09;编译平台&#xff1a;x86PC--VMware6.5--Ubuntu10.04&#xff08;下面简称“ubuntu系统”&#xff09; 或&am…

总结:如何使用redis缓存加索引处理数据库百万级并发

前言&#xff1a;事先说明&#xff1a;在实际应用中这种做法设计需要各位读者自己设计&#xff0c;本文只提供一种思想。准备工作&#xff1a;安装后本地数redis服务器&#xff0c;使用mysql数据库&#xff0c;事先插入1000万条数据&#xff0c;可以参考我之前的文章插入数据&a…

Linux----进程概念

程序 : 程序指的是一系列有逻辑, 有顺序结构的指令.进程 : 进程从两个角度来说:1 用户角度: 进程从用户角度来说就是运行中的程序2 操作系统的角度: 进程是操作系统对运行中程序的描述信息, 叫做进程描述符(程序控制块)简称PCBPCB : 在Linux下PCB指的是在内核中的task_struct 结…

DOMContentLoaded 与onload区别以及使用

一、何时触发这两个事件&#xff1f; 1、当 onload 事件触发时&#xff0c;页面上所有的DOM&#xff0c;样式表&#xff0c;脚本&#xff0c;图片&#xff0c;flash都已经加载完成了。 2、当 DOMContentLoaded 事件触发时&#xff0c;仅当DOM加载完成&#xff0c;不包括样式表&…

移动端开发者眼中的前端开发流程变迁与前后端分离

写在最开始 这是一篇面向移动端开发者的科普性文章&#xff0c;从前端开发的最初流程开始&#xff0c;结合示范代码&#xff0c;讨论开发流程的演变过程&#xff0c;希望能覆盖一部分前端开发技术栈&#xff0c;从而对前端开发的相关概念形成初步的认识。 本文会提供一些示范代…