-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheap.js
102 lines (93 loc) · 2.5 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
95
96
97
98
99
100
101
102
export class Heap {
constructor() {
this.items = [0];
}
swapIndices(i, j) {
const tmp = this.items[i];
this.items[i] = this.items[j];
this.items[j] = tmp;
}
size() {
return this.items.length - 1;
}
get(i) {
if (i > 0 && i <= this.items.length) {
return this.items[i];
}
return undefined;
}
// sink operation with an optional callback
sink(i, visit) {
if (visit === null) {
return;
}
visit(i, () => {
const curr = this.get(i);
const leftChild = this.get(2 * i);
const rightChild = this.get(2 * i + 1);
if (leftChild === undefined && rightChild === undefined) {
return;
}
else if (rightChild === undefined) {
if (leftChild < curr) {
this.swapIndices(i, 2 * i);
this.sink(2 * i, visit);
}
}
else {
if (leftChild < curr || rightChild < curr) {
if (leftChild <= rightChild) {
this.swapIndices(i, 2 * i);
this.sink(2 * i, visit);
}
else {
this.swapIndices(i, 2 * i + 1)
this.sink(2 * i + 1, visit);
}
}
}
});
}
swim(i, visit) {
if (visit === null) {
return;
}
visit(i, () => {
if (i === 1) {
return;
}
const curr = this.get(i);
const parent = this.get(Math.floor(i / 2));
if (parent > curr) {
this.swapIndices(i, Math.floor(i / 2));
this.swim(Math.floor(i / 2), visit);
}
});
}
insert(value, visit) {
this.items.push(value);
this.swim(this.size(), visit);
}
remove(visit) {
const toReturn = this.items[1];
if (visit === null) {
return;
}
visit(1, () => {
this.swapIndices(1, this.size());
this.items.pop();
this.sink(1, visit);
});
return toReturn;
}
toString() {
var str = "";
for (var i = 1; i <= this.size(); i++) {
str += `${this.get(i)}`;
if (i !== this.size()) {
str += " ";
}
}
return str;
}
}