# 队列
队列是遵循 FIFO(First In First Out)原则的一组有序的项。 队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的末尾。
# 队列的操作
enqueue(item(s)):向队列尾部添加一个(或多个)新的项dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素front():返回队列中第一个元素isEmpty():如果队列中不包含任何元素,返回true,否则返回falsesize():返回队列包含的元素个数print():打印队列元素
# 队列的实现
class Queue {
  constructor() {
    this._list = []
  }
  enqueue(...items) {
    this._list.push(...items)
  }
  dequeue() {
    return this._list.shift()
  }
  front() {
    return this._list[0]
  }
  size() {
    return this._list.length
  }
  isEmpty() {
    return this._list.length === 0
  }
  toString() {
    this._list.toString()
  }
  print() {
    console.log(this.toString())
  }
}
# 队列的使用
击鼓传花:
班里所有学生围成一圈,一个人负责击鼓。然后从某位同学手里开始向旁边的同学传一束花。鼓声停下的一刻,花落在谁手里,谁就出来表演节目。
修改游戏规则:
几个朋友围成一圈玩一个游戏,从某个人开始数数,数到某个数字的人自动淘汰,最后剩下的一个人会获得胜利,请问最后剩下的是原来在哪一个位置上的人?
function hotPotato(nameList, num) {
  const queue = new Queue()
  queue.enqueue(...nameList)
  while (queue.size() > 1) {
    for (let i = 0; i < num; i++) {
      queue.enqueue(queue.dequeue())
    }
    queue.dequeue()
  }
  return queue.dequeue()
}
const names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl']
const winner = hotPotato(names, 7)
console.log(`The winner is: ${winner}`) // The winner is: John
# 优先队列
在优先队列中,元素的添加和移除是基于优先级的。
优先队列可以简单的分为最小优先队列,其优先级的值较小的元素被放置在队列最前面(壹代表更高的优先级);最大优先队列则与之相反,把优先级的值较大的元素放置在队列最前面。
实现一个优先队列,有两种选项:设置优先级,然后在正确的位置添加元素;或者用入列操作添加元素,然后按照优先级移除它们。这里我们使用前面一种方式,其它的方法都不用改变,现在来修改一下入列方法。
class QueueElement {
  constructor(element, priority) {
    this.element = element
    this.priority = priority
  }
}
class PriorityQueue extends Queue {
  enqueue(element, priority) {
    const queueElement = new QueueElement(element, priority)
    const isInserted = this._list.some((item, index) => {
      // 数字越小, 优先级越高
      if (queueElement.priority < item.priority) {
        this._list.splice(index, 0, queueElement)
        return true
      }
      return false
    })
    if (!isInserted) {
      this._list.push(queueElement)
    }
  }
  print() {
    this._list.forEach(item => console.log(`${item.element} - ${item.priority}`))
  }
}
const priorityQueue = new PriorityQueue()
priorityQueue.enqueue('John', 2)
priorityQueue.enqueue('Jack', 1)
priorityQueue.enqueue('Camila', 1)
priorityQueue.print()
// Jack -       1
// Camila -       1
// John -       2
← 42. 接雨水 232. 用栈实现队列 →