首页 > 其他分享 >队列-单端队列

队列-单端队列

时间:2024-04-08 18:45:45浏览次数:30  
标签:count obj 队列 队首 元素 单端 frontIndex

队列和栈非常类似, 栈的一端是封闭的, 类似一口深井, 遵循先进后出原则 FILO.

队列则两端是放开的, 抽象于现实世界的排队现象, 遵循先进先出原则 FIFO.

队列在尾部进行元素的新增, 称为 "入队", 然后从头部移除元素, 成为 "出队". 生活中我们去坐火车进站检票, 去某个机关办理业务, 去用打印机印一叠文件等都是需要 "排队", 先来的先处理, 后来的往后站, 不允许插队哦.

创建队列

最简单方式可直接用 js 数组实现, 队尾用 arr.push(), arr.pop() , 队首用 arr.unshift(), arr.shift()

但从元素获取层面希望能更高效, 还是觉得用 js对象 来实现更合适一些呢.

class Queue {
  constructor() {
    this.count = 0  // 控制队列大小, 非长度
    this.fontIndex = 0  // 队首第一个元素索引
    this.obj = {}
  }
}

然后是要给队列声明一些常用方法

  • enqueue () 向队尾添加元素
  • dequeue () 向队首移除元素, 并返回
  • peek () 返回队首元素
  • isEmpty () 检查是否为空队列, 返回 true 或者 false
  • size () 返回队列的元素个数, 即队列长度, 类似数组的 length

元素入队

即元素必须要从队尾进行添加, 因为用的底层是 JS对象, 即用 count 作为键, 添加后自增 1 即可.

class Queue {
  constructor() {
    this.count = 0 
    this.frontIndex = 0  
    this.obj = {}
  }
  // 元素入队
  enqueue(item) {
    this.obj[this.count] = item 
    this.count += 1
  }
}

队列长度

即队列中元素个数, 即用队列的长度 减去 队首元素的索引即可, 当这个值为0 , 则说明是空队列了.

class Queue {
  constructor() {
    this.count = 0 
    this.frontIndex = 0  
    this.obj = {}
  }
  // 队列长度
  size() {
    return this.count - this.frontIndex
  }
  // 队列是否为空
  isEmpty() {
    this.size() == 0
  }
}

还是来简单模拟一下,直观理解一波这个长度的计算.

假设左边是队尾, 右边是队首, 而且是有序的

先入队a: { 0:a },
再入队b: { 1:b,  0:a },
再入队c: { 2:c, 1:b,  0:a }

此时的     this.count = 3;  
队首索引是: this.frontIndex = 0

根据先进先出, 对 a 进行出队

此时到对首元素是0, 动态表示为 obj[this.frontIndex], 值是 a
然后进行删除后, 此时的队列是 { 2:c, 1:b }, 即当前队首元素索引 从 0 变到 1
动态表示即 this.frontIndex + 1 表示此时队首的元素

元素出队

只要弄清楚了如何计算队列长度, 非空下的 frontIndex 就是队首长度, 删掉它即可.

class Queue {
  constructor() {
    this.count = 0 
    this.frontIndex = 0  
    this.obj = {}
  }
  // 队列是否为空
  isEmpty() {
    this.count - this.frontIndex == 0
  }
  // 元素出队
  dequeue() {
    if (this.isEmpty()) return undefined 

    let frontItem = this.obj[this.frontIndex]
    delete this.obj[this.frontIndex]

    this.frontIndex += 1 // 更新队首元素索引
    return frontItem
  }
}

清空队列元素

粗暴方式是直接指向空, 或者一直进行 dequeue() 直到返回 undefined 为止.

  // 清空队列
  clear() {
    this.obj = {}
    this.frontIndex = 0
    this.count = 0
  }
}

查看队首元素和全队列

队首就是索引为 this.frontIndex 的值, 查看全部可以类似栈封装一个 toString 方法

class Queue {
  constructor() {
    this.count = 0 
    this.frontIndex = 0  
    this.obj = {}
  }
  // 查看队首元素
  peek() {
    if (this.isEmpty()) return undefined
    return this.obj[this.frontIndex]
  }
  // 查看全队列
  toString() {
    if (this.isEmpty()) return undefined

    let objString = `${this.obj[this.frontIndex]}`
    for (let i = this.frontIndex + 1; i < this.count; i++) {
      objString = `${objString}, ${this.obj[i]}`
    }
    return objString
  }
}

这样以来,我们的队列就基本建好了, 然后我们来整体测试一波

class Queue {
  constructor() {
    this.count = 0 
    this.frontIndex = 0  
    this.obj = {}
  }
  // 元素入队
  enqueue(item) {
    this.obj[this.count] = item 
    this.count += 1
  }
  // 队列长度
  size() {
    return this.count - this.frontIndex
  }
  // 队列是否为空
  isEmpty() {
    this.count - this.frontIndex == 0
  }
  // 元素出队
  dequeue() {
    if (this.isEmpty()) return undefined 

    let frontItem = this.obj[this.frontIndex]
    delete this.obj[this.frontIndex]

    this.frontIndex += 1 // 更新队首元素索引
    return frontItem
  }
  // 清空队列
  clear() {
    this.obj = {}
    this.frontIndex = 0
    this.count = 0
  }
  // 查看队首元素
  peek() {
    if (this.isEmpty()) return undefined
    return this.obj[this.frontIndex]
  }
  // 查看全队列
  toString() {
    if (this.isEmpty()) return undefined

    let objString = `${this.obj[this.frontIndex]}`
    for (let i = this.frontIndex + 1; i < this.count; i++) {
      objString = `${objString}, ${this.obj[i]}`
    }
    return objString
  }
}


