优先队列

优先级队列(priority queue) 是一种抽象数据类型, 它类似于常规的队列或栈, 但每个元素都有与之关联的“优先级”。

在优先队列中, 低优先级的元素之前前面应该是高优先级的元素。 如果两个元素具有相同的优先级, 则根据它们在队列中的顺序是它们的出现顺序即可。

优先队列虽通常用堆来实现,但它在概念上与堆不同。优先队列是一个抽象概念,就像“列表”或“图”这样的抽象概念一样;

正如列表可以用链表或数组实现一样,优先队列可以用堆或各种其他方法实现,例如无序数组。

PriorityQueue:

import MinHeap from '../heap/MinHeap';
import Comparator from '../../utils/comparator/Comparator';

// It is the same as min heap except that when comparing to elements
// we take into account not element's value but rather its priority.
//优先队列由最小堆实现,当比较元素的时候,我们考虑元素的优先级而不是它的值
export default class PriorityQueue extends MinHeap {
  constructor() {
    super();//调用父类的构造函数
    this.priorities = {};//优先级属性
    this.compare = new Comparator(this.comparePriority.bind(this));
    //比较器工具类的实例,自定义比较方法传入的是PriorityQueue.prototype.comparePriority方法,绑定了this为新实例化的PriorityQueue对象
  }

  /**
   * @param {*} item
   * @param {number} [priority]
   * @return {PriorityQueue}
   */
  add(item, priority = 0) {//添加新节点
    this.priorities[item] = priority;//存下新节点的优先级
    super.add(item);//调用父类上的add方法,将新节点插入

    return this;
  }

  /**
   * @param {*} item
   * @param {Comparator} [customFindingComparator]
   * @return {PriorityQueue}
   */
  remove(item, customFindingComparator) {//删除节点
    super.remove(item, customFindingComparator);//调用父类上的remove方法,将对应节点删除
    delete this.priorities[item];//从优先级对象里删除节点对应的优先级

    return this;
  }

  /**
   * @param {*} item
   * @param {number} priority
   * @return {PriorityQueue}
   */
  changePriority(item, priority) {//改变节点的优先级
    this.remove(item, new Comparator(this.compareValue));//先删除要改变的节点
    this.add(item, priority);//然后再重新添加

    return this;
  }

  /**
   * @param {*} item
   * @return {Number[]}
   */
  findByValue(item) {//根据值找到对应节点
    return this.find(item, new Comparator(this.compareValue));
  }

  /**
   * @param {*} item
   * @return {boolean}
   */
  hasValue(item) {//判断优先队列有没有某个节点
    return this.findByValue(item).length > 0;
  }

  /**
   * @param {*} a
   * @param {*} b
   * @return {number}
   */
  comparePriority(a, b) {//比较a节点和b节点的优先级,如果优先级一样返回0,否则返回-1或1
    if (this.priorities[a] === this.priorities[b]) {
      return 0;
    }

    return this.priorities[a] < this.priorities[b] ? -1 : 1;
  }

  /**
   * @param {*} a
   * @param {*} b
   * @return {number}
   */
  compareValue(a, b) {//比较值,相等返回0,否则返回-1或1
    if (a === b) {
      return 0;
    }

    return a < b ? -1 : 1;
  }
}

note:

1.优先级队列自定义方法如下:覆盖了父类(MinHeap类)的父类-Heap类中的比较方法

this.compare = new Comparator(comparatorFunction);

实现优先级的比较

 constructor() {
    super();
    this.priorities = {};
    this.compare = new Comparator(this.comparePriority.bind(this));
  }
comparePriority(a, b) {
    if (this.priorities[a] === this.priorities[b]) {
      return 0;
    }

    return this.priorities[a] < this.priorities[b] ? -1 : 1;
  }

测试代码如下:

const priorityQueue = new PriorityQueue();

    priorityQueue.add(10, 1);
    expect(priorityQueue.peek()).toBe(10);

    priorityQueue.add(5, 2);
    expect(priorityQueue.peek()).toBe(10);

    priorityQueue.add(100, 0);
    expect(priorityQueue.peek()).toBe(100);

比较的是优先级

2.优先级队列如果优先级相同则先来先服务。

 

posted @ 2019-01-08 16:20  Archer-Fang  阅读(478)  评论(0编辑  收藏  举报