-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpq.ts
61 lines (56 loc) · 1.45 KB
/
pq.ts
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
/**
* Simple priority queue (binary heap impl).
* Supports add and popMin in O(log(n)).
*/
export class PriorityQueue<T> {
private arr: T[] = [];
constructor(private readonly cmp: (x: T, y: T) => -1 | 0 | 1) {}
insert(item: T) {
this.arr.push(item);
let idx = this.arr.length - 1;
while (idx > 0) {
const parent = (idx - 1) >> 1;
if (this.arr[parent] <= this.arr[idx]) return;
const temp = this.arr[parent];
this.arr[parent] = this.arr[idx];
this.arr[idx] = temp;
idx = parent;
}
}
length() {
return this.arr.length;
}
popMin(): T {
if (this.arr.length === 0) {
throw new Error(`can't pop from an empty priority queue.`);
}
const min = this.arr[0];
const last = this.arr.pop()!;
if (this.arr.length == 0) return min;
this.arr[0] = last;
this.adjustHeap();
return min;
}
private adjustHeap() {
let idx = 0;
while (true) {
const left = 2 * idx;
const right = left + 1;
if (left < this.arr.length && this.arr[left] < this.arr[idx]) {
const temp = this.arr[left];
this.arr[left] = this.arr[idx];
this.arr[idx] = temp;
idx = left;
continue;
}
if (right < this.arr.length && this.arr[right] < this.arr[idx]) {
const temp = this.arr[right];
this.arr[right] = this.arr[idx];
this.arr[idx] = temp;
idx = right;
continue;
}
break;
}
}
}