directed-graph-typed 1.39.6 → 1.41.0

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 (96) hide show
  1. package/dist/data-structures/binary-tree/avl-tree.js +0 -1
  2. package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +0 -3
  3. package/dist/data-structures/binary-tree/binary-indexed-tree.js +2 -11
  4. package/dist/data-structures/binary-tree/binary-tree.d.ts +13 -20
  5. package/dist/data-structures/binary-tree/binary-tree.js +30 -31
  6. package/dist/data-structures/binary-tree/bst.d.ts +2 -2
  7. package/dist/data-structures/binary-tree/bst.js +4 -4
  8. package/dist/data-structures/binary-tree/rb-tree.d.ts +95 -11
  9. package/dist/data-structures/binary-tree/rb-tree.js +379 -18
  10. package/dist/data-structures/binary-tree/segment-tree.d.ts +10 -26
  11. package/dist/data-structures/binary-tree/segment-tree.js +10 -58
  12. package/dist/data-structures/binary-tree/tree-multiset.d.ts +1 -1
  13. package/dist/data-structures/binary-tree/tree-multiset.js +6 -6
  14. package/dist/data-structures/graph/abstract-graph.d.ts +5 -24
  15. package/dist/data-structures/graph/abstract-graph.js +4 -43
  16. package/dist/data-structures/graph/directed-graph.d.ts +4 -10
  17. package/dist/data-structures/graph/directed-graph.js +2 -20
  18. package/dist/data-structures/graph/map-graph.d.ts +4 -10
  19. package/dist/data-structures/graph/map-graph.js +2 -20
  20. package/dist/data-structures/graph/undirected-graph.d.ts +1 -8
  21. package/dist/data-structures/graph/undirected-graph.js +1 -14
  22. package/dist/data-structures/hash/coordinate-map.d.ts +0 -1
  23. package/dist/data-structures/hash/coordinate-map.js +0 -3
  24. package/dist/data-structures/hash/coordinate-set.d.ts +0 -1
  25. package/dist/data-structures/hash/coordinate-set.js +0 -3
  26. package/dist/data-structures/hash/hash-map.d.ts +8 -14
  27. package/dist/data-structures/hash/hash-map.js +4 -22
  28. package/dist/data-structures/hash/hash-table.d.ts +6 -9
  29. package/dist/data-structures/hash/hash-table.js +0 -9
  30. package/dist/data-structures/heap/heap.d.ts +12 -6
  31. package/dist/data-structures/heap/heap.js +40 -22
  32. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +6 -14
  33. package/dist/data-structures/linked-list/doubly-linked-list.js +18 -42
  34. package/dist/data-structures/linked-list/singly-linked-list.d.ts +5 -11
  35. package/dist/data-structures/linked-list/singly-linked-list.js +17 -35
  36. package/dist/data-structures/linked-list/skip-linked-list.d.ts +29 -10
  37. package/dist/data-structures/linked-list/skip-linked-list.js +62 -17
  38. package/dist/data-structures/matrix/matrix.d.ts +1 -1
  39. package/dist/data-structures/matrix/matrix2d.d.ts +1 -1
  40. package/dist/data-structures/matrix/navigator.d.ts +4 -4
  41. package/dist/data-structures/queue/deque.d.ts +8 -12
  42. package/dist/data-structures/queue/deque.js +31 -43
  43. package/dist/data-structures/queue/queue.d.ts +20 -5
  44. package/dist/data-structures/queue/queue.js +35 -18
  45. package/dist/data-structures/stack/stack.d.ts +2 -1
  46. package/dist/data-structures/stack/stack.js +10 -7
  47. package/dist/data-structures/tree/tree.d.ts +3 -9
  48. package/dist/data-structures/tree/tree.js +3 -21
  49. package/dist/data-structures/trie/trie.d.ts +6 -12
  50. package/dist/data-structures/trie/trie.js +6 -24
  51. package/dist/interfaces/binary-tree.d.ts +1 -1
  52. package/dist/types/data-structures/binary-tree/bst.d.ts +1 -1
  53. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -7
  54. package/dist/types/data-structures/binary-tree/rb-tree.js +11 -6
  55. package/package.json +2 -2
  56. package/src/data-structures/binary-tree/avl-tree.ts +2 -4
  57. package/src/data-structures/binary-tree/binary-indexed-tree.ts +3 -15
  58. package/src/data-structures/binary-tree/binary-tree.ts +40 -43
  59. package/src/data-structures/binary-tree/bst.ts +9 -10
  60. package/src/data-structures/binary-tree/rb-tree.ts +415 -355
  61. package/src/data-structures/binary-tree/segment-tree.ts +16 -83
  62. package/src/data-structures/binary-tree/tree-multiset.ts +8 -9
  63. package/src/data-structures/graph/abstract-graph.ts +21 -67
  64. package/src/data-structures/graph/directed-graph.ts +13 -39
  65. package/src/data-structures/graph/map-graph.ts +7 -32
  66. package/src/data-structures/graph/undirected-graph.ts +9 -26
  67. package/src/data-structures/hash/coordinate-map.ts +0 -4
  68. package/src/data-structures/hash/coordinate-set.ts +0 -4
  69. package/src/data-structures/hash/hash-map.ts +13 -37
  70. package/src/data-structures/hash/hash-table.ts +6 -18
  71. package/src/data-structures/hash/tree-map.ts +2 -1
  72. package/src/data-structures/hash/tree-set.ts +2 -1
  73. package/src/data-structures/heap/heap.ts +58 -30
  74. package/src/data-structures/heap/max-heap.ts +1 -1
  75. package/src/data-structures/heap/min-heap.ts +1 -1
  76. package/src/data-structures/linked-list/doubly-linked-list.ts +26 -60
  77. package/src/data-structures/linked-list/singly-linked-list.ts +24 -49
  78. package/src/data-structures/linked-list/skip-linked-list.ts +73 -25
  79. package/src/data-structures/matrix/matrix.ts +2 -2
  80. package/src/data-structures/matrix/matrix2d.ts +1 -1
  81. package/src/data-structures/matrix/navigator.ts +4 -4
  82. package/src/data-structures/matrix/vector2d.ts +2 -1
  83. package/src/data-structures/priority-queue/max-priority-queue.ts +1 -1
  84. package/src/data-structures/priority-queue/min-priority-queue.ts +1 -1
  85. package/src/data-structures/priority-queue/priority-queue.ts +1 -1
  86. package/src/data-structures/queue/deque.ts +38 -53
  87. package/src/data-structures/queue/queue.ts +38 -20
  88. package/src/data-structures/stack/stack.ts +13 -9
  89. package/src/data-structures/tree/tree.ts +7 -33
  90. package/src/data-structures/trie/trie.ts +14 -40
  91. package/src/interfaces/binary-tree.ts +1 -1
  92. package/src/types/data-structures/binary-tree/bst.ts +1 -1
  93. package/src/types/data-structures/binary-tree/rb-tree.ts +6 -6
  94. package/src/types/data-structures/matrix/navigator.ts +1 -1
  95. package/src/types/utils/utils.ts +1 -1
  96. package/src/types/utils/validate-type.ts +2 -2
