javascript数据结构 -- 优先级队列

146 阅读1分钟

优先级队列

优先级队列相比于普通队列,其特殊之处表现在:队列中的每个元素都有一个优先级,新插入的新元素不一定在队尾,而是根据其优先级确定正确的位置。

相关概念

优先级:指的是队列中元素的权重,是排序的依据。

定义及特点

相比于普通队列,元素不遵守先进先出的原则,而是根据优先级/权重决定顺序。

常见应用场景

  • 飞机登机
  • 急诊排队

优先级队列的实现

通过继承队列,然后在子类中只需要改写入队列的enqueue方法即可,也就是说按照优先级排序这种行为只发生在插入新元素的时候。

队列方法

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

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

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

  // 数组直接转队列
  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);
  }
}

class PriorityQueue<T> extends Queue<T> {
  // @ts-ignore
  items: QueueElement[] = [];
  static QueueElement = class<T> {
    constructor(public value: T, public priority: number) {}
  };
  // @ts-ignore
  enqueue(value: T, priority: number): void {
    const element = new PriorityQueue.QueueElement(value, priority);
    if (this.isEmpty()) {
      this.items.push(element);
    } else {
      let insertIndex = this.size();
      while (insertIndex) {
        const currentPriority = this.items[insertIndex - 1].priority;
        if (priority > currentPriority) {
          break;
        } else {
          insertIndex--;
        }
      }

      this.items.splice(insertIndex, 0, element);
    }
  }

  toString(join: string): string {
    let rst = "";
    this.items.forEach((item) => {
      rst += item.value.concat(join);
    });
    return rst;
  }
}

const q1 = new PriorityQueue<string>();
q1.enqueue("a", 1);
q1.enqueue("b", 5);
q1.enqueue("c", 3);
q1.dequeue();
q1.enqueue("d", 4);
q1.enqueue("e", 2);
console.log(q1.toString(">>>")); // e>>>c>>>d>>>b>>>