Heap.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. // Binary min-heap implementation used for priority queue.
  6. // Implementation is stable, i.e. push time is considered for equal priorities
  7. class Heap {
  8. constructor() {
  9. this.heap = [];
  10. this.pushCount = Number.MIN_SAFE_INTEGER;
  11. }
  12. get length() {
  13. return this.heap.length;
  14. }
  15. empty() {
  16. this.heap = [];
  17. return this;
  18. }
  19. percUp(index) {
  20. let p;
  21. while (index > 0 && smaller(this.heap[index], this.heap[p = parent(index)])) {
  22. let t = this.heap[index];
  23. this.heap[index] = this.heap[p];
  24. this.heap[p] = t;
  25. index = p;
  26. }
  27. }
  28. percDown(index) {
  29. let l;
  30. while ((l = leftChi(index)) < this.heap.length) {
  31. if (l + 1 < this.heap.length && smaller(this.heap[l + 1], this.heap[l])) {
  32. l = l + 1;
  33. }
  34. if (smaller(this.heap[index], this.heap[l])) {
  35. break;
  36. }
  37. let t = this.heap[index];
  38. this.heap[index] = this.heap[l];
  39. this.heap[l] = t;
  40. index = l;
  41. }
  42. }
  43. push(node) {
  44. node.pushCount = ++this.pushCount;
  45. this.heap.push(node);
  46. this.percUp(this.heap.length - 1);
  47. }
  48. unshift(node) {
  49. return this.heap.push(node);
  50. }
  51. shift() {
  52. let [top] = this.heap;
  53. this.heap[0] = this.heap[this.heap.length - 1];
  54. this.heap.pop();
  55. this.percDown(0);
  56. return top;
  57. }
  58. toArray() {
  59. return [...this];
  60. }
  61. *[Symbol.iterator]() {
  62. for (let i = 0; i < this.heap.length; i++) {
  63. yield this.heap[i].data;
  64. }
  65. }
  66. remove(testFn) {
  67. let j = 0;
  68. for (let i = 0; i < this.heap.length; i++) {
  69. if (!testFn(this.heap[i])) {
  70. this.heap[j] = this.heap[i];
  71. j++;
  72. }
  73. }
  74. this.heap.splice(j);
  75. for (let i = parent(this.heap.length - 1); i >= 0; i--) {
  76. this.percDown(i);
  77. }
  78. return this;
  79. }
  80. }
  81. exports.default = Heap;
  82. function leftChi(i) {
  83. return (i << 1) + 1;
  84. }
  85. function parent(i) {
  86. return (i + 1 >> 1) - 1;
  87. }
  88. function smaller(x, y) {
  89. if (x.priority !== y.priority) {
  90. return x.priority < y.priority;
  91. } else {
  92. return x.pushCount < y.pushCount;
  93. }
  94. }
  95. module.exports = exports["default"];