typescript-ds-lib 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/dist/lib/graph.d.ts +14 -0
- package/dist/lib/graph.js +3 -0
- package/dist/lib/graph.js.map +1 -0
- package/dist/lib/hash-table-utils.d.ts +5 -0
- package/dist/lib/hash-table-utils.js +91 -0
- package/dist/lib/hash-table-utils.js.map +1 -0
- package/dist/lib/hash-table.d.ts +0 -2
- package/dist/lib/hash-table.js +10 -86
- package/dist/lib/hash-table.js.map +1 -1
- package/package.json +2 -4
- package/lib/binary-search-tree.ts +0 -218
- package/lib/deque.ts +0 -86
- package/lib/hash-table.ts +0 -179
- package/lib/linked-list.ts +0 -314
- package/lib/map.ts +0 -55
- package/lib/matrix.ts +0 -427
- package/lib/priority-queue.ts +0 -71
- package/lib/queue.ts +0 -62
- package/lib/red-black-tree.ts +0 -350
- package/lib/set.ts +0 -83
- package/lib/stack.ts +0 -59
- package/types/index.ts +0 -1
package/lib/red-black-tree.ts
DELETED
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
import { Comparator } from '../types';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export interface RedBlackTree<K, V> {
|
|
5
|
-
insert(key: K, value: V): void;
|
|
6
|
-
remove(key: K): void;
|
|
7
|
-
find(key: K): V | undefined;
|
|
8
|
-
min(): V | undefined;
|
|
9
|
-
max(): V | undefined;
|
|
10
|
-
forEach(callback: (key: K, value: V) => void): void;
|
|
11
|
-
isEmpty(): boolean;
|
|
12
|
-
size(): number;
|
|
13
|
-
clear(): void;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
enum Color {
|
|
18
|
-
RED,
|
|
19
|
-
BLACK
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class RBNode<K, V> {
|
|
24
|
-
key: K;
|
|
25
|
-
value: V;
|
|
26
|
-
color: Color;
|
|
27
|
-
left: RBNode<K, V> | null;
|
|
28
|
-
right: RBNode<K, V> | null;
|
|
29
|
-
parent: RBNode<K, V> | null;
|
|
30
|
-
|
|
31
|
-
constructor(key: K, value: V) {
|
|
32
|
-
this.key = key;
|
|
33
|
-
this.value = value;
|
|
34
|
-
this.color = Color.RED;
|
|
35
|
-
this.left = null;
|
|
36
|
-
this.right = null;
|
|
37
|
-
this.parent = null;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export class RedBlackTree<K, V> implements RedBlackTree<K, V> {
|
|
43
|
-
private root: RBNode<K, V> | null;
|
|
44
|
-
private nodeCount: number;
|
|
45
|
-
private comparator: Comparator<K>;
|
|
46
|
-
|
|
47
|
-
constructor(comparator: Comparator<K> = (a: K, b: K) => a < b) {
|
|
48
|
-
this.root = null;
|
|
49
|
-
this.nodeCount = 0;
|
|
50
|
-
this.comparator = comparator;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
private rotateLeft(node: RBNode<K, V>): void {
|
|
54
|
-
const rightChild = node.right!;
|
|
55
|
-
node.right = rightChild.left;
|
|
56
|
-
if (rightChild.left !== null) {
|
|
57
|
-
rightChild.left.parent = node;
|
|
58
|
-
}
|
|
59
|
-
rightChild.parent = node.parent;
|
|
60
|
-
if (node.parent === null) {
|
|
61
|
-
this.root = rightChild;
|
|
62
|
-
} else if (node === node.parent.left) {
|
|
63
|
-
node.parent.left = rightChild;
|
|
64
|
-
} else {
|
|
65
|
-
node.parent.right = rightChild;
|
|
66
|
-
}
|
|
67
|
-
rightChild.left = node;
|
|
68
|
-
node.parent = rightChild;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private rotateRight(node: RBNode<K, V>): void {
|
|
72
|
-
const leftChild = node.left!;
|
|
73
|
-
node.left = leftChild.right;
|
|
74
|
-
if (leftChild.right !== null) {
|
|
75
|
-
leftChild.right.parent = node;
|
|
76
|
-
}
|
|
77
|
-
leftChild.parent = node.parent;
|
|
78
|
-
if (node.parent === null) {
|
|
79
|
-
this.root = leftChild;
|
|
80
|
-
} else if (node === node.parent.right) {
|
|
81
|
-
node.parent.right = leftChild;
|
|
82
|
-
} else {
|
|
83
|
-
node.parent.left = leftChild;
|
|
84
|
-
}
|
|
85
|
-
leftChild.right = node;
|
|
86
|
-
node.parent = leftChild;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private fixInsert(node: RBNode<K, V>): void {
|
|
90
|
-
while (node !== this.root && node.parent?.color === Color.RED) {
|
|
91
|
-
if (node.parent === node.parent.parent?.left) {
|
|
92
|
-
const uncle = node.parent.parent.right;
|
|
93
|
-
|
|
94
|
-
if (uncle?.color === Color.RED) {
|
|
95
|
-
node.parent.color = Color.BLACK;
|
|
96
|
-
uncle.color = Color.BLACK;
|
|
97
|
-
node.parent.parent.color = Color.RED;
|
|
98
|
-
node = node.parent.parent;
|
|
99
|
-
} else {
|
|
100
|
-
if (node === node.parent.right) {
|
|
101
|
-
node = node.parent;
|
|
102
|
-
this.rotateLeft(node);
|
|
103
|
-
}
|
|
104
|
-
node.parent!.color = Color.BLACK;
|
|
105
|
-
node.parent!.parent!.color = Color.RED;
|
|
106
|
-
this.rotateRight(node.parent!.parent!);
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
const uncle = node.parent.parent?.left;
|
|
110
|
-
if (uncle?.color === Color.RED) {
|
|
111
|
-
node.parent.color = Color.BLACK;
|
|
112
|
-
uncle.color = Color.BLACK;
|
|
113
|
-
node.parent.parent!.color = Color.RED;
|
|
114
|
-
node = node.parent.parent!;
|
|
115
|
-
} else {
|
|
116
|
-
if (node === node.parent.left) {
|
|
117
|
-
node = node.parent;
|
|
118
|
-
this.rotateRight(node);
|
|
119
|
-
}
|
|
120
|
-
node.parent!.color = Color.BLACK;
|
|
121
|
-
node.parent!.parent!.color = Color.RED;
|
|
122
|
-
this.rotateLeft(node.parent!.parent!);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
this.root!.color = Color.BLACK;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
insert(key: K, value: V): void {
|
|
130
|
-
const newNode = new RBNode(key, value);
|
|
131
|
-
let parent: RBNode<K, V> | null = null;
|
|
132
|
-
let current = this.root;
|
|
133
|
-
while (current !== null) {
|
|
134
|
-
parent = current;
|
|
135
|
-
if (this.comparator(key, current.key)) {
|
|
136
|
-
current = current.left;
|
|
137
|
-
} else if (this.comparator(current.key, key)) {
|
|
138
|
-
current = current.right;
|
|
139
|
-
} else {
|
|
140
|
-
// Key already exists, update value
|
|
141
|
-
current.value = value;
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
newNode.parent = parent;
|
|
147
|
-
|
|
148
|
-
if (parent === null) {
|
|
149
|
-
this.root = newNode;
|
|
150
|
-
} else if (this.comparator(key, parent.key)) {
|
|
151
|
-
parent.left = newNode;
|
|
152
|
-
} else {
|
|
153
|
-
parent.right = newNode;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
this.nodeCount++;
|
|
157
|
-
this.fixInsert(newNode);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
private findNode(key: K): RBNode<K, V> | null {
|
|
161
|
-
let current = this.root;
|
|
162
|
-
while (current !== null) {
|
|
163
|
-
if (this.isEqual(key, current.key)) {
|
|
164
|
-
return current;
|
|
165
|
-
}
|
|
166
|
-
current = this.comparator(key, current.key) ? current.left : current.right;
|
|
167
|
-
}
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
find(key: K): V | undefined {
|
|
172
|
-
const node = this.findNode(key);
|
|
173
|
-
return node ? node.value : undefined;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
private findMinNode(node: RBNode<K, V>): RBNode<K, V> {
|
|
177
|
-
let current = node;
|
|
178
|
-
while (current.left !== null) {
|
|
179
|
-
current = current.left;
|
|
180
|
-
}
|
|
181
|
-
return current;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
min(): V | undefined {
|
|
185
|
-
if (!this.root) return undefined;
|
|
186
|
-
return this.findMinNode(this.root).value;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
private findMaxNode(node: RBNode<K, V>): RBNode<K, V> {
|
|
190
|
-
let current = node;
|
|
191
|
-
while (current.right !== null) {
|
|
192
|
-
current = current.right;
|
|
193
|
-
}
|
|
194
|
-
return current;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
max(): V | undefined {
|
|
198
|
-
if (!this.root) return undefined;
|
|
199
|
-
return this.findMaxNode(this.root).value;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
remove(key: K): void {
|
|
203
|
-
const node = this.findNode(key);
|
|
204
|
-
if (node) {
|
|
205
|
-
this.nodeCount--;
|
|
206
|
-
this.deleteNode(node);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
private deleteNode(node: RBNode<K, V>): void {
|
|
211
|
-
let x: RBNode<K, V> | null;
|
|
212
|
-
let y = node;
|
|
213
|
-
let originalColor = y.color;
|
|
214
|
-
|
|
215
|
-
if (node.left === null) {
|
|
216
|
-
x = node.right;
|
|
217
|
-
this.transplant(node, node.right);
|
|
218
|
-
} else if (node.right === null) {
|
|
219
|
-
x = node.left;
|
|
220
|
-
this.transplant(node, node.left);
|
|
221
|
-
} else {
|
|
222
|
-
y = this.findMinNode(node.right);
|
|
223
|
-
originalColor = y.color;
|
|
224
|
-
x = y.right;
|
|
225
|
-
|
|
226
|
-
if (y.parent === node) {
|
|
227
|
-
if (x) x.parent = y;
|
|
228
|
-
} else {
|
|
229
|
-
this.transplant(y, y.right);
|
|
230
|
-
y.right = node.right;
|
|
231
|
-
y.right.parent = y;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
this.transplant(node, y);
|
|
235
|
-
y.left = node.left;
|
|
236
|
-
y.left.parent = y;
|
|
237
|
-
y.color = node.color;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
if (originalColor === Color.BLACK && x) {
|
|
241
|
-
this.fixDelete(x);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
private transplant(u: RBNode<K, V>, v: RBNode<K, V> | null): void {
|
|
246
|
-
if (u.parent === null) {
|
|
247
|
-
this.root = v;
|
|
248
|
-
} else if (u === u.parent.left) {
|
|
249
|
-
u.parent.left = v;
|
|
250
|
-
} else {
|
|
251
|
-
u.parent.right = v;
|
|
252
|
-
}
|
|
253
|
-
if (v !== null) {
|
|
254
|
-
v.parent = u.parent;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
private fixDelete(x: RBNode<K, V>): void {
|
|
259
|
-
while (x !== this.root && x.color === Color.BLACK) {
|
|
260
|
-
if (x === x.parent!.left) {
|
|
261
|
-
let w = x.parent!.right!;
|
|
262
|
-
|
|
263
|
-
if (w.color === Color.RED) {
|
|
264
|
-
w.color = Color.BLACK;
|
|
265
|
-
x.parent!.color = Color.RED;
|
|
266
|
-
this.rotateLeft(x.parent!);
|
|
267
|
-
w = x.parent!.right!;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if ((!w.left || w.left.color === Color.BLACK) &&
|
|
271
|
-
(!w.right || w.right.color === Color.BLACK)) {
|
|
272
|
-
w.color = Color.RED;
|
|
273
|
-
x = x.parent!;
|
|
274
|
-
} else {
|
|
275
|
-
if (!w.right || w.right.color === Color.BLACK) {
|
|
276
|
-
if (w.left) w.left.color = Color.BLACK;
|
|
277
|
-
w.color = Color.RED;
|
|
278
|
-
this.rotateRight(w);
|
|
279
|
-
w = x.parent!.right!;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
w.color = x.parent!.color;
|
|
283
|
-
x.parent!.color = Color.BLACK;
|
|
284
|
-
if (w.right) w.right.color = Color.BLACK;
|
|
285
|
-
this.rotateLeft(x.parent!);
|
|
286
|
-
x = this.root!;
|
|
287
|
-
}
|
|
288
|
-
} else {
|
|
289
|
-
let w = x.parent!.left!;
|
|
290
|
-
|
|
291
|
-
if (w.color === Color.RED) {
|
|
292
|
-
w.color = Color.BLACK;
|
|
293
|
-
x.parent!.color = Color.RED;
|
|
294
|
-
this.rotateRight(x.parent!);
|
|
295
|
-
w = x.parent!.left!;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if ((!w.right || w.right.color === Color.BLACK) &&
|
|
299
|
-
(!w.left || w.left.color === Color.BLACK)) {
|
|
300
|
-
w.color = Color.RED;
|
|
301
|
-
x = x.parent!;
|
|
302
|
-
} else {
|
|
303
|
-
if (!w.left || w.left.color === Color.BLACK) {
|
|
304
|
-
if (w.right) w.right.color = Color.BLACK;
|
|
305
|
-
w.color = Color.RED;
|
|
306
|
-
this.rotateLeft(w);
|
|
307
|
-
w = x.parent!.left!;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
w.color = x.parent!.color;
|
|
311
|
-
x.parent!.color = Color.BLACK;
|
|
312
|
-
if (w.left) w.left.color = Color.BLACK;
|
|
313
|
-
this.rotateRight(x.parent!);
|
|
314
|
-
x = this.root!;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
x.color = Color.BLACK;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
isEmpty(): boolean {
|
|
322
|
-
return this.root === null;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
size(): number {
|
|
326
|
-
return this.nodeCount;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
clear(): void {
|
|
330
|
-
this.root = null;
|
|
331
|
-
this.nodeCount = 0;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
private isEqual(a: K, b: K): boolean {
|
|
335
|
-
// Two values are equal if neither is less than the other
|
|
336
|
-
return !this.comparator(a, b) && !this.comparator(b, a);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
private inorderTraversal(node: RBNode<K, V> | null, callback: (key: K, value: V) => void): void {
|
|
340
|
-
if (node !== null) {
|
|
341
|
-
this.inorderTraversal(node.left, callback);
|
|
342
|
-
callback(node.key, node.value);
|
|
343
|
-
this.inorderTraversal(node.right, callback);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
forEach(callback: (key: K, value: V) => void): void {
|
|
348
|
-
this.inorderTraversal(this.root, callback);
|
|
349
|
-
}
|
|
350
|
-
}
|
package/lib/set.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { Comparator } from '../types';
|
|
2
|
-
import { BinarySearchTree } from './binary-search-tree';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export interface Set<T> {
|
|
6
|
-
insert(element: T): void;
|
|
7
|
-
insertList(elements: T[]): void;
|
|
8
|
-
remove(element: T): void;
|
|
9
|
-
find(element: T): boolean;
|
|
10
|
-
forEach(callback: (element: T) => void): void;
|
|
11
|
-
isEmpty(): boolean;
|
|
12
|
-
size(): number;
|
|
13
|
-
clear(): void;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export class Set<T> implements Set<T> {
|
|
18
|
-
private bst: BinarySearchTree<T>;
|
|
19
|
-
|
|
20
|
-
constructor(comparator: Comparator<T> = (a: T, b: T) => a < b) {
|
|
21
|
-
this.bst = new BinarySearchTree<T>(comparator);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Adds a value to the set if it's not already present
|
|
26
|
-
*/
|
|
27
|
-
insert(value: T): void {
|
|
28
|
-
if (!this.find(value)) {
|
|
29
|
-
this.bst.insert(value);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Adds multiple values to the set if they're not already present
|
|
35
|
-
*/
|
|
36
|
-
insertList(values: T[]): void {
|
|
37
|
-
for (const value of values) {
|
|
38
|
-
this.insert(value);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Checks if a value exists in the set
|
|
44
|
-
*/
|
|
45
|
-
find(value: T): boolean {
|
|
46
|
-
return this.bst.find(value);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Removes a value from the set
|
|
51
|
-
*/
|
|
52
|
-
remove(value: T): void {
|
|
53
|
-
this.bst.remove(value);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Executes a callback function for each element in the set
|
|
58
|
-
*/
|
|
59
|
-
forEach(callback: (element: T) => void): void {
|
|
60
|
-
this.bst.forEach(callback);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Removes all elements from the set
|
|
65
|
-
*/
|
|
66
|
-
clear(): void {
|
|
67
|
-
this.bst = new BinarySearchTree<T>();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Returns true if the set contains no elements
|
|
72
|
-
*/
|
|
73
|
-
isEmpty(): boolean {
|
|
74
|
-
return this.bst.isEmpty();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Returns the number of elements in the set
|
|
79
|
-
*/
|
|
80
|
-
size(): number {
|
|
81
|
-
return this.bst.count();
|
|
82
|
-
}
|
|
83
|
-
}
|
package/lib/stack.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
export interface Stack<T> {
|
|
2
|
-
push(element: T): void;
|
|
3
|
-
pop(): T | undefined;
|
|
4
|
-
top(): T | undefined;
|
|
5
|
-
isEmpty(): boolean;
|
|
6
|
-
size(): number;
|
|
7
|
-
clear(): void;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export class Stack<T> implements Stack<T> {
|
|
12
|
-
private items: T[];
|
|
13
|
-
|
|
14
|
-
constructor() {
|
|
15
|
-
this.items = [];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Adds an element to the top of the stack.
|
|
20
|
-
*/
|
|
21
|
-
push(element: T): void {
|
|
22
|
-
this.items.push(element);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Removes and returns the top element from the stack, or undefined if stack is empty.
|
|
27
|
-
*/
|
|
28
|
-
pop(): T | undefined {
|
|
29
|
-
return this.items.pop();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Returns the top element of the stack without removing it, or undefined if stack is empty.
|
|
34
|
-
*/
|
|
35
|
-
top(): T | undefined {
|
|
36
|
-
return this.items[this.items.length - 1];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Checks if the stack is empty. Returns true if the stack is empty, false otherwise.
|
|
41
|
-
*/
|
|
42
|
-
isEmpty(): boolean {
|
|
43
|
-
return this.items.length === 0;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Returns the number of elements in the stack. The size of the stack
|
|
48
|
-
*/
|
|
49
|
-
size(): number {
|
|
50
|
-
return this.items.length;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Removes all elements from the stack.
|
|
55
|
-
*/
|
|
56
|
-
clear(): void {
|
|
57
|
-
this.items = [];
|
|
58
|
-
}
|
|
59
|
-
}
|
package/types/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type Comparator<T> = (a: T, b: T) => boolean;
|