二叉堆:完全二叉树
    堆和数组:
    image-20210504151226478.png
    注意:这里节点上的数字表示的是数组索引值,而不是节点保存的值
    插入节点:
    堆的插入.png
    删除节点:
    堆删除根节点.png

    1. /*
    2. * @Author: LongSir
    3. * @LastEditTime: 2021-05-04 19:27:12
    4. * @description: 大根堆,节点元素最大
    5. */
    6. class PriorityQueue {
    7. constructor(arr) {
    8. if (arr.length) {
    9. this.pq = [];
    10. this._buildTree(arr);
    11. return;
    12. }
    13. this.pq = [];
    14. }
    15. // 父亲节点
    16. parent(root) {
    17. return Math.floor((root + 1) / 2) - 1;
    18. }
    19. // 左孩子节点
    20. leftChild(root) {
    21. return root * 2 + 1;
    22. }
    23. // 右孩子节点
    24. rightChild(root) {
    25. return root * 2 + 2;
    26. }
    27. // 构建树
    28. _buildTree(arr) {
    29. Object.assign(this.pq, arr);
    30. }
    31. // 交互数组位置i和j
    32. _exch(i, j) {
    33. let temp = this.pq[i];
    34. this.pq[i] = this.pq[j];
    35. this.pq[j] = temp;
    36. }
    37. // pq[i]是否比pq[j]小
    38. _less(i, j) {
    39. if (this.pq[i] < this.pq[j]) {
    40. return -1;
    41. } else if (this.pq[i] === this.pq[j]) {
    42. return 0;
    43. } else {
    44. return 1;
    45. }
    46. }
    47. // 上浮
    48. _swim(k) {
    49. while (this._less(this.parent(k), k) < 0) {
    50. this._exch(this.parent(k), k);
    51. k = this.parent(k);
    52. }
    53. }
    54. // 下沉
    55. _sink(k) {
    56. while (this._less(k, this.leftChild(k)) < 0 || this._less(k, this.rightChild(k)) < 0) {
    57. if (this._less(this.leftChild(k), this.rightChild(k)) < 0) {
    58. this._exch(k, this.rightChild(k));
    59. k = this.rightChild(k);
    60. } else {
    61. this._exch(k, this.leftChild(k));
    62. k = this.leftChild(k);
    63. }
    64. }
    65. }
    66. show() {
    67. console.log(this.pq);
    68. }
    69. // 实现队列
    70. enqueue(val) {
    71. this.pq.push(val);
    72. this._swim(this.pq.length - 1);
    73. }
    74. dequeue() {
    75. let dqNode = this.pq.shift();
    76. let last = this.pq.pop();
    77. this.pq.unshift(last);
    78. this._sink(0);
    79. return dqNode;
    80. }
    81. // 取队首的值
    82. getFirst() {
    83. return this.pq[0];
    84. }
    85. }

    测试:

    1. let arr = [10, 5, 6, 2, 3];
    2. let priorityQueue = new PriorityQueue(arr);
    3. priorityQueue.show();
    4. priorityQueue.enqueue(7);
    5. priorityQueue.dequeue(11);
    6. priorityQueue.show();