Skip to content

队列是一种操作受限的线性数据结构

  • 一组有序的数据,操作受限的数据结构
  • 先进先出

queue

接口

typescript
// 队列接口
interface QueueInterface<T> {
  items: T[];                                     // 队列所有元素
  head: () => T | undefined;                      // 队列第一个
  size: () => number;                             // 队列总长度
  isEmpty: () => boolean;                         // 队列是否为空
  toString: () => string;                         // toString
  clear: () => void;                              // 清空队列
  enqueue: (value: T, priority?: number) => void; // 入列
  dequeue: () => T | void;                        // 出列
}

// 升序排序的优先级队列
// 优先级的队列与普通队列不同的地方在于:
// 元素不是根据执行的先后顺序排列, 而是根据优先级顺序来进行排列操作
interface PriorityQueueElement<T> {
  value: T;
  priority: number;
}

用抽象类来抽取公共方法

typescript
/**
 * 用抽象类来实现一些逻辑高度重合的方法
 */
export default abstract class QueueAbstract<T> implements QueueInterface<T> {
  public items: T[] = [];

  /**
   * 查看队列的第一个元素(并不执行出列操作)
   * @returns T | undefined
   */
  public head() {
    return this.items.length > 0 ? this.items[0] : undefined;
  }

  /**
   * 队列的长度(元素的个数)
   * @returns number
   */
  public size(): number {
    return this.items.length;
  }

  /**
   * 队列是否为空
   * @returns boolean
   */
  public isEmpty(): boolean {
    return this.size() === 0;
  }

  /**
   * 清空队列
   */
  public clear() {
    this.items = [];
  }

  /**
   * 字符串序列化队列
   * @returns string
   */
  public toString() {
    return "[" + this.items.toString() + "]";
  }

  /**
   * 默认实现,可以覆盖(出列)
   * @returns
   */
  public dequeue() {
    return this.items.shift();
  }

  /**
   *
   * @param args
   */
  abstract enqueue(value: T, priority?: number): void;
}

普通队列

typescript
import QueueAbstract from "./QueueAbstract";

/**
 * 最简单的队列
 */
export default class Queue<T> extends QueueAbstract<T> {
  /**
   * 从其他可迭代数据从提取元素生成队列
   * @param items 队列元素
   * @returns
   */
  public static from<U>(items: Array<U> | Set<U>): Queue<U> {
    const queue = new Queue<U>();
    for (const item of items) {
      queue.enqueue(item);
    }
    return queue;
  }

  /**
   * 入列
   * @returns Queue<T>
   */
  public enqueue(item: T) {
    this.items.push(item);
    return this;
  }
}

优先级队列

typescript
import QueueAbstract from "./QueueAbstract";

/**
 * 带有优先级的队列
 */
export default class PriorityQueue<T> extends QueueAbstract<PriorityQueueElement<T>> {
  /**
   * 创建带有优先级的队列元素
   * @param value T
   * @param priority
   * @returns PriorityQueueElement<T>
   */
  private createPriorityQueueElement(value: T, priority: number): PriorityQueueElement<T> {
    return {
      value,
      priority,
    };
  }

  /**
   * 入列: 按照元素的优先级入列
   * @param value
   * @param priority
   * @returns
   */
  /* @ts-ignore */
  public enqueue(value: T, priority: number): void {
    const element = this.createPriorityQueueElement(value, priority);

    // 插入到最前
    if (this.isEmpty() || priority < (this.head() as PriorityQueueElement<T>).priority) {
      this.items.unshift(element);
      return;
    }

    // 插入到最后
    const len = this.size();
    const tailItem = this.items[len - 1];
    if (tailItem.priority <= priority) {
      this.items.push(element);
      return;
    }

    // 在中间位置插入
    for (let i = 0; i < len; i++) {
      const current = this.items[i];
      if (current.priority > priority) {
        this.items.splice(i, 0, element);
        break;
      }
    }
  }

  /**
   * 查看第一个元素(值)
   * @returns
   */
  /* @ts-ignore */
  public head(): T | void {
    const element = super.head();
    if (element) {
      return element.value;
    }
  }

  /**
   * 出列
   * @returns
   */
  /* @ts-ignore */
  public dequeue(): T | void {
    const element = super.dequeue();
    if (element) {
      return element.value;
    }
  }
}

异步任务队列

TODO: 实现异步任务队列

Released under the MIT License.