data-structure-typed 1.41.0 → 1.41.2

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  3. package/dist/cjs/data-structures/binary-tree/binary-indexed-tree.js.map +1 -1
  4. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +9 -6
  5. package/dist/cjs/data-structures/binary-tree/binary-tree.js +29 -10
  6. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  7. package/dist/cjs/data-structures/binary-tree/bst.d.ts +1 -1
  8. package/dist/cjs/data-structures/binary-tree/bst.js +2 -2
  9. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  10. package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +20 -4
  11. package/dist/cjs/data-structures/binary-tree/rb-tree.js +109 -44
  12. package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
  13. package/dist/cjs/data-structures/binary-tree/tree-multiset.js +2 -2
  14. package/dist/cjs/data-structures/binary-tree/tree-multiset.js.map +1 -1
  15. package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
  16. package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
  17. package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
  18. package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
  19. package/dist/cjs/data-structures/hash/tree-map.js.map +1 -1
  20. package/dist/cjs/data-structures/hash/tree-set.js.map +1 -1
  21. package/dist/cjs/data-structures/heap/heap.js.map +1 -1
  22. package/dist/cjs/data-structures/heap/max-heap.js.map +1 -1
  23. package/dist/cjs/data-structures/heap/min-heap.js.map +1 -1
  24. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  25. package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
  26. package/dist/cjs/data-structures/matrix/matrix.js.map +1 -1
  27. package/dist/cjs/data-structures/matrix/vector2d.js.map +1 -1
  28. package/dist/cjs/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  29. package/dist/cjs/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  30. package/dist/cjs/data-structures/priority-queue/priority-queue.js.map +1 -1
  31. package/dist/cjs/data-structures/queue/deque.js.map +1 -1
  32. package/dist/cjs/data-structures/queue/queue.js.map +1 -1
  33. package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +9 -6
  34. package/dist/mjs/data-structures/binary-tree/binary-tree.js +28 -10
  35. package/dist/mjs/data-structures/binary-tree/bst.d.ts +1 -1
  36. package/dist/mjs/data-structures/binary-tree/bst.js +2 -2
  37. package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +20 -4
  38. package/dist/mjs/data-structures/binary-tree/rb-tree.js +110 -45
  39. package/dist/mjs/data-structures/binary-tree/tree-multiset.js +2 -2
  40. package/dist/umd/data-structure-typed.min.js +1 -1
  41. package/dist/umd/data-structure-typed.min.js.map +1 -1
  42. package/package.json +9 -9
  43. package/src/data-structures/binary-tree/avl-tree.ts +3 -2
  44. package/src/data-structures/binary-tree/binary-indexed-tree.ts +1 -1
  45. package/src/data-structures/binary-tree/binary-tree.ts +73 -25
  46. package/src/data-structures/binary-tree/bst.ts +7 -4
  47. package/src/data-structures/binary-tree/rb-tree.ts +121 -68
  48. package/src/data-structures/binary-tree/tree-multiset.ts +4 -3
  49. package/src/data-structures/graph/abstract-graph.ts +11 -12
  50. package/src/data-structures/graph/directed-graph.ts +7 -6
  51. package/src/data-structures/graph/undirected-graph.ts +7 -6
  52. package/src/data-structures/hash/hash-map.ts +1 -1
  53. package/src/data-structures/hash/tree-map.ts +1 -2
  54. package/src/data-structures/hash/tree-set.ts +1 -2
  55. package/src/data-structures/heap/heap.ts +2 -2
  56. package/src/data-structures/heap/max-heap.ts +1 -1
  57. package/src/data-structures/heap/min-heap.ts +1 -1
  58. package/src/data-structures/linked-list/doubly-linked-list.ts +1 -1
  59. package/src/data-structures/linked-list/singly-linked-list.ts +1 -1
  60. package/src/data-structures/matrix/matrix.ts +1 -1
  61. package/src/data-structures/matrix/vector2d.ts +1 -2
  62. package/src/data-structures/priority-queue/max-priority-queue.ts +1 -1
  63. package/src/data-structures/priority-queue/min-priority-queue.ts +1 -1
  64. package/src/data-structures/priority-queue/priority-queue.ts +1 -1
  65. package/src/data-structures/queue/deque.ts +3 -4
  66. package/src/data-structures/queue/queue.ts +1 -1
  67. package/src/types/data-structures/matrix/navigator.ts +1 -1
  68. package/src/types/utils/utils.ts +1 -1
  69. package/src/types/utils/validate-type.ts +2 -2
  70. package/test/integration/avl-tree.test.ts +3 -3
  71. package/test/integration/bst.test.ts +7 -7
  72. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +6 -6
  73. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +11 -11
  74. package/test/unit/data-structures/binary-tree/bst.test.ts +22 -20
  75. package/test/unit/data-structures/binary-tree/overall.test.ts +2 -2
  76. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +214 -21
  77. package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +8 -8
  78. package/test/utils/big-o.js +10 -0
