-
Notifications
You must be signed in to change notification settings - Fork 0
/
heap.js
94 lines (82 loc) · 1.85 KB
/
heap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
* custom Heap class
*/
export class Heap {
constructor(comparator) {
this.size = 0;
this.values = [];
this.comparator = comparator || Heap.minComparator;
}
add(val) {
this.values.push(val);
this.size++;
this.bubbleUp();
}
peek() {
return this.values[0] || null;
}
poll() {
const max = this.values[0];
const end = this.values.pop();
this.size--;
if (this.values.length) {
this.values[0] = end;
this.bubbleDown();
}
return max;
}
bubbleUp() {
let index = this.values.length - 1;
let parent = Math.floor((index - 1) / 2);
while (this.comparator(this.values[index], this.values[parent]) < 0) {
[this.values[parent], this.values[index]] = [
this.values[index],
this.values[parent],
];
index = parent;
parent = Math.floor((index - 1) / 2);
}
}
bubbleDown() {
let index = 0,
length = this.values.length;
while (true) {
let left = null,
right = null,
swap = null,
leftIndex = index * 2 + 1,
rightIndex = index * 2 + 2;
if (leftIndex < length) {
left = this.values[leftIndex];
if (this.comparator(left, this.values[index]) < 0) swap = leftIndex;
}
if (rightIndex < length) {
right = this.values[rightIndex];
if (
(swap !== null && this.comparator(right, left) < 0) ||
(swap === null && this.comparator(right, this.values[index]))
) {
swap = rightIndex;
}
}
if (swap === null) break;
[this.values[index], this.values[swap]] = [
this.values[swap],
this.values[index],
];
index = swap;
}
}
}
/**
* Min Comparator
*/
Heap.minComparator = (a, b) => {
return a - b;
};
/**
* Max Comparator
*/
Heap.maxComparator = (a, b) => {
return b - a;
};