如何实现一个优先级队列

本文阅读 2 分钟
首页 知识库 正文

// 封装优先级队列 function PriorityQueue() { // 在 PriorityQueue 中重新创建一个类,和 java 中的内部类很相似 function QueueElement(element, priority) { this.element = element; this.priority = priority; } // 封装属性,用数组来存储队列 this.items = [];

  1. // 入队
  2. PriorityQueue.prototype.enQueue = function (element, priority) {
  3. // 1.创建对象
  4. var queueElement = new QueueElement(element, priority);
  5. // 2.判断队列是否为空
  6. if(this.items.length == 0)
  7. this.items.push(queueElement);
  8. else {
  9. var flag = false;
  10. for(var i = 0; i< this.items.length; i++){
  11. if(queueElement.priority < this.items[i].priority){
  12. this.items.splice(i,0,queueElement);
  13. flag = true;
  14. break;
  15. }
  16. }
  17. if(!flag)
  18. this.items.push(queueElement);
  19. }
  20. }
  21. // 2.出队
  22. PriorityQueue.prototype.deQueue = function () {
  23. return this.items.shift();
  24. }
  25. // 3.查看队头元素
  26. PriorityQueue.prototype.front = function() {
  27. return this.items[0];
  28. }
  29. // 4.判断队列是否为空
  30. PriorityQueue.prototype.isEmpty = function() {
  31. return this.items.length == 0;
  32. }
  33. // 5.查看队列中元素的个数
  34. PriorityQueue.prototype.size = function() {
  35. return this.items.length;
  36. }
  37. // 6.将队列元素按字符串格式输出
  38. PriorityQueue.prototype.toString = function() {
  39. var result = "";
  40. for(var i = 0; i < this.items.length; i++)
  41. result += this.items[i].element + " ";
  42. return result;
  43. }
  44. }
  45. 基于最大堆实现优先队列

class MaxHeap {
constructor(arr = []) {

  1. this.heap = []; // 用数组表示堆结构
  2. arr.forEach((item) => this.add(item));

}

add(value) {

  1. // O(logK) 插入节点值: 放入数组末尾并上浮到合适位置
  2. this.heap.push(value);
  3. this.shiftUp(this.heap.length - 1);

}

pop() {

  1. // O(logK) 提取最大值/堆顶: 提取 heap[0] 并用 heap[-1] 进行代替,然后从顶部开始下沉到合适位置
  2. const max = this.heap[0];
  3. this.swap(0, this.size() - 1);
  4. this.heap.pop();
  5. this.shiftDown(0);
  6. return max;

}

peek() {

  1. // 获取最值/堆顶
  2. return this.heap[0];

}

size() {

  1. // 获取当前堆大小
  2. return this.heap.length;

}

// ↓私有属性↓
swap(index1, index2) {

  1. // 交换节点位置
  2. const temp = this.heap[index1];
  3. this.heap[index1] = this.heap[index2];
  4. this.heap[index2] = temp;

}

parentIndex(index) {

  1. // 获取父节点的位置 (index - 1) / 2 向下取整
  2. return (index - 1) >> 1;

}

leftChildIndex(index) {

  1. // 获取左子节点
  2. return index * 2 + 1;

}

rightChildIndex(index) {

  1. // 获取右子节点
  2. return index * 2 + 2;

}

shiftUp(index) {

  1. // 上浮节点,当前值小于父节点值时停止,使当前堆保持最大堆的性质
  2. let parentIndex = this.parentIndex(index);
  3. while (index > 0 && this.heap[parentIndex] < this.heap[index]) {
  4. this.swap(index, parentIndex);
  5. parentIndex = this.parentIndex((index = parentIndex));
  6. }

}

shiftDown(index) {

  1. // 下沉节点,当前值大于子节点值时停止,使当前堆保持最大堆的性质
  2. const leftIndex = this.leftChildIndex(index);
  3. const rightIndex = this.rightChildIndex(index);
  4. // 先比较左子节点值,当前值小于左子节点,则交换,并递归进行下沉
  5. if (this.heap[index] < this.heap[leftIndex]) {
  6. this.swap(leftIndex, index);
  7. this.shiftDown(leftIndex);
  8. }
  9. if (this.heap[index] < this.heap[rightIndex]) {
  10. this.swap(rightIndex, index);
  11. this.shiftDown(rightIndex);
  12. }

}
}

// ==TEST==
const priorityQueue = new MaxHeap([2, 5, 3]);
console.log(priorityQueue.peek()); // 5
priorityQueue.add(7);
console.log(priorityQueue.peek()); // 7
priorityQueue.pop();
priorityQueue.add(1);
console.log(priorityQueue.peek()); // 5

解压密码: detechn或detechn.com

免责声明

本站所有资源出自互联网收集整理,本站不参与制作,如果侵犯了您的合法权益,请联系本站我们会及时删除。

本站发布资源来源于互联网,可能存在水印或者引流等信息,请用户自行鉴别,做一个有主见和判断力的用户。

本站资源仅供研究、学习交流之用,若使用商业用途,请购买正版授权,否则产生的一切后果将由下载用户自行承担。

2022年马哥全栈+爬虫+数据+AI
« 上一篇 05-28
如何判断两个链表是否相交
下一篇 » 05-28

发表评论

惪特博客
  • 文章总数:
    18497 篇
  • 评论总数:
    53306 条
  • 标签总数:
    8873 个
  • 总浏览量:
    22596279 次
  • 最后更新:
    3天前

最多点赞

随便看看

标签TAG