美文网首页让前端飞Web 前端开发
前端中的数据结构——队列篇

前端中的数据结构——队列篇

作者: ac68882199a1 | 来源:发表于2018-01-07 19:25 被阅读263次

队列是数据结构中的一种,它与实际生活中的排队相似:在一条队伍中,先来的人总是能够先得到服务,后来的人只能排在队伍末尾等候。队列也是一样,它符合先进先出 FIFO(First Input First Out)的顺序。

那队列在我们的代码中有什么样的作用呢?还是以排队为例,当我们需要做一个排队系统时,就可以用到了,具体如下:

某个商品销售异常火爆,为了保证系统的稳定,所以限制购买的用户同时最多只能有100人,每当一个用户购买成功,下一个用户才可以进入购买者的队伍。这样既保证系统稳定,又提高了用户的购买体验(在等待期间可以提醒用户前面还有多少人)。

那队列在前端中有哪些可以使用到的地方呢?这个我们最后再说,先来看队列的 js 实现。

队列的类型

队列有两种类型:一种是和日常排队类似的队列,叫做普通队列;另一种叫做环形队列。

对于一个队列来说,有队头和队尾,以及容量。

从上图可以看出来,普通队列的队头和队尾是分开的,当队头的元素离开队列后,下一个元素就会成为队头,而新加入的元素会跟随在原本的队尾之后,成为新的队尾。

而对于环形队列来说,当只有一个元素时,队头队尾是同一个元素;当队列容量已满时,队头和队尾是连接在一起的;当队头的元素离开后,下一个元素会成为队头,而新的元素则会插入原本队头的位置成为新的队尾。

在容量确定的情况下,普通队列前面的元素离开后,对应的内存就会被空置,而在环形队列中,前面的元素离开,新的元素就会占据原来的内存。相比之下,就容量而言,环形队列具有更高的内存利用率,可以减小内存的开支消耗。

实现一个环形队列

环形队列具有的属性

首先,在上文中提到的队头、队尾以及容量这三个属性是必不可少的;除此之外,还需要:

  1. 队列长度的属性,因为队列的实际长度可能并不会达到队列容量的大小
  2. 队列中用来存放元素的数组(为什么是?如果说队列与 JS 中的哪一种数据类型最相似的话,那数组肯定是最好的答案)

环形队列具有的方法

  1. 将元素插入队尾的方法
  2. 将队头移出队列的方法
  3. 清空队列的方法
  4. 判断队列是否已满(如果已满,则不能再插入元素)
  5. 判断队列是否为空(如果为空,则不能移除元素)
  6. 遍历所有元素的方法
  7. ……(你还可以根据你的实际需要增加方法,如定时从队列中执行任务、增加任务等)

代码实现

// 环形队列
class CircleQueue {
  constructor (capacity = 0) {
    this.capacity = capacity // 容量
    this.clean()
  }

  // 清空队列
 clean () {
    this.head = 0 // 队头
    this.tail = 0 // 队尾
    this.length = 0 // 队列长度
    this.queue = []
  }

  // 将元素添加到队尾
  push (element) {
    // 判断队列是否已满
    // 如果已满则返回 false
    if (this.isFull()) return false
    // 将元素添加进队尾
    this.queue[this.tail] = element
    this.length++
    // 修改队尾
    // 先将原队尾+1并对容量取余,防止队尾超出数组长度,实现环形队列的队尾
    this.tail = ++this.tail % this.capacity
    return this.length
  }

  // 将元素移出队列
  shift () {
    // 判断队列是否为空
    // 如果为空则返回
    if (this.isEmpty()) return
    // 获取对头并将队头移除(置空)
    let temp = this.queue[this.head]
    this.queue[this.head] = null
    this.length--
    // 修改队头
    // 先将原队头+1并对容量取余,防止队头超出数组长度,实现环形队列的队头
    this.head = ++this.head % this.capacity
    return temp
  }

  // 判断是否已满
  isFull () {
    if (this.length === this.capacity) return true
    return false
  }

  // 判断是否为空
  isEmpty () {
    if (this.length === 0) return true
    return false
  }

  // 遍历所有元素
  travel (cb) {
    for (let i = this.head; i < this.length + this.head; i++) {
      cb && cb(this.queue[i % this.capacity])
    }
  }
}

Demo on github

队列在前端中的应用

我们知道前端中的任务执行就是通过队列的方式进行的,那队列在前端中还能用来干嘛呢?下面就是一个实际的例子:

通过一个专门用来存放请求的队列,实现请求发起的前后顺序(先进入的先发起)及当前页面中同时发起请求的数量(进入队列的队列在发起的同时移出,请求结束后向队列中添加下一个请求),甚至可以通过队列实现请求的自动发起(这就需要对 demo 中的代码进行修改从而实现想要的功能)。

至于队列的其他应用,就需要我们在实际工作中去发掘啦!

扫码关注微信公众号【前端程序员的斜杠青年进化录】 微信扫码,给我赞赏一下~

相关文章

  • 前端中的数据结构——队列篇

    队列是数据结构中的一种,它与实际生活中的排队相似:在一条队伍中,先来的人总是能够先得到服务,后来的人只能排在队伍末...

  • JavaScript数据结构之队列

    接上篇-数据结构之栈 数据结构之---队列 1.队列的定义 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端...

  • 数据结构与算法 (队列实现篇)

    数据结构与算法 (队列实现篇) 在数据结构与算法中,队列(queue)是一种受限的线性储存结构,特殊之处在于它只允...

  • 数据结构-队列

    数据结构-队列 定义 队列(queue)在计算机科学中,是一种先进先出的线性表。它只允许在表的前端进行删除操作,而...

  • 前端常见数据结构小结

    常见数据结构的 JavaScript 实现 栈 队列 链表 集合 字典 哈希表 二叉树 图 前端与数据结构 数据结...

  • RocketMQ系列之理论基础

    消息队列 消息队列是利用了数据结构中先进先出的一种数据结构——队列来实现的,在当前大部分企业的系统架构中,作为中间...

  • 刷穿剑指offer-Day20-队列I 队列的使用与基础题型!

    队列的介绍 队列(queue)是一种简单、常用的数据结构,在上一章栈的学习中,我们已经提到了队列这种数据结构。 队...

  • Handler精讲

    讲解本技术点之前需要准备的技术点回顾 队列数据结构 数据结构-队列(queue) - CSDN博客 Java中的T...

  • 数据结构之"队列"

    队列 (常用数据结构之一) 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在...

  • JAVA基础——Queue集合

    Queue集合 Queue用于模拟队列这种数据结构,队列FIFO的容器。队列的头部保存在队列中存放时间最长的元素,...

网友评论

    本文标题:前端中的数据结构——队列篇

    本文链接:https://www.haomeiwen.com/subject/gdrmnxtx.html