-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
129 lines (98 loc) · 2.36 KB
/
index.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* 大顶堆 */
class Heap<T = number> {
len: number;
capacity: number;
data: T[]
constructor(capacity: number) {
capacity = Math.ceil(capacity);
if (Number.isNaN(capacity) || capacity < 0) {
throw new Error('capacity must be positive integer')
}
this.len = 0;
this.capacity = capacity;
this.data = new Array(capacity + 1);
}
private exist(i: number) {
return i <= this.len && i > 0;
}
/* 交换 */
private swap(i: number, j: number) {
const data = this.data;
const tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
/* 从下往上堆化 */
private heapifyFromBottom() {
const data = this.data;
let current = this.len;
let parent = current >> 1;
let finished = current < 2;
while (!finished) {
if (data[current] > data[parent]) {
this.swap(current, parent);
current = parent;
parent = current >> 1;
finished = current < 2;
} else {
finished = true;
}
}
}
/* 从顶往下堆化 */
private heapifyFromTop() {
const data = this.data;
if (!this.len) {
return;
}
let finished = false;
let current = 1;
while (!finished) {
let maxPos = current;
let left = current << 1;
let right = left + 1;
if (this.exist(left) && data[maxPos] < data[left]) {
maxPos = left;
}
if (this.exist(right) && data[maxPos] < data[right]) {
maxPos = right;
}
// 当前自己节点就是最大的,所以结束
finished = maxPos === current;
if (!finished) {
this.swap(current, maxPos);
current = maxPos;
}
}
}
/* 删除堆顶元素 */
public deleteTop() {
if (!this.len) {
return null;
}
const data = this.data;
const top = data[1];
data[1] = data[this.len];
this.len--;
this.heapifyFromTop();
return top;
}
public insert(v: T, force: boolean = false) {
debugger;
const isFull = this.len === this.capacity;
if (isFull && !force) {
// 堆满了
return false;
}
if (isFull) {
// 先删除堆顶元素,然后再插入
this.deleteTop();
}
this.len++;
// 总是将当前值插入到最后,然后从下往上堆化
this.data[this.len] = v;
this.heapifyFromBottom();
return true;
}
}
export default Heap;