javascript数据结构 -- 队列

737 阅读2分钟

队列(Queue)

队列是除了栈之外的另外一种受限的线性结构(这里的线性结构指的是数组)

相关概念

  • 队头:队列的头部,队列中最先进入的元素放在此处,只允许在队头删除旧的元素。
  • 队尾:队列的尾部,队列中最后进入的元素放在此处,只允许在队尾添加新的元素。

定义及特点

  • 队列是另外一种受限的线性结构,受限表现在元素必须是先进先出的;
  • 具体来说,表现在其只允许在一端添加元素,而只在另一端删除元素。

常见应用场景

  • 在生活中的应用场景
    • 排队、打印文档
  • 在程序中的应用场景
    • 多个线程队列

队列的实现

基于javascript数组实现

队列方法

  • enqueue: 向队尾中添加元素
  • dequeue: 从队头取出元素
  • front: 返回队头元素,但不取出(类似于Stack中的peek方法)
  • isEmpty: 判断队列是否为空
  • size: 队列中元素个数
  • toString: 打印队列中的元素

typescript实现(javascript代码见代码块)

class Queue<Element> {
  items: Element[] = [];

  // 数组直接转队列
  init(arr: Element[]): void {
    this.items = [...arr];
  }

  // 进入队列
  enqueue(element: Element): void {
    this.items.push(element);
  }

  // 出队列
  dequeue(): Element | null {
    return this.isEmpty() ? null : this.items.shift()!;
  }

  // 查看队头元素
  front(): Element | null {
    return this.isEmpty() ? null : this.items[0];
  }

  // 判断队列是否为空
  isEmpty(): boolean {
    return this.items.length === 0;
  }

  // 返回元素个数
  size(): number {
    return this.items.length;
  }

  // 打印元素
  toString(join: string): string {
    return this.items.join(join);
  }
}

const q1 = new Queue<string>();
q1.enqueue("a");
q1.enqueue("b");
q1.enqueue("c");
q1.dequeue();
q1.enqueue("d");
q1.enqueue("e");
console.log(q1.toString(">>>")); // b>>>c>>>d>>>e

应用

应用一:击鼓传花

从第一个同学开始报数,依次报数1,2,3;报数为3的同学淘汰

// 使用队列数据结构解决击鼓传花问题
function passGame(nameList, num) {
  const q = new Queue();

  q.init(nameList);
  // 核心逻辑
  while (q.size() > 1) {
    for (let j = 0; j < num - 1; j++) {
      q.enqueue(q.dequeue());
    }
    q.dequeue();
    console.log(q.toString(">>>"));
  }
  return q.front();
}

const nameList = [
  "zs1", //
  "zs2", //
  "zs3", //
  "zs4", //
  "zs5", //
  "zs6", //
  "zs7",
  "zs8", //
  "zs9", //
  "zs10", //
  "zs11", //
];

console.log(passGame(nameList, 3)); // zs7