data-structure-typed 1.41.1 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "data-structure-typed",
3
- "version": "1.41.1",
3
+ "version": "1.41.2",
4
4
  "description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/mjs/index.js",
@@ -61,17 +61,17 @@
61
61
  "@typescript-eslint/eslint-plugin": "^6.7.4",
62
62
  "@typescript-eslint/parser": "^6.7.4",
63
63
  "auto-changelog": "^2.4.0",
64
- "avl-tree-typed": "^1.41.0",
64
+ "avl-tree-typed": "^1.41.1",
65
65
  "benchmark": "^2.1.4",
66
- "binary-tree-typed": "^1.41.0",
67
- "bst-typed": "^1.41.0",
66
+ "binary-tree-typed": "^1.41.1",
67
+ "bst-typed": "^1.41.1",
68
68
  "dependency-cruiser": "^14.1.0",
69
69
  "eslint": "^8.50.0",
70
70
  "eslint-config-prettier": "^9.0.0",
71
71
  "eslint-import-resolver-alias": "^1.1.2",
72
72
  "eslint-import-resolver-typescript": "^3.6.1",
73
73
  "eslint-plugin-import": "^2.28.1",
74
- "heap-typed": "^1.41.0",
74
+ "heap-typed": "^1.41.1",
75
75
  "istanbul-badges-readme": "^1.8.5",
76
76
  "jest": "^29.7.0",
77
77
  "prettier": "^3.0.3",
@@ -559,21 +559,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
559
559
  has<C extends BTNCallback<N, BTNKey>>(
560
560
  identifier: BTNKey,
561
561
  callback?: C,
562
- beginRoot?: N,
562
+ beginRoot?: N | null,
563
563
  iterationType?: IterationType
564
564
  ): boolean;
565
565
 
566
566
  has<C extends BTNCallback<N, N>>(
567
567
  identifier: N | null,
568
568
  callback?: C,
569
- beginRoot?: N,
569
+ beginRoot?: N | null,
570
570
  iterationType?: IterationType
571
571
  ): boolean;
572
572
 
573
573
  has<C extends BTNCallback<N>>(
574
574
  identifier: ReturnType<C> | null,
575
575
  callback: C,
576
- beginRoot?: N,
576
+ beginRoot?: N | null,
577
577
  iterationType?: IterationType
578
578
  ): boolean;
579
579
 
@@ -601,28 +601,28 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
601
601
  iterationType = this.iterationType
602
602
  ): boolean {
603
603
  if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
604
- // TODO may support finding node by value equal
604
+
605
605
  return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
606
606
  }
607
607
 
608
608
  getNode<C extends BTNCallback<N, BTNKey>>(
609
609
  identifier: BTNKey,
610
610
  callback?: C,
611
- beginRoot?: N,
611
+ beginRoot?: N | null,
612
612
  iterationType?: IterationType
613
613
  ): N | null;
614
614
 
615
615
  getNode<C extends BTNCallback<N, N>>(
616
616
  identifier: N | null,
617
617
  callback?: C,
618
- beginRoot?: N,
618
+ beginRoot?: N | null,
619
619
  iterationType?: IterationType
620
620
  ): N | null;
621
621
 
622
622
  getNode<C extends BTNCallback<N>>(
623
623
  identifier: ReturnType<C>,
624
624
  callback: C,
625
- beginRoot?: N,
625
+ beginRoot?: N | null,
626
626
  iterationType?: IterationType
627
627
  ): N | null;
628
628
 
@@ -648,28 +648,28 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
648
648
  iterationType = this.iterationType
649
649
  ): N | null {
650
650
  if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
651
- // TODO may support finding node by value equal
651
+
652
652
  return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
653
653
  }
654
654
 
655
655
  get<C extends BTNCallback<N, BTNKey>>(
656
656
  identifier: BTNKey,
657
657
  callback?: C,
658
- beginRoot?: N,
658
+ beginRoot?: N | null,
659
659
  iterationType?: IterationType
660
660
  ): V | undefined;
661
661
 
662
662
  get<C extends BTNCallback<N, N>>(
663
663
  identifier: N | null,
664
664
  callback?: C,
665
- beginRoot?: N,
665
+ beginRoot?: N | null,
666
666
  iterationType?: IterationType
667
667
  ): V | undefined;
668
668
 
