JavaScript 数据结构与算法(五)优先队列

生活中类似优先队列的场景:

  • 优先排队的人,优先处理。 (买票、结账、WC)。
  • 排队中,有紧急情况(特殊情况)的人可优先处理。

优先队列

优先级队列主要考虑的问题:

  • 每个元素不再只是一个数据,还包含优先级。
  • 在添加元素过程中,根据优先级放入到正确位置。

优先队列的实现

代码实现
  1. // 优先队列内部的元素类
  2. class QueueElement {
  3. constructor(element, priority) {
  4. this.element = element;
  5. this.priority = priority;
  6. }
  7. }
  8. // 优先队列类(继承 Queue 类)
  9. export class PriorityQueue extends Queue {
  10. constructor() {
  11. super();
  12. }
  13. // enqueue(element, priority) 入队,将元素按优先级加入到队列中
  14. // 重写 enqueue()
  15. enqueue(element, priority) {
  16. // 根据传入的元素,创建 QueueElement 对象
  17. const queueElement = new QueueElement(element, priority);
  18. // 判断队列是否为空
  19. if (this.isEmpty()) {
  20. // 如果为空,不用判断优先级,直接添加
  21. this.items.push(queueElement);
  22. } else {
  23. // 定义一个变量记录是否成功添加了新元素
  24. let added = false;
  25. for (let i = 0; i < this.items.length; i++) {
  26. // 让新插入的元素进行优先级比较,priority 值越小,优先级越大
  27. if (queueElement.priority < this.items[i].priority) {
  28. // 在指定的位置插入元素
  29. this.items.splice(i, 0, queueElement);
  30. added = true;
  31. break;
  32. }
  33. }
  34. // 如果遍历完所有元素,优先级都大于新插入的元素,就将新插入的元素插入到最后
  35. if (!added) {
  36. this.items.push(queueElement);
  37. }
  38. }
  39. }
  40. // dequeue() 出队,从队列中删除前端元素,返回删除的元素
  41. // 继承 Queue 类的 dequeue()
  42. dequeue() {
  43. return super.dequeue();
  44. }
  45. // front() 查看队列的前端元素
  46. // 继承 Queue 类的 front()
  47. front() {
  48. return super.front();
  49. }
  50. // isEmpty() 查看队列是否为空
  51. // 继承 Queue 类的 isEmpty()
  52. isEmpty() {
  53. return super.isEmpty();
  54. }
  55. // size() 查看队列中元素的个数
  56. // 继承 Queue 类的 size()
  57. size() {
  58. return super.size();
  59. }
  60. // toString() 将队列中元素以字符串形式返回
  61. // 重写 toString()
  62. toString() {
  63. let result = '';
  64. for (let item of this.items) {
  65. result += item.element + '-' + item.priority + ' ';
  66. }
  67. return result;
  68. }
  69. }

测试代码

  1. const priorityQueue = new PriorityQueue();
  2. // 入队 enqueue() 测试
  3. priorityQueue.enqueue('A', 10);
  4. priorityQueue.enqueue('B', 15);
  5. priorityQueue.enqueue('C', 11);
  6. priorityQueue.enqueue('D', 20);
  7. priorityQueue.enqueue('E', 18);
  8. console.log(priorityQueue.items);
  9. //--> output:
  10. // QueueElement {element: "A", priority: 10}
  11. // QueueElement {element: "C", priority: 11}
  12. // QueueElement {element: "B", priority: 15}
  13. // QueueElement {element: "E", priority: 18}
  14. // QueueElement {element: "D", priority: 20}
  15. // 出队 dequeue() 测试
  16. priorityQueue.dequeue();
  17. priorityQueue.dequeue();
  18. console.log(priorityQueue.items);
  19. //--> output:
  20. // QueueElement {element: "B", priority: 15}
  21. // QueueElement {element: "E", priority: 18}
  22. // QueueElement {element: "D", priority: 20}
  23. // isEmpty() 测试
  24. console.log(priorityQueue.isEmpty()); //--> false
  25. // size() 测试
  26. console.log(priorityQueue.size()); //--> 3
  27. // toString() 测试
  28. console.log(priorityQueue.toString()); //--> B-15 E-18 D-20

补充:数组、栈和队列图解

05_JavaScript数据结构与算法(五)优先队列 - 图1