-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheap.ts
94 lines (76 loc) · 1.89 KB
/
heap.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
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
export interface Comparator<T> {
(a: T, b: T): number;
}
const swap = <T>(a: number, b: number, arr: T[]) => {
const tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
};
export class Heap<T> {
private _arr: T[] = [];
constructor(private _comparator: Comparator<T>) {}
insert(el: T) {
let idx = this._arr.length;
this._arr.push(el);
while (idx) {
const parentIdx = Math.floor(idx / 2);
if (this._comparator(el, this._arr[parentIdx]) < 0) {
swap(parentIdx, idx, this._arr);
idx = parentIdx;
} else {
return;
}
}
}
pop(): T | undefined {
if (!this._arr.length) {
return undefined;
}
swap(0, this._arr.length - 1, this._arr);
const result = this._arr.pop();
this._heapify(0);
return result;
}
top(): T | undefined {
return this._arr[0];
}
private _heapify(start: number) {
const len = this._arr.length;
if (start >= len) {
return;
}
const left = 2 * start + 1;
const right = 2 * start + 2;
let futureParent = start;
const startVal = this._arr[start];
if (left < len && this._comparator(this._arr[left], startVal) < 0) {
futureParent = left;
}
if (right < len &&
(this._comparator(this._arr[right], startVal) < 0 &&
this._comparator(this._arr[right], this._arr[left]) < 0)) {
futureParent = right;
}
if (futureParent !== start) {
swap(start, futureParent, this._arr);
this._heapify(futureParent);
}
}
}
const heap = new Heap<number>((a, b) => a - b);
heap.insert(5);
console.log(heap.top());
heap.insert(6);
console.log(heap.top());
heap.insert(1);
console.log(heap.top());
heap.insert(8);
console.log(heap.top());
heap.insert(-1);
console.log(heap.top());
console.log(heap.pop());
console.log(heap.pop());
console.log(heap.pop());
console.log(heap.pop());
console.log(heap.pop());
console.log(heap.pop());