669
669
  get<C extends BTNCallback<N>>(
670
670
  identifier: ReturnType<C>,
671
671
  callback: C,
672
- beginRoot?: N,
672
+ beginRoot?: N | null,
673
673
  iterationType?: IterationType
674
674
  ): V | undefined;
675
675
 
@@ -695,8 +695,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
695
695
  iterationType = this.iterationType
696
696
  ): V | undefined {
697
697
  if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
698
- // TODO may support finding node by value equal
699
- return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0].value ?? undefined;
698
+
699
+ return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
700
700
  }
701
701
 
702
702
  /**
@@ -1,3 +1,11 @@
1
+ /**
2
+ * data-structure-typed
3
+ *
4
+ * @author Tyler Zeng
5
+ * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
6
+ * @license MIT License
7
+ */
8
+
1
9
  import {RBTNColor} from '../../types';
2
10
 
3
11
  export class RBTreeNode {
@@ -16,11 +24,18 @@ export class RBTreeNode {
16
24
  }
17
25
  }
18
26
 
19
- export const SN = new RBTreeNode(0);
27
+ export const NIL = new RBTreeNode(0);
20
28
 
29
+ /**
30
+ * 1. Each node is either red or black.
31
+ * 2. The root node is always black.
32
+ * 3. Leaf nodes are typically NIL nodes and are considered black.
33
+ * 4. Red nodes must have black children.
34
+ * 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
35
+ */
21
36
  export class RedBlackTree {
22
37
  constructor() {
23
- this._root = SN;
38
+ this._root = NIL;
24
39
  }
25
40
 
26
41
  protected _root: RBTreeNode;
@@ -38,13 +53,13 @@ export class RedBlackTree {
38
53
  */
39
54
  insert(key: number): void {
40
55
  const node: RBTreeNode = new RBTreeNode(key, RBTNColor.RED);
41
- node.left = SN;
42
- node.right = SN;
56
+ node.left = NIL;
57
+ node.right = NIL;
43
58
 
44
59
  let y: RBTreeNode = null as unknown as RBTreeNode;
45
60
  let x: RBTreeNode = this.root;
46
61
 
47
- while (x !== SN) {
62
+ while (x !== NIL) {
48
63
  y = x;
49
64
  if (node.key < x.key) {
50
65
  x = x.left;
@@ -83,9 +98,9 @@ export class RedBlackTree {
83
98
  */
84
99
  delete(key: number): void {
85
100
  const helper = (node: RBTreeNode): void => {
86
- let z: RBTreeNode = SN;
101
+ let z: RBTreeNode = NIL;
87
102
  let x: RBTreeNode, y: RBTreeNode;
88
- while (node !== SN) {
103
+ while (node !== NIL) {
89
104
  if (node.key === key) {
90
105
  z = node;
91
106
  }
@@ -97,16 +112,16 @@ export class RedBlackTree {
97
112
  }
98
113
  }
99
114
 
100
- if (z === SN) {
115
+ if (z === NIL) {
101
116
  return;
102
117
  }
103
118
 
104
119
  y = z;
105
120
  let yOriginalColor: number = y.color;
106
- if (z.left === SN) {
121
+ if (z.left === NIL) {
107
122
  x = z.right;
108
123
  this._rbTransplant(z, z.right);
109
- } else if (z.right === SN) {
124
+ } else if (z.right === NIL) {
110
125
  x = z.left;
111
126
  this._rbTransplant(z, z.left);
112
127
  } else {
@@ -133,8 +148,8 @@ export class RedBlackTree {
133
148
  helper(this.root);
134
149
  }
135
150
 
136
- isRealNode(node: RBTreeNode): node is RBTreeNode {
137
- return node !== SN && node !== null;
151
+ isRealNode(node: RBTreeNode | null | undefined): node is RBTreeNode {
152
+ return node !== NIL && node !== null;
138
153
  }
139
154
 
140
155
  /**
@@ -170,7 +185,7 @@ export class RedBlackTree {
170
185
  * @returns The leftmost node in the given RBTreeNode.
171
186
  */
172
187
  getLeftMost(node: RBTreeNode = this.root): RBTreeNode {
173
- while (node.left !== null && node.left !== SN) {
188
+ while (node.left !== null && node.left !== NIL) {
174
189
  node = node.left;
175
190
  }
176
191
  return node;
@@ -182,7 +197,7 @@ export class RedBlackTree {
182
197
  * @returns the rightmost node in a red-black tree.
183
198
  */
184
199
  getRightMost(node: RBTreeNode): RBTreeNode {
185
- while (node.right !== null && node.right !== SN) {
200
+ while (node.right !== null && node.right !== NIL) {
186
201
  node = node.right;
187
202
  }
188
203
  return node;
@@ -194,12 +209,12 @@ export class RedBlackTree {
194
209
  * @returns the successor of the given RBTreeNode.
195
210
  */
196
211
  getSuccessor(x: RBTreeNode): RBTreeNode {
197
- if (x.right !== SN) {
212
+ if (x.right !== NIL) {
198
213
  return this.getLeftMost(x.right);
199
214
  }
200
215
 
201
216
  let y: RBTreeNode = x.parent;
202
- while (y !== SN && y !== null && x === y.right) {
217
+ while (y !== NIL && y !== null && x === y.right) {
203
218
  x = y;
204
219
  y = y.parent;
205
220
  }
@@ -213,12 +228,12 @@ export class RedBlackTree {
213
228
  * @returns the predecessor of the given RBTreeNode 'x'.
214
229
  */
215
230
  getPredecessor(x: RBTreeNode): RBTreeNode {
216
- if (x.left !== SN) {
231
+ if (x.left !== NIL) {
217
232
  return this.getRightMost(x.left);
218
233
  }
219
234
 
220
235
  let y: RBTreeNode = x.parent;
221
- while (y !== SN && x === y.left) {
236
+ while (y !== NIL && x === y.left) {
222
237
  x = y;
223
238
  y = y.parent;
224
239
  }
@@ -226,6 +241,65 @@ export class RedBlackTree {
226
241
  return y;
227
242
  }
228
243
 
244
+ print(beginRoot: RBTreeNode = this.root) {
245
+ const display = (root: RBTreeNode | null): void => {
246
+ const [lines, , ,] = _displayAux(root);
247
+ for (const line of lines) {
248
+ console.log(line);
249
+ }
250
+ };
251
+
252
+ const _displayAux = (node: RBTreeNode | null): [string[], number, number, number] => {
253
+ if (node === null) {
254
+ return [[], 0, 0, 0];
255
+ }
256
+
257
+ if (node.right === null && node.left === null) {
258
+ const line = `${node.key}`;
259
+ const width = line.length;
260
+ const height = 1;
261
+ const middle = Math.floor(width / 2);
262
+ return [[line], width, height, middle];
263
+ }
264
+
265
+ if (node.right === null) {
266
+ const [lines, n, p, x] = _displayAux(node.left);
267
+ const s = `${node.key}`;
268
+ const u = s.length;
269
+ const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s;
270
+ const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u);
271
+ const shifted_lines = lines.map(line => line + ' '.repeat(u));
272
+ return [[first_line, second_line, ...shifted_lines], n + u, p + 2, n + Math.floor(u / 2)];
273
+ }
274
+
275
+ if (node.left === null) {
276
+ const [lines, n, p, u] = _displayAux(node.right);
277
+ const s = `${node.key}`;
278
+ const x = s.length;
279
+ const first_line = s + '_'.repeat(x) + ' '.repeat(n - x);
280
+ const second_line = ' '.repeat(u + x) + '\\' + ' '.repeat(n - x - 1);
281
+ const shifted_lines = lines.map(line => ' '.repeat(u) + line);
282
+ return [[first_line, second_line, ...shifted_lines], n + x, p + 2, Math.floor(u / 2)];
283
+ }
284
+
285
+ const [left, n, p, x] = _displayAux(node.left);
286
+ const [right, m, q, y] = _displayAux(node.right);
287
+ const s = `${node.key}`;
288
+ const u = s.length;
289
+ const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s + '_'.repeat(y) + ' '.repeat(m - y);
290
+ const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u + y) + '\\' + ' '.repeat(m - y - 1);
291
+ if (p < q) {
292
+ left.push(...new Array(q - p).fill(' '.repeat(n)));
293
+ } else if (q < p) {
294
+ right.push(...new Array(p - q).fill(' '.repeat(m)));
295
+ }
296
+ const zipped_lines = left.map((a, i) => a + ' '.repeat(u) + right[i]);
297
+ return [[first_line, second_line, ...zipped_lines], n + m + u, Math.max(p, q) + 2, n + Math.floor(u / 2)];
298
+ };
299
+
300
+ display(beginRoot);
301
+ }
302
+
229
303
  /**
230
304
  * The function performs a left rotation on a red-black tree node.
231
305
  * @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
@@ -233,7 +307,7 @@ export class RedBlackTree {
233
307
  protected _leftRotate(x: RBTreeNode): void {
234
308
  const y: RBTreeNode = x.right;
235
309
  x.right = y.left;
236
- if (y.left !== SN) {
310
+ if (y.left !== NIL) {
237
311
  y.left.parent = x;
238
312
  }
239
313
  y.parent = x.parent;
@@ -256,7 +330,7 @@ export class RedBlackTree {
256
330
  protected _rightRotate(x: RBTreeNode): void {
257
331
  const y: RBTreeNode = x.left;
258
332
  x.left = y.right;
259
- if (y.right !== SN) {
333
+ if (y.right !== NIL) {
260
334
  y.right.parent = x;
261
335
  }
262
336
  y.parent = x.parent;
@@ -12,13 +12,13 @@ describe('AVL Tree Test', () => {
12
12
  expect(node6 && tree.getHeight(node6)).toBe(3);
13
13
  expect(node6 && tree.getDepth(node6)).toBe(1);
14
14
 
15
- const getNodeById = tree.get(10);
16
- expect(getNodeById?.key).toBe(10);
15
+ const getValueById = tree.get(10);
16
+ expect(getValueById).toBe(10);
17
17
 
18
18
  const getMinNodeByRoot = tree.getLeftMost();
19
19
  expect(getMinNodeByRoot?.key).toBe(1);
20
20
 
21
- const node15 = tree.get(15);
21
+ const node15 = tree.getNode(15);
22
22
  const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
23
23
  expect(getMinNodeBySpecificNode?.key).toBe(12);
24
24
 
@@ -20,16 +20,16 @@ describe('Individual package BST operations test', () => {
20
20
  expect(node6 && bst.getHeight(6)).toBe(2);
21
21
  expect(node6 && bst.getDepth(6)).toBe(3);
22
22
 
23
- const nodeId10 = bst.get(10);
23
+ const nodeId10 = bst.getNode(10);
24
24
  expect(nodeId10?.key).toBe(10);
25
25
 
26
- const nodeVal9 = bst.get(9, node => node.value);
26
+ const nodeVal9 = bst.getNode(9, node => node.value);
27
27
  expect(nodeVal9?.key).toBe(9);
28
28
 
29
29
  const leftMost = bst.getLeftMost();
30
30
  expect(leftMost?.key).toBe(1);
31
31
 
32
- const node15 = bst.get(15);
32
+ const node15 = bst.getNode(15);
33
33
  const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
34
34
  expect(minNodeBySpecificNode?.key).toBe(12);
35
35
 
@@ -43,7 +43,7 @@ describe('Individual package BST operations test', () => {
43
43
 
44
44
  expect(node15).toBeInstanceOf(BSTNode);
45
45
 
46
- const node11 = bst.get(11);
46
+ const node11 = bst.getNode(11);
47
47
  expect(node11).toBeInstanceOf(BSTNode);
48
48
 
49
49
  const dfsInorderNodes = bst.dfs(node => node, 'in');
@@ -216,7 +216,7 @@ describe('Individual package BST operations test', () => {
216
216
 
217
217
  expect(objBST.has(6)).toBe(true);
218
218
 
219
- const node6 = objBST.get(6);
219
+ const node6 = objBST.getNode(6);
220
220
  expect(node6 && objBST.getHeight(node6)).toBe(2);
221
221
  expect(node6 && objBST.getDepth(node6)).toBe(3);
222
222
 
@@ -229,7 +229,7 @@ describe('Individual package BST operations test', () => {
229
229
  const leftMost = objBST.getLeftMost();
230
230
  expect(leftMost?.key).toBe(1);
231
231
 
232
- const node15 = objBST.get(15);
232
+ const node15 = objBST.getNode(15);
233
233
  expect(node15?.value).toEqual({key: 15, keyA: 15});
234
234
  const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
235
235
  expect(minNodeBySpecificNode?.key).toBe(12);
@@ -244,7 +244,7 @@ describe('Individual package BST operations test', () => {
244
244
 
245
245
  expect(node15).toBeInstanceOf(BSTNode);
246
246
 
247
- const node11 = objBST.get(11);
247
+ const node11 = objBST.getNode(11);
248
248
  expect(node11).toBeInstanceOf(BSTNode);
249
249
 
250
250
  const dfsInorderNodes = objBST.dfs(node => node, 'in');
@@ -1,5 +1,8 @@
1
- import {RBTreeNode, RedBlackTree, SN} from '../../../../src';
1
+ import {RBTNColor, RBTreeNode, RedBlackTree, NIL} from '../../../../src';
2
2
  import {getRandomInt} from '../../../utils';
3
+ import {isDebugTest} from '../../../config';
4
+
5
+ const isDebug = isDebugTest;
3
6
 
4
7
  describe('RedBlackTree', () => {
5
8
  let tree: RedBlackTree;
@@ -63,7 +66,7 @@ describe('RedBlackTree', () => {
63
66
 
64
67
  test('should handle an empty tree', () => {
65
68
  const minNode = tree.getLeftMost(tree.root);
66
- expect(minNode).toBe(SN);
69
+ expect(minNode).toBe(NIL);
67
70
  });
68
71
  });
69
72
 
@@ -81,7 +84,7 @@ describe('RedBlackTree', () => {
81
84
 
82
85
  test('should handle an empty tree', () => {
83
86
  const maxNode = tree.getRightMost(tree.root);
84
- expect(maxNode).toBe(SN);
87
+ expect(maxNode).toBe(NIL);
85
88
  });
86
89
  });
87
90
 
@@ -105,7 +108,7 @@ describe('RedBlackTree', () => {
105
108
 
106
109
  const node = tree.getNode(10);
107
110
  const successorNode = tree.getSuccessor(node);
108
- // TODO not sure if it should be null or SN
111
+ // TODO not sure if it should be null or NIL
109
112
  expect(successorNode).toBe(null);
110
113
  });
111
114
  });
@@ -130,7 +133,7 @@ describe('RedBlackTree', () => {
130
133
 
131
134
  const node = tree.getNode(20);
132
135
  const predecessorNode = tree.getPredecessor(node);
133
- // TODO not sure if it should be SN or something else.
136
+ // TODO not sure if it should be NIL or something else.
134
137
  expect(predecessorNode).toBe(tree.getNode(10));
135
138
  });
136
139
  });
@@ -198,14 +201,146 @@ describe('RedBlackTree', () => {
198
201
  expect(node.right.key).toBe(25);
199
202
  });
200
203
 
201
- it('should fix the tree after deletion', () => {
204
+ it('should all node attributes fully conform to the red-black tree standards.', () => {
202
205
  tree.insert(10);
203
206
  tree.insert(20);
204
207
  tree.insert(5);
205
208
  tree.insert(15);
206
- tree.delete(15);
207
- // Verify that the tree is still valid
208
- // You can add assertions to check the Red-Black Tree properties
209
+ tree.insert(21);
210
+ tree.insert(6);
211
+ tree.insert(2);
212
+
213
+ let node10F = tree.getNode(10);
214
+ let node20F = tree.getNode(20);
215
+ let node5F = tree.getNode(5);
216
+ let node15F = tree.getNode(15);
217
+ let node21F = tree.getNode(21);
218
+ let node6F = tree.getNode(6);
219
+ let node2F = tree.getNode(2);
220
+ expect(node10F.key).toBe(10);
221
+ expect(node10F.color).toBe(RBTNColor.BLACK);
222
+ expect(node10F.left).toBe(node5F);
223
+ expect(node10F.right).toBe(node20F);
224
+ expect(node10F.parent).toBe(null);
225
+ expect(node20F.key).toBe(20);
226
+ expect(node20F.color).toBe(RBTNColor.BLACK);
227
+ expect(node20F.left).toBe(node15F);
228
+ expect(node20F.right).toBe(node21F);
229
+ expect(node20F.parent).toBe(node10F);
230
+ expect(node5F.key).toBe(5);
231
+ expect(node5F.color).toBe(RBTNColor.BLACK);
232
+ expect(node5F.left).toBe(node2F);
233
+ expect(node5F.right).toBe(node6F);
234
+ expect(node5F.parent).toBe(node10F);
235
+ expect(node15F.key).toBe(15);
236
+ expect(node15F.color).toBe(RBTNColor.RED);
237
+ expect(node15F.left).toBe(NIL);
238
+ expect(node15F.right).toBe(NIL);
239
+ expect(node15F.parent).toBe(node20F);
240
+ expect(node21F.key).toBe(21);
241
+ expect(node21F.color).toBe(RBTNColor.RED);
242
+ expect(node21F.left).toBe(NIL);
243
+ expect(node21F.right).toBe(NIL);
244
+ expect(node21F.parent).toBe(node20F);
245
+ expect(node6F.key).toBe(6);
246
+ expect(node6F.color).toBe(RBTNColor.RED);
247
+ expect(node6F.left).toBe(NIL);
248
+ expect(node6F.right).toBe(NIL);
249
+ expect(node6F.parent).toBe(node5F);
250
+ expect(node2F.key).toBe(2);
251
+ expect(node2F.color).toBe(RBTNColor.RED);
252
+ expect(node2F.left).toBe(NIL);
253
+ expect(node2F.right).toBe(NIL);
254
+ expect(node2F.parent).toBe(node5F);
255
+ expect(node15F.key).toBe(15);
256
+ expect(node15F.color).toBe(RBTNColor.RED);
257
+ expect(node15F.left).toBe(NIL);
258
+ expect(node15F.right).toBe(NIL);
259
+ expect(node15F.parent).toBe(node20F);
260
+ tree.delete(5);
261
+ node10F = tree.getNode(10);
262
+ node20F = tree.getNode(20);
263
+ node5F = tree.getNode(5);
264
+ node15F = tree.getNode(15);
265
+ node21F = tree.getNode(21);
266
+ node6F = tree.getNode(6);
267
+ node2F = tree.getNode(2);
268
+ expect(node10F.key).toBe(10);
269
+ expect(node10F.color).toBe(RBTNColor.BLACK);
270
+ expect(node10F.left).toBe(node6F);
271
+ expect(node10F.right).toBe(node20F);
272
+ expect(node10F.parent).toBe(null);
273
+ expect(node20F.key).toBe(20);
274
+ expect(node20F.color).toBe(RBTNColor.BLACK);
275
+ expect(node20F.left).toBe(node15F);
276
+ expect(node20F.right).toBe(node21F);
277
+ expect(node20F.parent).toBe(node10F);
278
+ expect(node5F).toBe(null);
279
+ expect(node15F.key).toBe(15);
280
+ expect(node15F.color).toBe(RBTNColor.RED);
281
+ expect(node15F.left).toBe(NIL);
282
+ expect(node15F.right).toBe(NIL);
283
+ expect(node15F.parent).toBe(node20F);
284
+ expect(node21F.key).toBe(21);
285
+ expect(node21F.color).toBe(RBTNColor.RED);
286
+ expect(node21F.left).toBe(NIL);
287
+ expect(node21F.right).toBe(NIL);
288
+ expect(node21F.parent).toBe(node20F);
289
+ expect(node6F.key).toBe(6);
290
+ expect(node6F.color).toBe(RBTNColor.BLACK);
291
+ expect(node6F.left).toBe(node2F);
292
+ expect(node6F.right).toBe(NIL);
293
+ expect(node6F.parent).toBe(node10F);
294
+ expect(node2F.key).toBe(2);
295
+ expect(node2F.color).toBe(RBTNColor.RED);
296
+ expect(node2F.left).toBe(NIL);
297
+ expect(node2F.right).toBe(NIL);
298
+ expect(node2F.parent).toBe(node6F);
299
+ expect(node15F.key).toBe(15);
300
+ expect(node15F.color).toBe(RBTNColor.RED);
301
+ expect(node15F.left).toBe(NIL);
302
+ expect(node15F.right).toBe(NIL);
303
+ expect(node15F.parent).toBe(node20F);
304
+ tree.delete(20);
305
+ node10F = tree.getNode(10);
306
+ node20F = tree.getNode(20);
307
+ node5F = tree.getNode(5);
308
+ node15F = tree.getNode(15);
309
+ node21F = tree.getNode(21);
310
+ node6F = tree.getNode(6);
311
+ node2F = tree.getNode(2);
312
+ expect(node10F.key).toBe(10);
313
+ expect(node10F.color).toBe(RBTNColor.BLACK);
314
+ expect(node10F.left).toBe(node6F);
315
+ expect(node10F.right).toBe(node21F);
316
+ expect(node10F.parent).toBe(null);
317
+ expect(node20F).toBe(null);
318
+ expect(node5F).toBe(null);
319
+ expect(node15F.key).toBe(15);
320
+ expect(node15F.color).toBe(RBTNColor.RED);
321
+ expect(node15F.left).toBe(NIL);
322
+ expect(node15F.right).toBe(NIL);
323
+ expect(node15F.parent).toBe(node21F);
324
+ expect(node21F.key).toBe(21);
325
+ expect(node21F.color).toBe(RBTNColor.BLACK);
326
+ expect(node21F.left).toBe(node15F);
327
+ expect(node21F.right).toBe(NIL);
328
+ expect(node21F.parent).toBe(node10F);
329
+ expect(node6F.key).toBe(6);
330
+ expect(node6F.color).toBe(RBTNColor.BLACK);
331
+ expect(node6F.left).toBe(node2F);
332
+ expect(node6F.right).toBe(NIL);
333
+ expect(node6F.parent).toBe(node10F);
334
+ expect(node2F.key).toBe(2);
335
+ expect(node2F.color).toBe(RBTNColor.RED);
336
+ expect(node2F.left).toBe(NIL);
337
+ expect(node2F.right).toBe(NIL);
338
+ expect(node2F.parent).toBe(node6F);
339
+ expect(node15F.key).toBe(15);
340
+ expect(node15F.color).toBe(RBTNColor.RED);
341
+ expect(node15F.left).toBe(NIL);
342
+ expect(node15F.right).toBe(NIL);
343
+ expect(node15F.parent).toBe(node21F);
209
344
  });
210
345
 
211
346
  it('should fix the tree after insertion', () => {
@@ -214,8 +349,8 @@ describe('RedBlackTree', () => {
214
349
  tree.insert(5);
215
350
  tree.insert(15);
216
351
  const node15F = tree.getNode(15);
217
- expect(node15F.left).toBe(SN);
218
- expect(node15F.right).toBe(SN);
352
+ expect(node15F.left).toBe(NIL);
353
+ expect(node15F.right).toBe(NIL);
219
354
  expect(node15F.parent).toBe(tree.getNode(5));
220
355
 
221
356
  tree.insert(25);
@@ -230,8 +365,8 @@ describe('RedBlackTree', () => {
230
365
  tree.insert(155);
231
366
  tree.insert(225);
232
367
  const node225F = tree.getNode(225);
233
- expect(node225F.left).toBe(SN);
234
- expect(node225F.right).toBe(SN);
368
+ expect(node225F.left).toBe(NIL);
369
+ expect(node225F.right).toBe(NIL);
235
370
  expect(node225F.parent.key).toBe(155);
236
371
  tree.insert(7);
237
372
 
@@ -257,16 +392,38 @@ describe('RedBlackTree', () => {
257
392
  const node50 = tree.getNode(50);
258
393
  expect(node50.key).toBe(50);
259
394
  expect(node50.left.key).toBe(33);
260
- expect(node50.right).toBe(SN);
395
+ expect(node50.right).toBe(NIL);
261
396
  const node15Fo = tree.getNode(15);
262
397
 
263
398
  expect(node15Fo.key).toBe(15);
264
- expect(node15Fo.left).toBe(SN);
399
+ expect(node15Fo.left).toBe(NIL);
265
400
  const node225S = tree.getNode(225);
266
- expect(node225S.left).toBe(SN);
267
- expect(node225S.right).toBe(SN);
401
+ expect(node225S.left).toBe(NIL);
402
+ expect(node225S.right).toBe(NIL);
268
403
  expect(node225S.parent.key).toBe(155);
269
404
  expect(tree.getNode(0)).toBe(null);
405
+ tree.insert(1);
406
+ tree.insert(2);
407
+ tree.insert(3);
408
+ tree.insert(4);
409
+ tree.insert(5);
410
+ tree.insert(6);
411
+ tree.insert(7);
412
+ tree.insert(8);
413
+ tree.insert(9);
414
+ tree.insert(10);
415
+ tree.insert(11);
416
+ tree.insert(12);
417
+ tree.insert(13);
418
+ tree.insert(14);
419
+ tree.insert(15);
420
+ tree.insert(16);
421
+ tree.insert(17);
422
+ tree.insert(18);
423
+ tree.insert(19);
424
+ tree.insert(110);
425
+
426
+ isDebug && tree.print();
270
427
  });
271
428
 
272
429
  it('should fix the tree after insertion and deletion', () => {