JavaScript(ES6)数据结构与算法——队列

认识队列

什么是队列

队列(Queue),它是一种受限的线性表,先进先出,受限之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作。

生活中类似队列的结构

生活中类似队列的场景有电影院,商场,一系列排队问题都可以归纳为队列,优先排队的人,优先处理。

还有一种就是打印机队列的问题:有五份文档需要打印,这些文档会按照次序放入到打印队列中。打印机依次会从队列中取出文档,优先放入的文档,优先被取出,并且对该文档进行打印,依次类推,直到队列中不再有新的文档。

队列的实现方式

  • 基于数组实现
  • 基于链表实现

队列有哪些操作

  • 向队列尾部添加一个或者多个新的项。enqueue(element)
  • 移除队列队头的第一项,并返回被移除的元素。dequeue()
  • 返回队列中第一个元素——最先被添加的元素,队列不做任何操作。front()
  • 如果队列中不包含任何元素,返回true,否则返回false。isEmpty()
  • 返回队列包含的元素个数,与数组的length属性类似。size()
  • 将队列中的内容,转换为字符串

基于数组封装队列

class Queue {
  constructor() {
    this.items = [];
  }

  // - 向队列尾部添加一个或者多个新的项。enqueue(element)
  enqueue(element) {
    this.items.push(element);
  }
  // - 移除队列队头的第一项,并返回被移除的元素。dequeue()
  dequeue() {
    return this.items.shift;
  }
  // - 返回队列中第一个元素——最先被添加的元素,队列不做任何操作。front()
  front() {
    if (this.isEmpty()) return null;
    return this.items[0];
  }
  // - 如果队列中不包含任何元素,返回true,否则返回false。isEmpty()
  isEmpty() {
    return this.items.length === 0;
  }
  // - 返回队列包含的元素个数,与数组的length属性类似。size()
  size() {
    return this.items.length;
  }
}

module.exports = new Queue();

测试

const queue = require("./queue");

queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
queue.enqueue(4);
queue.enqueue(5);

console.log(queue.items);
console.log(queue.dequeue());
console.log(queue.items);
console.log(queue.front());

在这里插入图片描述

队列结构的应用

击鼓传花

游戏规则:

  • 所有同学围成一个圈,从某位同学手里开始向旁边的同学传一朵花,这个时候一位同学在击鼓,当鼓声停止时,花在谁的手里,谁就表演节目。

为了更好理解队列结构的应用我们修改一下游戏规则:

  • 几个同学围成一个圈,开始数数,数到某个数字的人自动淘汰,最后剩下的这个人会获得胜利,请问最后剩下的是原来哪一个位置上的人。

对于这个问题的解决可以封装一个基于队列的函数,设置两个参数,一个是人名的一组数据,一个是淘汰的数字,返回结果是最后胜利的人名

const queue = require("../queue");

module.exports = function passGame(nameList, num) {
  for (let i = 0; i < nameList.length; i++) {
    queue.enqueue(nameList[i]);
  }

  while (queue.size() > 1) {
    for (let i = 0; i < num - 1; i++) {
      queue.enqueue(queue.dequeue());
    }
    queue.dequeue();
  }
  return queue.front();
};

测试

const passGame = require("../application/passGame");

console.log(passGame(["tom", "lilei", "hanmeimei", "wangbadan"], 4));

在这里插入图片描述

*优先级队列

优先级队列的特点:

  • 普通的队列插入一个元素,数据会被放在队尾,并且需要前面所有的元素都处理完成之后才会处理后面的数据。

  • 但是优先级队列,在插入一个元素的时候会考虑该数据的优先级,和其他数据优先级进行比较,比较完成后,可以得出这个元素在队列中正确的位置,其他的处理方式和基本的队列的处理方式一样。

优先级队列的应用

  • 头等舱和商务舱乘客的优先级要高于经济舱乘客。在有些国家,老年人和孕妇登机时也会享有高于其他乘客的优先级。

  • 在医院,医生会优先处理病情比较严重的患者

  • 在计算机中,我们可以通过优先级队列来重新排序队列中任务的顺序,比如每个线程处理的任务重要程度不同,我们可以通过优先级的大小,来决定该线程在队列中被处理的次序。

封装优先级队列

可以通过继承的方式来实现优先级队列,需要重写的方法就是enqueue方法,也就是向队列中添加元素的方法

class QueueElement {
  constructor(element, priority) {
    this.element = element;
    this.priority = priority;
  }
}
class PriorityQueue extends Queue {
  enqueue(element, priority) {
    const queueElement = new QueueElement(element, priority);

    if (this.isEmpty()) {
      this.items.push(queueElement);
    } else {
      let added = false;
      for (let i = 0; i < this.items.length; i++) {
        if (this.items[i].priority > queueElement.priority) {
          this.items.splice(i, 0, queueElement);
          added = true;
          break;
        }
      }
      if (!added) {
        this.items.push(queueElement);
      }
    }
  }
}

// module.exports = new Queue();
module.exports = new PriorityQueue();

测试

const priorityQueue = require("../queue");

priorityQueue.enqueue("A", 100);
priorityQueue.enqueue("B", 90);
priorityQueue.enqueue("C", 500);
priorityQueue.enqueue("D", 80);

console.log(priorityQueue.items);

在这里插入图片描述


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值