// test 
const queue = new Queue()

queue.enqueue('youge')
queue.enqueue('yaya')
queue.enqueue('jack')

// 检验入队
console.log('此时的队列是: ', queue.toString());
console.log('队列长度是: ', queue.size());
console.log('队首元素是: ', queue.peek());

// 检验出队
console.log('出队的元素是: ', queue.dequeue());

console.log('此时的队列是: ', queue.toString());
console.log('队列长度是: ', queue.size());
console.log('队首元素是: ', queue.peek());

// 剩下元素出队
console.log('出队的元素是: ', queue.dequeue());
console.log('出队的元素是: ', queue.dequeue());

// 空了
console.log('此时的队列是: ', queue.toString());
console.log('队列长度是: ', queue.size());
console.log('队首元素是: ', queue.peek());

查看一下结果:

PS F:\algorithms> node queue.js

此时的队列是:  youge, yaya, jack
队列长度是:  3
队首元素是:  youge

出队的元素是:  youge
此时的队列是:  yaya, jack
队列长度是:  2
队首元素是:  yaya

出队的元素是:  yaya
出队的元素是:  jack

此时的队列是:  undefined
队列长度是:  0
队首元素是:  undefined

这样就实现了一个单端的队列, 后面接着会再来实现一个双端的队列哦.

标签:count,obj,队列,队首,元素,单端,frontIndex
From: https://www.cnblogs.com/chenjieyouge/p/18122288

相关文章

  • Kafka、ActiveMQ、RabbitMQ、RocketMQ四大消息队列优劣对比与选择指南
    在分布式系统架构中,消息队列(MessageQueue,MQ)扮演着至关重要的角色,它作为异步通信的核心组件,能够实现系统解耦、削峰填谷、数据缓冲等功能。本文将聚焦于四大主流消息队列——Kafka、ActiveMQ、RabbitMQ、RocketMQ,深度剖析它们各自的优缺点,并在最后提供一份详尽的选择指南,以助......
  • 如何使用Java和RabbitMQ实现延迟队列(方式二)?
    前言昨天写了一篇关于Java和RabbitMQ使用插件实现延迟队列功能的文章,今天来讲下另外一种方式,不需要RabbitMQ的插件。前期准备,需要安装好docker、docker-compose的运行环境。需要安装RabbitMQ的可以看下面这篇文章。如何使用PHP和RabbitMQ实现消息队列?-CSDN博客使用RabbitM......
  • 如何使用Java和RabbitMQ实现延迟队列?
    前言今天我们使用Java和RabbitMQ实现消息队列的延迟功能。前期准备,需要安装好docker、docker-compose的运行环境。需要安装RabbitMQ的可以看下面这篇文章。如何使用PHP和RabbitMQ实现消息队列?-CSDN博客今天讲的是依赖RabbitMQ的延迟插件实现消息队列的延迟功能。如何安装......
  • Offer必备算法22_优先级队列_堆_四道力扣题详解(由易到难)
    目录①力扣1046.最后一块石头的重量解析代码②力扣703.数据流中的第K大元素解析代码③力扣692.前K个高频单词解析代码④力扣295.数据流的中位数解析代码本篇完。①力扣1046.最后一块石头的重量1046.最后一块石头的重量难度简单有一堆石头,每块石头的重......
  • java中的栈和队列
    java中的栈和队列栈特点:先进后出插入和删除只能在一段进行(栈顶),另一端称为(栈底)插入和删除的时候时间复杂度都是最理想的O(1)java中提供了一个类:Stack,并且实现了泛型方法:empty()检测栈是否为空peek()查看头部元素,不删除pop()删除头部元素,并返回删除的元素push()将该元素......
  • 迷宫问题(C++): 最短路径计算(队列)&& 路径输出(栈)(附一个易错点~)
    迷宫问题大同小异,先直接上代码ba~:#include<bits/stdc++.h>//包含标准库头文件usingnamespacestd;//使用标准命名空间#definesize100//定义迷宫大小typedefstruct{//定义结构体STUintx,y;}STU;queue<STU>q;//定义队列qintn,bd[size][size]={0}......
  • 队列链式实现
    链式存储实现的队列:链队列typedefstructLinkNode{//链式队列结点ElemTypedata;structLinkNode*next;}LinkNode;typedefstruct{//链式队列LinkNode*front,*rear;//队列的队头和队尾指针}LinkQueue;带头结点:不......
  • 二分+单调队列优化 2
    7-7列车调度(天梯赛选拔赛)https://pintia.cn/problem-sets/1768624240956489728/exam/problems/1768624240990044166?type=7&page=0火车站的列车调度铁轨的结构如下图所示。两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以......
  • 二分+单调队列思想
    [AHOI2018初中组]分组(洛谷P4447)题目描述小可可的学校信息组总共有\(n\)个队员,每个人都有一个实力值\(a_i\)。现在,一年一度的编程大赛就要到了,小可可的学校获得了若干个参赛名额,教练决定把学校信息组的\(n\)个队员分成若干个小组去参加这场比赛。但是每个队员都不会愿意与......
  • 单调栈 and 单调队列学习笔记
    单调栈and单调队列学习笔记本文均以维护单调递增的栈/队列举例。本篇代码合集以后在写动态规划单调队列/单调栈优化的时候,这两个东西会合并。单调栈本质上就是模拟。假设要维护一个单调递增的栈,那么对于一个元素进来了,在栈顶的所有比他小的数我全部都要踢出去,不然就不满足......