@@ -1,366 +1,426 @@
1
- import {BTNKey, RBColor, RBTreeNodeNested, RBTreeOptions} from '../../types';
2
- import {IBinaryTree} from '../../interfaces';
3
- import {BST, BSTNode} from './bst';
4
-
5
- export class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V>> extends BSTNode<V, N> {
6
- constructor(key: BTNKey, value?: V) {
7
- super(key, value);
8
- this._color = RBColor.RED;
1
+ import {RBTNColor} from "../../types";
2
+
3
+ export class RBTreeNode {
4
+ key: number = 0;
5
+ parent: RBTreeNode;
6
+ left: RBTreeNode;
7
+ right: RBTreeNode;
8
+ color: number = RBTNColor.BLACK;
9
+
10
+ constructor() {
11
+ this.parent = null as unknown as RBTreeNode;
12
+ this.left = null as unknown as RBTreeNode;
13
+ this.right = null as unknown as RBTreeNode;
14
+ }
15
+ }
16
+
17
+ export class RedBlackTree {
18
+
19
+ constructor() {
20
+ this._NIL = new RBTreeNode();
21
+ this.NIL.color = RBTNColor.BLACK;
22
+ this.NIL.left = null as unknown as RBTreeNode;
23
+ this.NIL.right = null as unknown as RBTreeNode;
24
+ this._root = this.NIL;
9
25
  }
10
26
 
11
- private _color: RBColor;
27
+ protected _root: RBTreeNode;
12
28
 
13
- get color(): RBColor {
14
- return this._color;
29
+ get root(): RBTreeNode {
30
+ return this._root;
15
31
  }
16
32
 
17
- set color(value: RBColor) {
18
- this._color = value;
33
+ protected _NIL: RBTreeNode;
34
+
35
+ get NIL(): RBTreeNode {
36
+ return this._NIL;
37
+ }
38
+
39
+ /**
40
+ * The `insert` function inserts a new node with a given key into a red-black tree and fixes any
41
+ * violations of the red-black tree properties.
42
+ * @param {number} key - The key parameter is a number that represents the value to be inserted into
43
+ * the RBTree.
44
+ * @returns The function does not explicitly return anything.
45
+ */
46
+ insert(key: number): void {
47
+
48
+ const node: RBTreeNode = new RBTreeNode();
49
+ node.parent = null as unknown as RBTreeNode;
50
+ node.key = key;
51
+ node.left = this.NIL;
52
+ node.right = this.NIL;
53
+ node.color = RBTNColor.RED;
54
+
55
+ let y: RBTreeNode = null as unknown as RBTreeNode;
56
+ let x: RBTreeNode = this.root;
57
+
58
+ while (x !== this.NIL) {
59
+ y = x;
60
+ if (node.key < x.key) {
61
+ x = x.left;
62
+ } else {
63
+ x = x.right;
64
+ }
65
+ }
66
+
67
+ node.parent = y;
68
+ if (y === null) {
69
+ this._root = node;
70
+ } else if (node.key < y.key) {
71
+ y.left = node;
72
+ } else {
73
+ y.right = node;
74
+ }
75
+
76
+ if (node.parent === null) {
77
+ node.color = RBTNColor.BLACK;
78
+ return;
79
+ }
80
+
81
+ if (node.parent.parent === null) {
82
+ return;
83
+ }
84
+
85
+ this._fixInsert(node);
19
86
  }
20
- }
21
87
 
22
- export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNested<V>>>
23
- extends BST<V, N>
24
- implements IBinaryTree<V, N>
25
- {
26
- constructor(options?: RBTreeOptions) {
27
- super(options);
88
+ /**
89
+ * The `delete` function in TypeScript is used to remove a node with a specific key from a red-black
90
+ * tree.
91
+ * @param {RBTreeNode} node - The `node` parameter is of type `RBTreeNode` and represents the current
92
+ * node being processed in the delete operation.
93
+ * @returns The `delete` function does not return anything. It has a return type of `void`.
94
+ */
95
+ delete(key: number): void {
96
+ const helper = (node: RBTreeNode): void => {
97
+
98
+ let z: RBTreeNode = this.NIL;
99
+ let x: RBTreeNode, y: RBTreeNode;
100
+ while (node !== this.NIL) {
101
+ if (node.key === key) {
102
+ z = node;
103
+ }
104
+
105
+ if (node.key <= key) {
106
+ node = node.right;
107
+ } else {
108
+ node = node.left;
109
+ }
110
+ }
111
+
112
+ if (z === this.NIL) {
113
+ console.log("Couldn't find key in the tree");
114
+ return;
115
+ }
116
+
117
+ y = z;
118
+ let yOriginalColor: number = y.color;
119
+ if (z.left === this.NIL) {
120
+ x = z.right;
121
+ this._rbTransplant(z, z.right);
122
+ } else if (z.right === this.NIL) {
123
+ x = z.left;
124
+ this._rbTransplant(z, z.left);
125
+ } else {
126
+ y = this.getLeftMost(z.right);
127
+ yOriginalColor = y.color;
128
+ x = y.right;
129
+ if (y.parent === z) {
130
+ x.parent = y;
131
+ } else {
132
+ this._rbTransplant(y, y.right);
133
+ y.right = z.right;
134
+ y.right.parent = y;
135
+ }
136
+
137
+ this._rbTransplant(z, y);
138
+ y.left = z.left;
139
+ y.left.parent = y;
140
+ y.color = z.color;
141
+ }
142
+ if (yOriginalColor === 0) {
143
+ this._fixDelete(x);
144
+ }
145
+ }
146
+ helper(this.root);
28
147
  }
29
148
 
30
- override createNode(key: BTNKey, value?: V): N {
31
- return new RBTreeNode(key, value) as N;
149
+ /**
150
+ * The function `getNode` is a recursive depth-first search algorithm that searches for a node with a
151
+ * given key in a red-black tree.
152
+ * @param {number} key - The key parameter is a number that represents the value we are searching for
153
+ * in the RBTree.
154
+ * @param beginRoot - The `beginRoot` parameter is an optional parameter that represents the starting
155
+ * point for the search in the binary search tree. If no value is provided for `beginRoot`, it
156
+ * defaults to the root of the binary search tree (`this.root`).
157
+ * @returns a RBTreeNode.
158
+ */
159
+ getNode(key: number, beginRoot = this.root): RBTreeNode {
160
+ const dfs = (node: RBTreeNode): RBTreeNode => {
161
+ if (node === this.NIL || key === node.key) {
162
+ return node;
163
+ }
164
+
165
+ if (key < node.key) {
166
+ return dfs(node.left);
167
+ }
168
+ return dfs(node.right);
169
+ }
170
+ return dfs(beginRoot);
32
171
  }
33
172
 
34
- // override add(keyOrNode: BTNKey | N | null, value?: V): N | null | undefined {
35
- // const inserted = super.add(keyOrNode, value);
36
- // if (inserted) this._fixInsertViolation(inserted);
37
- // return inserted;
38
- // }
39
- //
40
- // // Method for fixing insert violations in a red-black tree
41
- // private _fixInsertViolation(node: N) {
42
- // while (node !== this.root! && node.color === RBColor.RED && node.parent!.color === RBColor.RED) {
43
- // const parent = node.parent!;
44
- // const grandparent = parent.parent!;
45
- // let uncle: N | null | undefined = null;
46
- //
47
- // if (parent === grandparent.left) {
48
- // uncle = grandparent.right;
49
- //
50
- // // Case 1: The uncle node is red
51
- // if (uncle && uncle.color === RBColor.RED) {
52
- // grandparent.color = RBColor.RED;
53
- // parent.color = RBColor.BLACK;
54
- // uncle.color = RBColor.BLACK;
55
- // node = grandparent;
56
- // } else {
57
- // // Case 2: The uncle node is black, and the current node is a right child
58
- // if (node === parent.right) {
59
- // this._rotateLeft(parent);
60
- // node = parent;
61
- // // Update parent reference
62
- // node.parent = grandparent;
63
- // parent.parent = node;
64
- // }
65
- //
66
- // // Case 3: The uncle node is black, and the current node is a left child
67
- // parent.color = RBColor.BLACK;
68
- // grandparent.color = RBColor.RED;
69
- // this._rotateRight(grandparent);
70
- // }
71
- // } else {
72
- // // Symmetric case: The parent is the right child of the grandparent
73
- // uncle = grandparent.left;
74
- //
75
- // // Case 1: The uncle node is red
76
- // if (uncle && uncle.color === RBColor.RED) {
77
- // grandparent.color = RBColor.RED;
78
- // parent.color = RBColor.BLACK;
79
- // uncle.color = RBColor.BLACK;
80
- // node = grandparent;
81
- // } else {
82
- // // Case 2: The uncle node is black, and the current node is a left child
83
- // if (node === parent.left) {
84
- // this._rotateRight(parent);
85
- // node = parent;
86
- // // Update parent reference
87
- // node.parent = grandparent;
88
- // parent.parent = node;
89
- // }
90
- //
91
- // // Case 3: The uncle node is black, and the current node is a right child
92
- // parent.color = RBColor.BLACK;
93
- // grandparent.color = RBColor.RED;
94
- // this._rotateLeft(grandparent);
95
- // }
96
- // }
97
- // }
98
- //
99
- // // The root node is always black
100
- // this.root!.color = RBColor.BLACK;
101
- // }
102
- //
103
- // // Left rotation operation
104
- // private _rotateLeft(node: N) {
105
- // const rightChild = node.right;
106
- // node.right = rightChild!.left;
107
- //
108
- // if (rightChild!.left) {
109
- // rightChild!.left.parent = node;
110
- // }
111
- //
112
- // rightChild!.parent = node.parent;
113
- //
114
- // if (node === this.root) {
115
- // // @ts-ignore
116
- // this._setRoot(rightChild);
117
- // } else if (node === node.parent!.left) {
118
- // node.parent!.left = rightChild;
119
- // } else {
120
- // node.parent!.right = rightChild;
121
- // }
122
- //
123
- // rightChild!.left = node;
124
- // node.parent = rightChild;
125
- // }
126
- //
127
- // // Right rotation operation
128
- // private _rotateRight(node: N) {
129
- // const leftChild = node.left;
130
- // node.left = leftChild!.right;
131
- //
132
- // if (leftChild!.right) {
133
- // leftChild!.right.parent = node;
134
- // }
135
- //
136
- // leftChild!.parent = node.parent;
137
- //
138
- // if (node === this.root) {
139
- // // @ts-ignore
140
- // this._setRoot(leftChild);
141
- // } else if (node === node.parent!.right) {
142
- // node.parent!.right = leftChild;
143
- // } else {
144
- // node.parent!.left = leftChild;
145
- // }
146
- //
147
- // leftChild!.right = node;
148
- // node.parent = leftChild;
149
- // }
150
- //
151
- // private _isNodeRed(node: N | null | undefined): boolean {
152
- // return node ? node.color === RBColor.RED : false;
153
- // }
154
- //
155
- // // Find the sibling node
156
- // private _findSibling(node: N): N | null | undefined {
157
- // if (!node.parent) {
158
- // return undefined;
159
- // }
160
- //
161
- // return node === node.parent.left ? node.parent.right : node.parent.left;
162
- // }
163
- //
164
- // // Remove a node
165
- // private _removeNode(node: N, replacement: N | null | undefined): void {
166
- // if (node === this.root && !replacement) {
167
- // // If there's only the root node and no replacement, simply delete the root node
168
- // this._setRoot(null);
169
- // } else if (node === this.root || this._isNodeRed(node)) {
170
- // // If the node is the root or a red node, delete it directly
171
- // if (node.parent!.left === node) {
172
- // node.parent!.left = replacement;
173
- // } else {
174
- // node.parent!.right = replacement;
175
- // }
176
- //
177
- // if (replacement) {
178
- // replacement.parent = node.parent!;
179
- // replacement.color = RBColor.BLACK; // Set the replacement node's color to black
180
- // }
181
- // } else {
182
- // // If the node is a black node, perform removal and repair
183
- // const sibling = this._findSibling(node);
184
- //
185
- // if (node.parent!.left === node) {
186
- // node.parent!.left = replacement;
187
- // } else {
188
- // node.parent!.right = replacement;
189
- // }
190
- //
191
- // if (replacement) {
192
- // replacement.parent = node.parent;
193
- // }
194
- //
195
- // if (!this._isNodeRed(sibling)) {
196
- // // If the sibling node is black, perform repair
197
- // this._fixDeleteViolation(replacement || node);
198
- // }
199
- // }
200
- //
201
- // if (node.parent) {
202
- // node.parent = null;
203
- // }
204
- // node.left = null;
205
- // node.right = null;
206
- // }
207
- //
208
- // override delete(keyOrNode: BTNKey | N): BinaryTreeDeletedResult<N>[] {
209
- // const node = this.get(keyOrNode);
210
- // const result: BinaryTreeDeletedResult<N>[] = [{deleted: undefined, needBalanced: null}];
211
- // if (!node) return result; // Node does not exist
212
- //
213
- // const replacement = this._getReplacementNode(node);
214
- //
215
- // const isRed = this._isNodeRed(node);
216
- // const isRedReplacement = this._isNodeRed(replacement);
217
- //
218
- // // Remove the node
219
- // this._removeNode(node, replacement);
220
- //
221
- // if (isRed || isRedReplacement) {
222
- // // If the removed node is red or the replacement node is red, no repair is needed
223
- // return result;
224
- // }
225
- //
226
- // // Repair any violation introduced by the removal
227
- // this._fixDeleteViolation(replacement);
228
- //
229
- // return result;
230
- // }
231
- //
232
- // // Repair operation after node deletion
233
- // private _fixDeleteViolation(node: N | null | undefined) {
234
- // let sibling;
235
- //
236
- // while (node && node !== this.root && !this._isNodeRed(node)) {
237
- // if (node === node.parent!.left) {
238
- // sibling = node.parent!.right;
239
- //
240
- // if (sibling && this._isNodeRed(sibling)) {
241
- // // Case 1: The sibling node is red
242
- // sibling.color = RBColor.BLACK;
243
- // node.parent!.color = RBColor.RED;
244
- // this._rotateLeft(node.parent!);
245
- // sibling = node.parent!.right;
246
- // }
247
- //
248
- // if (!sibling) return;
249
- //
250
- // if (
251
- // (!sibling.left || sibling.left.color === RBColor.BLACK) &&
252
- // (!sibling.right || sibling.right.color === RBColor.BLACK)
253
- // ) {
254
- // // Case 2: The sibling node and its children are all black
255
- // sibling.color = RBColor.RED;
256
- // node = node.parent!;
257
- // } else {
258
- // if (!(sibling.right && this._isNodeRed(sibling.right))) {
259
- // // Case 3: The sibling node is black, and the left child is red, the right child is black
260
- // sibling.left!.color = RBColor.BLACK;
261
- // sibling.color = RBColor.RED;
262
- // this._rotateRight(sibling);
263
- // sibling = node.parent!.right;
264
- // }
265
- //
266
- // // Case 4: The sibling node is black, and the right child is red
267
- // if (sibling) {
268
- // sibling.color = node.parent!.color;
269
- // }
270
- // if (node.parent) {
271
- // node.parent.color = RBColor.BLACK;
272
- // }
273
- // if (sibling!.right) {
274
- // sibling!.right.color = RBColor.BLACK;
275
- // }
276
- // this._rotateLeft(node.parent!);
277
- // node = this.root;
278
- // }
279
- // } else {
280
- // // Symmetric case: The parent is the right child of the grandparent
281
- // sibling = node.parent!.left;
282
- //
283
- // if (sibling && this._isNodeRed(sibling)) {
284
- // // Case 1: The sibling node is red
285
- // sibling.color = RBColor.BLACK;
286
- // node.parent!.color = RBColor.RED;
287
- // this._rotateRight(node.parent!);
288
- // sibling = node.parent!.left;
289
- // }
290
- //
291
- // if (!sibling) return;
292
- //
293
- // if (
294
- // (!sibling.left || sibling.left.color === RBColor.BLACK) &&
295
- // (!sibling.right || sibling.right.color === RBColor.BLACK)
296
- // ) {
297
- // // Case 2: The sibling node and its children are all black
298
- // sibling.color = RBColor.RED;
299
- // node = node.parent!;
300
- // } else {
301
- // if (!(sibling.left && this._isNodeRed(sibling.left))) {
302
- // // Case 3: The sibling node is black, and the right child is red, the left child is black
303
- // sibling.right!.color = RBColor.BLACK;
304
- // sibling.color = RBColor.RED;
305
- // this._rotateLeft(sibling);
306
- // sibling = node.parent!.left;
307
- // }
308
- //
309
- // // Case 4: The sibling node is black, and the left child is red
310
- // if (sibling) {
311
- // sibling.color = node.parent!.color;
312
- // }
313
- // if (node.parent) {
314
- // node.parent.color = RBColor.BLACK;
315
- // }
316
- // if (sibling!.left) {
317
- // sibling!.left.color = RBColor.BLACK;
318
- // }
319
- // this._rotateRight(node.parent!);
320
- // node = this.root;
321
- // }
322
- // }
323
- // }
324
- //
325
- // if (node) {
326
- // node.color = RBColor.BLACK;
327
- // }
328
- // }
329
- //
330
- // private _findMin(node: N): N {
331
- // while (node.left) {
332
- // node = node.left;
333
- // }
334
- // return node;
335
- // }
336
- //
337
- // // Get the replacement node
338
- // private _getReplacementNode(node: N): N | null | undefined {
339
- // if (node.left && node.right) {
340
- // return this._findSuccessor(node);
341
- // }
342
- //
343
- // if (!node.left && !node.right) {
344
- // return null; // Return a fake node with color black
345
- // }
346
- //
347
- // return node.left || node.right;
348
- // }
349
- //
350
- // // Find the successor node
351
- // private _findSuccessor(node: N): N | null | undefined {
352
- // if (node.right) {
353
- // // If the node has a right child, find the minimum node in the right subtree as the successor
354
- // return this._findMin(node.right);
355
- // }
356
- //
357
- // // Otherwise, traverse upward until finding the first parent whose left child is the current node
358
- // let parent = node.parent;
359
- // while (parent && node === parent.right) {
360
- // node = parent;
361
- // parent = parent.parent;
362
- // }
363
- //
364
- // return parent;
365
- // }
366
- }
173
+
174
+ /**
175
+ * The function returns the leftmost node in a red-black tree.
176
+ * @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode, which represents a node in
177
+ * a Red-Black Tree.
178
+ * @returns The leftmost node in the given RBTreeNode.
179
+ */
180
+ getLeftMost(node: RBTreeNode): RBTreeNode {
181
+ while (node.left !== null && node.left !== this.NIL) {
182
+ node = node.left;
183
+ }
184
+ return node;
185
+ }
186
+
187
+
188
+ /**
189
+ * The function returns the rightmost node in a red-black tree.
190
+ * @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode.
191
+ * @returns the rightmost node in a red-black tree.
192
+ */
193
+ getRightMost(node: RBTreeNode): RBTreeNode {
194
+ while (node.right !== null && node.right !== this.NIL) {
195
+ node = node.right;
196
+ }
197
+ return node;
198
+ }
199
+
200
+ /**
201
+ * The function returns the successor of a given node in a red-black tree.
202
+ * @param {RBTreeNode} x - RBTreeNode - The node for which we want to find the successor.
203
+ * @returns the successor of the given RBTreeNode.
204
+ */
205
+ getSuccessor(x: RBTreeNode): RBTreeNode {
206
+
207
+ if (x.right !== this.NIL) {
208
+ return this.getLeftMost(x.right);
209
+ }
210
+
211
+ let y: RBTreeNode = x.parent;
212
+ while (y !== this.NIL && y !== null && x === y.right) {
213
+ x = y;
214
+ y = y.parent;
215
+ }
216
+ return y;
217
+ }
218
+
219
+ /**
220
+ * The function returns the predecessor of a given node in a red-black tree.
221
+ * @param {RBTreeNode} x - The parameter `x` is of type `RBTreeNode`, which represents a node in a
222
+ * Red-Black Tree.
223
+ * @returns the predecessor of the given RBTreeNode 'x'.
224
+ */
225
+ getPredecessor(x: RBTreeNode): RBTreeNode {
226
+
227
+ if (x.left !== this.NIL) {
228
+ return this.getRightMost(x.left);
229
+ }
230
+
231
+ let y: RBTreeNode = x.parent;
232
+ while (y !== this.NIL && x === y.left) {
233
+ x = y;
234
+ y = y.parent;
235
+ }
236
+
237
+ return y;
238
+ }
239
+
240
+ /**
241
+ * The function performs a left rotation on a red-black tree node.
242
+ * @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
243
+ */
244
+ protected _leftRotate(x: RBTreeNode): void {
245
+ const y: RBTreeNode = x.right;
246
+ x.right = y.left;
247
+ if (y.left !== this.NIL) {
248
+ y.left.parent = x;
249
+ }
250
+ y.parent = x.parent;
251
+ if (x.parent === null) {
252
+ this._root = y;
253
+ } else if (x === x.parent.left) {
254
+ x.parent.left = y;
255
+ } else {
256
+ x.parent.right = y;
257
+ }
258
+ y.left = x;
259
+ x.parent = y;
260
+ }
261
+
262
+ /**
263
+ * The function performs a right rotation on a red-black tree node.
264
+ * @param {RBTreeNode} x - x is a RBTreeNode, which represents the node that needs to be right
265
+ * rotated.
266
+ */
267
+ protected _rightRotate(x: RBTreeNode): void {
268
+ const y: RBTreeNode = x.left;
269
+ x.left = y.right;
270
+ if (y.right !== this.NIL) {
271
+ y.right.parent = x;
272
+ }
273
+ y.parent = x.parent;
274
+ if (x.parent === null) {
275
+ this._root = y;
276
+ } else if (x === x.parent.right) {
277
+ x.parent.right = y;
278
+ } else {
279
+ x.parent.left = y;
280
+ }
281
+ y.right = x;
282
+ x.parent = y;
283
+ }
284
+
285
+ /**
286
+ * The _fixDelete function is used to rebalance the Red-Black Tree after a node deletion.
287
+ * @param {RBTreeNode} x - The parameter `x` is of type `RBTreeNode`, which represents a node in a
288
+ * red-black tree.
289
+ */
290
+ protected _fixDelete(x: RBTreeNode): void {
291
+ let s: RBTreeNode;
292
+ while (x !== this.root && x.color === 0) {
293
+ if (x === x.parent.left) {
294
+ s = x.parent.right;
295
+ if (s.color === 1) {
296
+
297
+ s.color = RBTNColor.BLACK;
298
+ x.parent.color = RBTNColor.RED;
299
+ this._leftRotate(x.parent);
300
+ s = x.parent.right;
301
+ }
302
+
303
+ if (s.left.color === 0 && s.right.color === 0) {
304
+
305
+ s.color = RBTNColor.RED;
306
+ x = x.parent;
307
+ } else {
308
+ if (s.right.color === 0) {
309
+
310
+ s.left.color = RBTNColor.BLACK;
311
+ s.color = RBTNColor.RED;
312
+ this._rightRotate(s);
313
+ s = x.parent.right;
314
+ }
315
+
316
+ s.color = x.parent.color;
317
+ x.parent.color = RBTNColor.BLACK;
318
+ s.right.color = RBTNColor.BLACK;
319
+ this._leftRotate(x.parent);
320
+ x = this.root;
321
+ }
322
+ } else {
323
+ s = x.parent.left;
324
+ if (s.color === 1) {
325
+
326
+ s.color = RBTNColor.BLACK;
327
+ x.parent.color = RBTNColor.RED;
328
+ this._rightRotate(x.parent);
329
+ s = x.parent.left;
330
+ }
331
+
332
+ if (s.right.color === 0 && s.right.color === 0) {
333
+
334
+ s.color = RBTNColor.RED;
335
+ x = x.parent;
336
+ } else {
337
+ if (s.left.color === 0) {
338
+
339
+ s.right.color = RBTNColor.BLACK;
340
+ s.color = RBTNColor.RED;
341
+ this._leftRotate(s);
342
+ s = x.parent.left;
343
+ }
344
+
345
+ s.color = x.parent.color;
346
+ x.parent.color = RBTNColor.BLACK;
347
+ s.left.color = RBTNColor.BLACK;
348
+ this._rightRotate(x.parent);
349
+ x = this.root;
350
+ }
351
+ }
352
+ }
353
+ x.color = RBTNColor.BLACK;
354
+ }
355
+
356
+ /**
357
+ * The function `_rbTransplant` replaces one node in a red-black tree with another node.
358
+ * @param {RBTreeNode} u - The parameter "u" represents a RBTreeNode object.
359
+ * @param {RBTreeNode} v - The parameter "v" is a RBTreeNode object.
360
+ */
361
+ protected _rbTransplant(u: RBTreeNode, v: RBTreeNode): void {
362
+ if (u.parent === null) {
363
+ this._root = v;
364
+ } else if (u === u.parent.left) {
365
+ u.parent.left = v;
366
+ } else {
367
+ u.parent.right = v;
368
+ }
369
+ v.parent = u.parent;
370
+ }
371
+
372
+ /**
373
+ * The `_fixInsert` function is used to fix the red-black tree after an insertion operation.
374
+ * @param {RBTreeNode} k - The parameter `k` is a RBTreeNode object, which represents a node in a
375
+ * red-black tree.
376
+ */
377
+ protected _fixInsert(k: RBTreeNode): void {
378
+ let u: RBTreeNode;
379
+ while (k.parent.color === 1) {
380
+ if (k.parent === k.parent.parent.right) {
381
+ u = k.parent.parent.left;
382
+ if (u.color === 1) {
383
+
384
+ u.color = RBTNColor.BLACK;
385
+ k.parent.color = RBTNColor.BLACK;
386
+ k.parent.parent.color = RBTNColor.RED;
387
+ k = k.parent.parent;
388
+ } else {
389
+ if (k === k.parent.left) {
390
+
391
+ k = k.parent;
392
+ this._rightRotate(k);
393
+ }
394
+
395
+ k.parent.color = RBTNColor.BLACK;
396
+ k.parent.parent.color = RBTNColor.RED;
397
+ this._leftRotate(k.parent.parent);
398
+ }
399
+ } else {
400
+ u = k.parent.parent.right;
401
+
402
+ if (u.color === 1) {
403
+
404
+ u.color = RBTNColor.BLACK;
405
+ k.parent.color = RBTNColor.BLACK;
406
+ k.parent.parent.color = RBTNColor.RED;
407
+ k = k.parent.parent;
408
+ } else {
409
+ if (k === k.parent.right) {
410
+
411
+ k = k.parent;
412
+ this._leftRotate(k);
413
+ }
414
+
415
+ k.parent.color = RBTNColor.BLACK;
416
+ k.parent.parent.color = RBTNColor.RED;
417
+ this._rightRotate(k.parent.parent);
418
+ }
419
+ }
420
+ if (k === this.root) {
421
+ break;
422
+ }
423
+ }
424
+ this.root.color = RBTNColor.BLACK;
425
+ }
426
+ }