@@ -1,36 +1,45 @@
1
1
  "use strict";
2
+ /**
3
+ * data-structure-typed
4
+ *
5
+ * @author Tyler Zeng
6
+ * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
7
+ * @license MIT License
8
+ */
2
9
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RedBlackTree = exports.RBTreeNode = void 0;
10
+ exports.RedBlackTree = exports.NIL = exports.RBTreeNode = void 0;
4
11
  const types_1 = require("../../types");
5
12
  class RBTreeNode {
6
- key = 0;
13
+ key;
7
14
  parent;
8
15
  left;
9
16
  right;
10
17
  color = types_1.RBTNColor.BLACK;
11
- constructor() {
18
+ constructor(key, color = types_1.RBTNColor.BLACK) {
19
+ this.key = key;
20
+ this.color = color;
12
21
  this.parent = null;
13
22
  this.left = null;
14
23
  this.right = null;
15
24
  }
16
25
  }
17
26
  exports.RBTreeNode = RBTreeNode;
27
+ exports.NIL = new RBTreeNode(0);
28
+ /**
29
+ * 1. Each node is either red or black.
30
+ * 2. The root node is always black.
31
+ * 3. Leaf nodes are typically NIL nodes and are considered black.
32
+ * 4. Red nodes must have black children.
33
+ * 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
34
+ */
18
35
  class RedBlackTree {
19
36
  constructor() {
20
- this._NIL = new RBTreeNode();
21
- this.NIL.color = types_1.RBTNColor.BLACK;
22
- this.NIL.left = null;
23
- this.NIL.right = null;
24
- this._root = this.NIL;
37
+ this._root = exports.NIL;
25
38
  }
26
39
  _root;
27
40
  get root() {
28
41
  return this._root;
29
42
  }
30
- _NIL;
31
- get NIL() {
32
- return this._NIL;
33
- }
34
43
  /**
35
44
  * The `insert` function inserts a new node with a given key into a red-black tree and fixes any
36
45
  * violations of the red-black tree properties.
@@ -39,15 +48,12 @@ class RedBlackTree {
39
48
  * @returns The function does not explicitly return anything.
40
49
  */
41
50
  insert(key) {
42
- const node = new RBTreeNode();
43
- node.parent = null;
44
- node.key = key;
45
- node.left = this.NIL;
46
- node.right = this.NIL;
47
- node.color = types_1.RBTNColor.RED;
51
+ const node = new RBTreeNode(key, types_1.RBTNColor.RED);
52
+ node.left = exports.NIL;
53
+ node.right = exports.NIL;
48
54
  let y = null;
49
55
  let x = this.root;
50
- while (x !== this.NIL) {
56
+ while (x !== exports.NIL) {
51
57
  y = x;
52
58
  if (node.key < x.key) {
53
59
  x = x.left;
@@ -84,9 +90,9 @@ class RedBlackTree {
84
90
  */
85
91
  delete(key) {
86
92
  const helper = (node) => {
87
- let z = this.NIL;
93
+ let z = exports.NIL;
88
94
  let x, y;
89
- while (node !== this.NIL) {
95
+ while (node !== exports.NIL) {
90
96
  if (node.key === key) {
91
97
  z = node;
92
98
  }
@@ -97,17 +103,16 @@ class RedBlackTree {
97
103
  node = node.left;
98
104
  }
99
105
  }
100
- if (z === this.NIL) {
101
- console.log("Couldn't find key in the tree");
106
+ if (z === exports.NIL) {
102
107
  return;
103
108
  }
104
109
  y = z;
105
110
  let yOriginalColor = y.color;
106
- if (z.left === this.NIL) {
111
+ if (z.left === exports.NIL) {
107
112
  x = z.right;
108
113
  this._rbTransplant(z, z.right);
109
114
  }
110
- else if (z.right === this.NIL) {
115
+ else if (z.right === exports.NIL) {
111
116
  x = z.left;
112
117
  this._rbTransplant(z, z.left);
113
118
  }
@@ -128,12 +133,15 @@ class RedBlackTree {
128
133
  y.left.parent = y;
129
134
  y.color = z.color;
130
135
  }
131
- if (yOriginalColor === 0) {
136
+ if (yOriginalColor === types_1.RBTNColor.BLACK) {
132
137
  this._fixDelete(x);
133
138
  }
134
139
  };
135
140
  helper(this.root);
136
141
  }
142
+ isRealNode(node) {
143
+ return node !== exports.NIL && node !== null;
144
+ }
137
145
  /**
138
146
  * The function `getNode` is a recursive depth-first search algorithm that searches for a node with a
139
147
  * given key in a red-black tree.
@@ -146,13 +154,17 @@ class RedBlackTree {
146
154
  */
147
155
  getNode(key, beginRoot = this.root) {
148
156
  const dfs = (node) => {
149
- if (node === this.NIL || key === node.key) {
150
- return node;
157
+ if (this.isRealNode(node)) {
158
+ if (key === node.key) {
159
+ return node;
160
+ }
161
+ if (key < node.key)
162
+ return dfs(node.left);
163
+ return dfs(node.right);
151
164
  }
152
- if (key < node.key) {
153
- return dfs(node.left);
165
+ else {
166
+ return null;
154
167
  }
155
- return dfs(node.right);
156
168
  };
157
169
  return dfs(beginRoot);
158
170
  }
@@ -162,8 +174,8 @@ class RedBlackTree {
162
174
  * a Red-Black Tree.
163
175
  * @returns The leftmost node in the given RBTreeNode.
164
176
  */
165
- getLeftMost(node) {
166
- while (node.left !== null && node.left !== this.NIL) {
177
+ getLeftMost(node = this.root) {
178
+ while (node.left !== null && node.left !== exports.NIL) {
167
179
  node = node.left;
168
180
  }
169
181
  return node;
@@ -174,7 +186,7 @@ class RedBlackTree {
174
186
  * @returns the rightmost node in a red-black tree.
175
187
  */
176
188
  getRightMost(node) {
177
- while (node.right !== null && node.right !== this.NIL) {
189
+ while (node.right !== null && node.right !== exports.NIL) {
178
190
  node = node.right;
179
191
  }
180
192
  return node;
@@ -185,11 +197,11 @@ class RedBlackTree {
185
197
  * @returns the successor of the given RBTreeNode.
186
198
  */
187
199
  getSuccessor(x) {
188
- if (x.right !== this.NIL) {
200
+ if (x.right !== exports.NIL) {
189
201
  return this.getLeftMost(x.right);
190
202
  }
191
203
  let y = x.parent;
192
- while (y !== this.NIL && y !== null && x === y.right) {
204
+ while (y !== exports.NIL && y !== null && x === y.right) {
193
205
  x = y;
194
206
  y = y.parent;
195
207
  }
@@ -202,16 +214,69 @@ class RedBlackTree {
202
214
  * @returns the predecessor of the given RBTreeNode 'x'.
203
215
  */
204
216
  getPredecessor(x) {
205
- if (x.left !== this.NIL) {
217
+ if (x.left !== exports.NIL) {
206
218
  return this.getRightMost(x.left);
207
219
  }
208
220
  let y = x.parent;
209
- while (y !== this.NIL && x === y.left) {
221
+ while (y !== exports.NIL && x === y.left) {
210
222
  x = y;
211
223
  y = y.parent;
212
224
  }
213
225
  return y;
214
226
  }
227
+ print(beginRoot = this.root) {
228
+ const display = (root) => {
229
+ const [lines, , ,] = _displayAux(root);
230
+ for (const line of lines) {
231
+ console.log(line);
232
+ }
233
+ };
234
+ const _displayAux = (node) => {
235
+ if (node === null) {
236
+ return [[], 0, 0, 0];
237
+ }
238
+ if (node.right === null && node.left === null) {
239
+ const line = `${node.key}`;
240
+ const width = line.length;
241
+ const height = 1;
242
+ const middle = Math.floor(width / 2);
243
+ return [[line], width, height, middle];
244
+ }
245
+ if (node.right === null) {
246
+ const [lines, n, p, x] = _displayAux(node.left);
247
+ const s = `${node.key}`;
248
+ const u = s.length;
249
+ const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s;
250
+ const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u);
251
+ const shifted_lines = lines.map(line => line + ' '.repeat(u));
252
+ return [[first_line, second_line, ...shifted_lines], n + u, p + 2, n + Math.floor(u / 2)];
253
+ }
254
+ if (node.left === null) {
255
+ const [lines, n, p, u] = _displayAux(node.right);
256
+ const s = `${node.key}`;
257
+ const x = s.length;
258
+ const first_line = s + '_'.repeat(x) + ' '.repeat(n - x);
259
+ const second_line = ' '.repeat(u + x) + '\\' + ' '.repeat(n - x - 1);
260
+ const shifted_lines = lines.map(line => ' '.repeat(u) + line);
261
+ return [[first_line, second_line, ...shifted_lines], n + x, p + 2, Math.floor(u / 2)];
262
+ }
263
+ const [left, n, p, x] = _displayAux(node.left);
264
+ const [right, m, q, y] = _displayAux(node.right);
265
+ const s = `${node.key}`;
266
+ const u = s.length;
267
+ const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s + '_'.repeat(y) + ' '.repeat(m - y);
268
+ const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u + y) + '\\' + ' '.repeat(m - y - 1);
269
+ if (p < q) {
270
+ left.push(...new Array(q - p).fill(' '.repeat(n)));
271
+ }
272
+ else if (q < p) {
273
+ right.push(...new Array(p - q).fill(' '.repeat(m)));
274
+ }
275
+ const zipped_lines = left.map((a, i) => a + ' '.repeat(u) + right[i]);
276
+ return [[first_line, second_line, ...zipped_lines], n + m + u, Math.max(p, q) + 2, n + Math.floor(u / 2)];
277
+ };
278
+ display(beginRoot);
279
+ }
215
280
  /**
216
281
  * The function performs a left rotation on a red-black tree node.
217
282
  * @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
@@ -219,7 +284,7 @@ class RedBlackTree {
219
284
  _leftRotate(x) {
220
285
  const y = x.right;
221
286
  x.right = y.left;
222
- if (y.left !== this.NIL) {
287
+ if (y.left !== exports.NIL) {
223
288
  y.left.parent = x;
224
289
  }
225
290
  y.parent = x.parent;
@@ -243,7 +308,7 @@ class RedBlackTree {
243
308
  _rightRotate(x) {
244
309
  const y = x.left;
245
310
  x.left = y.right;
246
- if (y.right !== this.NIL) {
311
+ if (y.right !== exports.NIL) {
247
312
  y.right.parent = x;
248
313
  }
249
314
  y.parent = x.parent;
@@ -266,7 +331,7 @@ class RedBlackTree {
266
331
  */
267
332
  _fixDelete(x) {
268
333
  let s;
269
- while (x !== this.root && x.color === 0) {
334
+ while (x !== this.root && x.color === types_1.RBTNColor.BLACK) {
270
335
  if (x === x.parent.left) {
271
336
  s = x.parent.right;
272
337
  if (s.color === 1) {
@@ -275,12 +340,12 @@ class RedBlackTree {
275
340
  this._leftRotate(x.parent);
276
341
  s = x.parent.right;
277
342
  }
278
- if (s.left.color === 0 && s.right.color === 0) {
343
+ if (s.left !== null && s.left.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
279
344
  s.color = types_1.RBTNColor.RED;
280
345
  x = x.parent;
281
346
  }
282
347
  else {
283
- if (s.right.color === 0) {
348
+ if (s.right.color === types_1.RBTNColor.BLACK) {
284
349
  s.left.color = types_1.RBTNColor.BLACK;
285
350
  s.color = types_1.RBTNColor.RED;
286
351
  this._rightRotate(s);
@@ -301,12 +366,12 @@ class RedBlackTree {
301
366
  this._rightRotate(x.parent);
302
367
  s = x.parent.left;
303
368
  }
304
- if (s.right.color === 0 && s.right.color === 0) {
369
+ if (s.right.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
305
370
  s.color = types_1.RBTNColor.RED;
306
371
  x = x.parent;
307
372
  }
308
373
  else {
309
- if (s.left.color === 0) {
374
+ if (s.left.color === types_1.RBTNColor.BLACK) {
310
375
  s.right.color = types_1.RBTNColor.BLACK;
311
376
  s.color = types_1.RBTNColor.RED;
312
377
  this._leftRotate(s);
@@ -160,7 +160,7 @@ class TreeMultiset extends avl_tree_1.AVLTree {
160
160
  else if (parent.right === undefined) {
161
161
  parent.right = newNode;
162
162
  if (newNode !== null) {
163
- this._size = (this.size + 1);
163
+ this._size = this.size + 1;
164
164
  this._setCount(this.count + newNode.count);
165
165
  }
166
166
  return parent.right;
@@ -263,7 +263,7 @@ class TreeMultiset extends avl_tree_1.AVLTree {
263
263
  const bstDeletedResult = [];
264
264
  if (!this.root)
265
265
  return bstDeletedResult;
266
- const curr = this.get(identifier, callback);
266
+ const curr = this.getNode(identifier, callback);
267
267
  if (!curr)
268
268
  return bstDeletedResult;
269
269
  const parent = curr?.parent ? curr.parent : null;