data-structure-typed 1.42.3 → 1.42.5

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 (74) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +17 -17
  3. package/benchmark/report.html +12 -12
  4. package/benchmark/report.json +106 -106
  5. package/dist/cjs/src/data-structures/binary-tree/avl-tree.d.ts +2 -2
  6. package/dist/cjs/src/data-structures/binary-tree/avl-tree.js +5 -3
  7. package/dist/cjs/src/data-structures/binary-tree/avl-tree.js.map +1 -1
  8. package/dist/cjs/src/data-structures/binary-tree/binary-tree.d.ts +56 -52
  9. package/dist/cjs/src/data-structures/binary-tree/binary-tree.js +115 -53
  10. package/dist/cjs/src/data-structures/binary-tree/binary-tree.js.map +1 -1
  11. package/dist/cjs/src/data-structures/binary-tree/bst.d.ts +42 -15
  12. package/dist/cjs/src/data-structures/binary-tree/bst.js +77 -21
  13. package/dist/cjs/src/data-structures/binary-tree/bst.js.map +1 -1
  14. package/dist/cjs/src/data-structures/binary-tree/index.d.ts +1 -1
  15. package/dist/cjs/src/data-structures/binary-tree/index.js +1 -1
  16. package/dist/cjs/src/data-structures/binary-tree/rb-tree.d.ts +28 -51
  17. package/dist/cjs/src/data-structures/binary-tree/rb-tree.js +148 -180
  18. package/dist/cjs/src/data-structures/binary-tree/rb-tree.js.map +1 -1
  19. package/dist/cjs/src/data-structures/binary-tree/{tree-multiset.d.ts → tree-multimap.d.ts} +20 -20
  20. package/dist/cjs/src/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +35 -32
  21. package/dist/cjs/src/data-structures/binary-tree/tree-multimap.js.map +1 -0
  22. package/dist/cjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  23. package/dist/cjs/src/types/data-structures/binary-tree/index.d.ts +1 -1
  24. package/dist/cjs/src/types/data-structures/binary-tree/index.js +1 -1
  25. package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.d.ts +4 -0
  26. package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.js +0 -5
  27. package/dist/cjs/src/types/data-structures/binary-tree/rb-tree.js.map +1 -1
  28. package/dist/cjs/src/types/data-structures/binary-tree/tree-multimap.d.ts +4 -0
  29. package/dist/cjs/src/types/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +1 -1
  30. package/dist/cjs/src/types/data-structures/binary-tree/tree-multimap.js.map +1 -0
  31. package/dist/mjs/src/data-structures/binary-tree/avl-tree.d.ts +2 -2
  32. package/dist/mjs/src/data-structures/binary-tree/avl-tree.js +5 -3
  33. package/dist/mjs/src/data-structures/binary-tree/binary-tree.d.ts +56 -52
  34. package/dist/mjs/src/data-structures/binary-tree/binary-tree.js +115 -53
  35. package/dist/mjs/src/data-structures/binary-tree/bst.d.ts +42 -15
  36. package/dist/mjs/src/data-structures/binary-tree/bst.js +79 -21
  37. package/dist/mjs/src/data-structures/binary-tree/index.d.ts +1 -1
  38. package/dist/mjs/src/data-structures/binary-tree/index.js +1 -1
  39. package/dist/mjs/src/data-structures/binary-tree/rb-tree.d.ts +28 -51
  40. package/dist/mjs/src/data-structures/binary-tree/rb-tree.js +148 -184
  41. package/dist/mjs/src/data-structures/binary-tree/{tree-multiset.d.ts → tree-multimap.d.ts} +20 -20
  42. package/dist/mjs/src/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +33 -31
  43. package/dist/mjs/src/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  44. package/dist/mjs/src/types/data-structures/binary-tree/index.d.ts +1 -1
  45. package/dist/mjs/src/types/data-structures/binary-tree/index.js +1 -1
  46. package/dist/mjs/src/types/data-structures/binary-tree/rb-tree.d.ts +4 -0
  47. package/dist/mjs/src/types/data-structures/binary-tree/rb-tree.js +0 -5
  48. package/dist/mjs/src/types/data-structures/binary-tree/tree-multimap.d.ts +4 -0
  49. package/dist/umd/data-structure-typed.min.js +1 -1
  50. package/dist/umd/data-structure-typed.min.js.map +1 -1
  51. package/package.json +5 -3
  52. package/src/data-structures/binary-tree/avl-tree.ts +5 -4
  53. package/src/data-structures/binary-tree/binary-tree.ts +201 -131
  54. package/src/data-structures/binary-tree/bst.ts +100 -34
  55. package/src/data-structures/binary-tree/index.ts +1 -1
  56. package/src/data-structures/binary-tree/rb-tree.ts +227 -236
  57. package/src/data-structures/binary-tree/{tree-multiset.ts → tree-multimap.ts} +38 -37
  58. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  59. package/src/types/data-structures/binary-tree/index.ts +1 -1
  60. package/src/types/data-structures/binary-tree/rb-tree.ts +5 -5
  61. package/src/types/data-structures/binary-tree/tree-multimap.ts +6 -0
  62. package/test/performance/data-structures/binary-tree/rb-tree.test.ts +2 -2
  63. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +20 -1
  64. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +12 -31
  65. package/test/unit/data-structures/binary-tree/bst.test.ts +3 -3
  66. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +205 -159
  67. package/test/unit/data-structures/binary-tree/{tree-multiset.test.ts → tree-multimap.test.ts} +182 -182
  68. package/dist/cjs/src/data-structures/binary-tree/tree-multiset.js.map +0 -1
  69. package/dist/cjs/src/types/data-structures/binary-tree/tree-multiset.d.ts +0 -4
  70. package/dist/cjs/src/types/data-structures/binary-tree/tree-multiset.js.map +0 -1
  71. package/dist/mjs/src/types/data-structures/binary-tree/tree-multiset.d.ts +0 -4
  72. package/src/types/data-structures/binary-tree/tree-multiset.ts +0 -6
  73. /package/dist/mjs/src/types/data-structures/binary-tree/{tree-multiset.js → tree-multimap.js} +0 -0
  74. /package/test/performance/data-structures/binary-tree/{tree-multiset.test.ts → tree-multimap.test.ts} +0 -0
@@ -5,16 +5,13 @@
5
5
  * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
- import { RBTNColor } from '../../types';
9
- export declare class RBTreeNode {
10
- key: number;
11
- parent: RBTreeNode;
12
- left: RBTreeNode;
13
- right: RBTreeNode;
14
- color: number;
15
- constructor(key: number, color?: RBTNColor);
8
+ import { BinaryTreeDeletedResult, BTNCallback, BTNKey, IterationType, RBTNColor, RBTreeNodeNested, RBTreeOptions } from '../../types';
9
+ import { BST, BSTNode } from "./bst";
10
+ import { IBinaryTree } from "../../interfaces";
11
+ export declare class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V>> extends BSTNode<V, N> {
12
+ color: RBTNColor;
13
+ constructor(key: BTNKey, value?: V, color?: RBTNColor);
16
14
  }
17
- export declare const NIL: RBTreeNode;
18
15
  /**
19
16
  * 1. Each node is either red or black.
20
17
  * 2. The root node is always black.
@@ -22,95 +19,75 @@ export declare const NIL: RBTreeNode;
22
19
  * 4. Red nodes must have black children.
23
20
  * 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
24
21
  */
25
- export declare class RedBlackTree {
26
- constructor();
27
- protected _root: RBTreeNode;
28
- get root(): RBTreeNode;
22
+ export declare class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNested<V>>> extends BST<V, N> implements IBinaryTree<V, N> {
23
+ constructor(options?: RBTreeOptions);
24
+ protected _root: N;
25
+ get root(): N;
29
26
  protected _size: number;
30
27
  get size(): number;
31
- /**
32
- * The `insert` function inserts a new node with a given key into a red-black tree and fixes any
33
- * violations of the red-black tree properties.
34
- * @param {number} key - The key parameter is a number that represents the value to be inserted into
35
- * the RBTree.
36
- * @returns The function does not explicitly return anything.
37
- */
38
- add(key: number): void;
39
- /**
40
- * The `delete` function in TypeScript is used to remove a node with a specific key from a red-black
41
- * tree.
42
- * @param {number} key - The `node` parameter is of type `RBTreeNode` and represents the current
43
- * node being processed in the delete operation.
44
- * @returns The `delete` function does not return anything. It has a return type of `void`.
45
- */
46
- delete(key: number): void;
47
- isRealNode(node: RBTreeNode | null | undefined): node is RBTreeNode;
48
- /**
49
- * The function `getNode` is a recursive depth-first search algorithm that searches for a node with a
50
- * given key in a red-black tree.
51
- * @param {number} key - The key parameter is a number that represents the value we are searching for
52
- * in the RBTree.
53
- * @param beginRoot - The `beginRoot` parameter is an optional parameter that represents the starting
54
- * point for the search in the binary search tree. If no value is provided for `beginRoot`, it
55
- * defaults to the root of the binary search tree (`this.root`).
56
- * @returns a RBTreeNode.
57
- */
58
- getNode(key: number, beginRoot?: RBTreeNode): RBTreeNode;
28
+ NIL: N;
29
+ add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | undefined;
30
+ createNode(key: BTNKey, value?: V, color?: RBTNColor): N;
31
+ delete<C extends BTNCallback<N>>(identifier: ReturnType<C> | null | undefined, callback?: C): BinaryTreeDeletedResult<N>[];
32
+ isNode(node: N | undefined): node is N;
33
+ getNode<C extends BTNCallback<N, BTNKey>>(identifier: BTNKey, callback?: C, beginRoot?: N | undefined, iterationType?: IterationType): N | undefined;
34
+ getNode<C extends BTNCallback<N, N>>(identifier: N | undefined, callback?: C, beginRoot?: N | undefined, iterationType?: IterationType): N | undefined;
35
+ getNode<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C, beginRoot?: N | undefined, iterationType?: IterationType): N | undefined;
59
36
  /**
60
37
  * The function returns the leftmost node in a red-black tree.
61
38
  * @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode, which represents a node in
62
39
  * a Red-Black Tree.
63
40
  * @returns The leftmost node in the given RBTreeNode.
64
41
  */
65
- getLeftMost(node?: RBTreeNode): RBTreeNode;
42
+ getLeftMost(node?: N): N;
66
43
  /**
67
44
  * The function returns the rightmost node in a red-black tree.
68
45
  * @param {RBTreeNode} node - The parameter "node" is of type RBTreeNode.
69
46
  * @returns the rightmost node in a red-black tree.
70
47
  */
71
- getRightMost(node: RBTreeNode): RBTreeNode;
48
+ getRightMost(node: N): N;
72
49
  /**
73
50
  * The function returns the successor of a given node in a red-black tree.
74
51
  * @param {RBTreeNode} x - RBTreeNode - The node for which we want to find the successor.
75
52
  * @returns the successor of the given RBTreeNode.
76
53
  */
77
- getSuccessor(x: RBTreeNode): RBTreeNode;
54
+ getSuccessor(x: N): N | undefined;
78
55
  /**
79
56
  * The function returns the predecessor of a given node in a red-black tree.
80
57
  * @param {RBTreeNode} x - The parameter `x` is of type `RBTreeNode`, which represents a node in a
81
58
  * Red-Black Tree.
82
59
  * @returns the predecessor of the given RBTreeNode 'x'.
83
60
  */
84
- getPredecessor(x: RBTreeNode): RBTreeNode;
61
+ getPredecessor(x: N): N;
85
62
  clear(): void;
86
- print(beginRoot?: RBTreeNode): void;
63
+ protected _setRoot(v: N): void;
87
64
  /**
88
65
  * The function performs a left rotation on a red-black tree node.
89
66
  * @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
90
67
  */
91
- protected _leftRotate(x: RBTreeNode): void;
68
+ protected _leftRotate(x: N): void;
92
69
  /**
93
70
  * The function performs a right rotation on a red-black tree node.
94
71
  * @param {RBTreeNode} x - x is a RBTreeNode, which represents the node that needs to be right
95
72
  * rotated.
96
73
  */
97
- protected _rightRotate(x: RBTreeNode): void;
74
+ protected _rightRotate(x: N): void;
98
75
  /**
99
76
  * The _fixDelete function is used to rebalance the Red-Black Tree after a node deletion.
100
77
  * @param {RBTreeNode} x - The parameter `x` is of type `RBTreeNode`, which represents a node in a
101
78
  * red-black tree.
102
79
  */
103
- protected _fixDelete(x: RBTreeNode): void;
80
+ protected _fixDelete(x: N): void;
104
81
  /**
105
82
  * The function `_rbTransplant` replaces one node in a red-black tree with another node.
106
83
  * @param {RBTreeNode} u - The parameter "u" represents a RBTreeNode object.
107
84
  * @param {RBTreeNode} v - The parameter "v" is a RBTreeNode object.
108
85
  */
109
- protected _rbTransplant(u: RBTreeNode, v: RBTreeNode): void;
86
+ protected _rbTransplant(u: N, v: N): void;
110
87
  /**
111
88
  * The `_fixInsert` function is used to fix the red-black tree after an insertion operation.
112
89
  * @param {RBTreeNode} k - The parameter `k` is a RBTreeNode object, which represents a node in a
113
90
  * red-black tree.
114
91
  */
115
- protected _fixInsert(k: RBTreeNode): void;
92
+ protected _fixInsert(k: N): void;
116
93
  }
@@ -7,20 +7,17 @@
7
7
  * @license MIT License
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.RedBlackTree = exports.NIL = exports.RBTreeNode = void 0;
10
+ exports.RedBlackTree = exports.RBTreeNode = void 0;
11
11
  const types_1 = require("../../types");
12
- class RBTreeNode {
13
- constructor(key, color = types_1.RBTNColor.BLACK) {
14
- this.color = types_1.RBTNColor.BLACK;
15
- this.key = key;
12
+ const bst_1 = require("./bst");
13
+ const binary_tree_1 = require("./binary-tree");
14
+ class RBTreeNode extends bst_1.BSTNode {
15
+ constructor(key, value, color = types_1.RBTNColor.BLACK) {
16
+ super(key, value);
16
17
  this.color = color;
17
- this.parent = null;
18
- this.left = null;
19
- this.right = null;
20
18
  }
21
19
  }
22
20
  exports.RBTreeNode = RBTreeNode;
23
- exports.NIL = new RBTreeNode(0);
24
21
  /**
25
22
  * 1. Each node is either red or black.
26
23
  * 2. The root node is always black.
@@ -28,10 +25,12 @@ exports.NIL = new RBTreeNode(0);
28
25
  * 4. Red nodes must have black children.
29
26
  * 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
30
27
  */
31
- class RedBlackTree {
32
- constructor() {
28
+ class RedBlackTree extends bst_1.BST {
29
+ constructor(options) {
30
+ super(options);
33
31
  this._size = 0;
34
- this._root = exports.NIL;
32
+ this.NIL = new RBTreeNode(NaN);
33
+ this._root = this.NIL;
35
34
  }
36
35
  get root() {
37
36
  return this._root;
@@ -39,31 +38,39 @@ class RedBlackTree {
39
38
  get size() {
40
39
  return this._size;
41
40
  }
42
- /**
43
- * The `insert` function inserts a new node with a given key into a red-black tree and fixes any
44
- * violations of the red-black tree properties.
45
- * @param {number} key - The key parameter is a number that represents the value to be inserted into
46
- * the RBTree.
47
- * @returns The function does not explicitly return anything.
48
- */
49
- add(key) {
50
- const node = new RBTreeNode(key, types_1.RBTNColor.RED);
51
- node.left = exports.NIL;
52
- node.right = exports.NIL;
53
- let y = null;
41
+ add(keyOrNode, value) {
42
+ let node;
43
+ if (typeof keyOrNode === 'number') {
44
+ node = this.createNode(keyOrNode, value, types_1.RBTNColor.RED);
45
+ }
46
+ else if (keyOrNode instanceof RBTreeNode) {
47
+ node = keyOrNode;
48
+ }
49
+ else if (keyOrNode === null) {
50
+ return;
51
+ }
52
+ else if (keyOrNode === undefined) {
53
+ return;
54
+ }
55
+ else {
56
+ return;
57
+ }
58
+ node.left = this.NIL;
59
+ node.right = this.NIL;
60
+ let y = undefined;
54
61
  let x = this.root;
55
- while (x !== exports.NIL) {
62
+ while (x !== this.NIL) {
56
63
  y = x;
57
- if (node.key < x.key) {
64
+ if (x && node.key < x.key) {
58
65
  x = x.left;
59
66
  }
60
67
  else {
61
- x = x.right;
68
+ x = x === null || x === void 0 ? void 0 : x.right;
62
69
  }
63
70
  }
64
71
  node.parent = y;
65
- if (y === null) {
66
- this._root = node;
72
+ if (y === undefined) {
73
+ this._setRoot(node);
67
74
  }
68
75
  else if (node.key < y.key) {
69
76
  y.left = node;
@@ -71,51 +78,50 @@ class RedBlackTree {
71
78
  else {
72
79
  y.right = node;
73
80
  }
74
- if (node.parent === null) {
81
+ if (node.parent === undefined) {
75
82
  node.color = types_1.RBTNColor.BLACK;
76
83
  this._size++;
77
84
  return;
78
85
  }
79
- if (node.parent.parent === null) {
86
+ if (node.parent.parent === undefined) {
80
87
  this._size++;
81
88
  return;
82
89
  }
83
90
  this._fixInsert(node);
84
91
  this._size++;
85
92
  }
86
- /**
87
- * The `delete` function in TypeScript is used to remove a node with a specific key from a red-black
88
- * tree.
89
- * @param {number} key - The `node` parameter is of type `RBTreeNode` and represents the current
90
- * node being processed in the delete operation.
91
- * @returns The `delete` function does not return anything. It has a return type of `void`.
92
- */
93
- delete(key) {
93
+ createNode(key, value, color = types_1.RBTNColor.BLACK) {
94
+ return new RBTreeNode(key, value, color);
95
+ }
96
+ delete(identifier, callback = this.defaultOneParamCallback) {
97
+ const ans = [];
98
+ if (identifier === null)
99
+ return ans;
94
100
  const helper = (node) => {
95
- let z = exports.NIL;
101
+ let z = this.NIL;
96
102
  let x, y;
97
- while (node !== exports.NIL) {
98
- if (node.key === key) {
103
+ while (node !== this.NIL) {
104
+ if (node && callback(node) === identifier) {
99
105
  z = node;
100
106
  }
101
- if (node.key <= key) {
107
+ if (node && identifier && callback(node) <= identifier) {
102
108
  node = node.right;
103
109
  }
104
110
  else {
105
- node = node.left;
111
+ node = node === null || node === void 0 ? void 0 : node.left;
106
112
  }
107
113
  }
108
- if (z === exports.NIL) {
114
+ if (z === this.NIL) {
109
115
  this._size--;
110
116
  return;
111
117
  }
112
118
  y = z;
113
119
  let yOriginalColor = y.color;
114
- if (z.left === exports.NIL) {
120
+ if (z.left === this.NIL) {
115
121
  x = z.right;
116
122
  this._rbTransplant(z, z.right);
117
123
  }
118
- else if (z.right === exports.NIL) {
124
+ else if (z.right === this.NIL) {
119
125
  x = z.left;
120
126
  this._rbTransplant(z, z.left);
121
127
  }
@@ -142,35 +148,32 @@ class RedBlackTree {
142
148
  this._size--;
143
149
  };
144
150
  helper(this.root);
151
+ // TODO
152
+ return ans;
145
153
  }
146
- isRealNode(node) {
147
- return node !== exports.NIL && node !== null;
154
+ isNode(node) {
155
+ return node !== this.NIL && node !== undefined;
148
156
  }
149
157
  /**
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
+ * The function `get` returns the first node in a binary tree that matches the given property or key.
159
+ * @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
160
+ * the node that you want to find in the binary tree. It can be either a `BTNKey` or `N`
161
+ * type.
162
+ * @param callback - The `callback` parameter is a function that is used to determine whether a node
163
+ * matches the desired criteria. It takes a node as input and returns a boolean value indicating
164
+ * whether the node matches the criteria or not. The default callback function
165
+ * (`this.defaultOneParamCallback`) is used if no callback function is
166
+ * @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
167
+ * the root node from which the search should begin.
168
+ * @param iterationType - The `iterationType` parameter specifies the type of iteration to be
169
+ * performed when searching for a node in the binary tree. It can have one of the following values:
170
+ * @returns either the found node (of type N) or null if no node is found.
158
171
  */
159
- getNode(key, beginRoot = this.root) {
160
- const dfs = (node) => {
161
- if (this.isRealNode(node)) {
162
- if (key === node.key) {
163
- return node;
164
- }
165
- if (key < node.key)
166
- return dfs(node.left);
167
- return dfs(node.right);
168
- }
169
- else {
170
- return null;
171
- }
172
- };
173
- return dfs(beginRoot);
172
+ getNode(identifier, callback = this.defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
173
+ var _a;
174
+ if (identifier instanceof binary_tree_1.BinaryTreeNode)
175
+ callback = (node => node);
176
+ return (_a = this.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : undefined;
174
177
  }
175
178
  /**
176
179
  * The function returns the leftmost node in a red-black tree.
@@ -179,7 +182,7 @@ class RedBlackTree {
179
182
  * @returns The leftmost node in the given RBTreeNode.
180
183
  */
181
184
  getLeftMost(node = this.root) {
182
- while (node.left !== null && node.left !== exports.NIL) {
185
+ while (node.left !== undefined && node.left !== this.NIL) {
183
186
  node = node.left;
184
187
  }
185
188
  return node;
@@ -190,7 +193,7 @@ class RedBlackTree {
190
193
  * @returns the rightmost node in a red-black tree.
191
194
  */
192
195
  getRightMost(node) {
193
- while (node.right !== null && node.right !== exports.NIL) {
196
+ while (node.right !== undefined && node.right !== this.NIL) {
194
197
  node = node.right;
195
198
  }
196
199
  return node;
@@ -201,11 +204,11 @@ class RedBlackTree {
201
204
  * @returns the successor of the given RBTreeNode.
202
205
  */
203
206
  getSuccessor(x) {
204
- if (x.right !== exports.NIL) {
207
+ if (x.right !== this.NIL) {
205
208
  return this.getLeftMost(x.right);
206
209
  }
207
210
  let y = x.parent;
208
- while (y !== exports.NIL && y !== null && x === y.right) {
211
+ while (y !== this.NIL && y !== undefined && x === y.right) {
209
212
  x = y;
210
213
  y = y.parent;
211
214
  }
@@ -218,95 +221,51 @@ class RedBlackTree {
218
221
  * @returns the predecessor of the given RBTreeNode 'x'.
219
222
  */
220
223
  getPredecessor(x) {
221
- if (x.left !== exports.NIL) {
224
+ if (x.left !== this.NIL) {
222
225
  return this.getRightMost(x.left);
223
226
  }
224
227
  let y = x.parent;
225
- while (y !== exports.NIL && x === y.left) {
228
+ while (y !== this.NIL && x === y.left) {
226
229
  x = y;
227
230
  y = y.parent;
228
231
  }
229
232
  return y;
230
233
  }
231
234
  clear() {
232
- this._root = exports.NIL;
235
+ this._root = this.NIL;
233
236
  this._size = 0;
234
237
  }
235
- print(beginRoot = this.root) {
236
- const display = (root) => {
237
- const [lines, , ,] = _displayAux(root);
238
- for (const line of lines) {
239
- console.log(line);
240
- }
241
- };
242
- const _displayAux = (node) => {
243
- if (node === null) {
244
- return [[], 0, 0, 0];
245
- }
246
- if (node.right === null && node.left === null) {
247
- const line = `${node.key}`;
248
- const width = line.length;
249
- const height = 1;
250
- const middle = Math.floor(width / 2);
251
- return [[line], width, height, middle];
252
- }
253
- if (node.right === null) {
254
- const [lines, n, p, x] = _displayAux(node.left);
255
- const s = `${node.key}`;
256
- const u = s.length;
257
- const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s;
258
- const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u);
259
- const shifted_lines = lines.map(line => line + ' '.repeat(u));
260
- return [[first_line, second_line, ...shifted_lines], n + u, p + 2, n + Math.floor(u / 2)];
261
- }
262
- if (node.left === null) {
263
- const [lines, n, p, u] = _displayAux(node.right);
264
- const s = `${node.key}`;
265
- const x = s.length;
266
- const first_line = s + '_'.repeat(x) + ' '.repeat(n - x);
267
- const second_line = ' '.repeat(u + x) + '\\' + ' '.repeat(n - x - 1);
268
- const shifted_lines = lines.map(line => ' '.repeat(u) + line);
269
- return [[first_line, second_line, ...shifted_lines], n + x, p + 2, Math.floor(u / 2)];
270
- }
271
- const [left, n, p, x] = _displayAux(node.left);
272
- const [right, m, q, y] = _displayAux(node.right);
273
- const s = `${node.key}`;
274
- const u = s.length;
275
- const first_line = ' '.repeat(x + 1) + '_'.repeat(n - x - 1) + s + '_'.repeat(y) + ' '.repeat(m - y);
276
- const second_line = ' '.repeat(x) + '/' + ' '.repeat(n - x - 1 + u + y) + '\\' + ' '.repeat(m - y - 1);
277
- if (p < q) {
278
- left.push(...new Array(q - p).fill(' '.repeat(n)));
279
- }
280
- else if (q < p) {
281
- right.push(...new Array(p - q).fill(' '.repeat(m)));
282
- }
283
- const zipped_lines = left.map((a, i) => a + ' '.repeat(u) + right[i]);
284
- return [[first_line, second_line, ...zipped_lines], n + m + u, Math.max(p, q) + 2, n + Math.floor(u / 2)];
285
- };
286
- display(beginRoot);
238
+ _setRoot(v) {
239
+ if (v) {
240
+ v.parent = undefined;
241
+ }
242
+ this._root = v;
287
243
  }
288
244
  /**
289
245
  * The function performs a left rotation on a red-black tree node.
290
246
  * @param {RBTreeNode} x - The parameter `x` is a RBTreeNode object.
291
247
  */
292
248
  _leftRotate(x) {
293
- const y = x.right;
294
- x.right = y.left;
295
- if (y.left !== exports.NIL) {
296
- y.left.parent = x;
297
- }
298
- y.parent = x.parent;
299
- if (x.parent === null) {
300
- this._root = y;
301
- }
302
- else if (x === x.parent.left) {
303
- x.parent.left = y;
304
- }
305
- else {
306
- x.parent.right = y;
249
+ if (x.right) {
250
+ const y = x.right;
251
+ x.right = y.left;
252
+ if (y.left !== this.NIL) {
253
+ if (y.left)
254
+ y.left.parent = x;
255
+ }
256
+ y.parent = x.parent;
257
+ if (x.parent === undefined) {
258
+ this._setRoot(y);
259
+ }
260
+ else if (x === x.parent.left) {
261
+ x.parent.left = y;
262
+ }
263
+ else {
264
+ x.parent.right = y;
265
+ }
266
+ y.left = x;
267
+ x.parent = y;
307
268
  }
308
- y.left = x;
309
- x.parent = y;
310
269
  }
311
270
  /**
312
271
  * The function performs a right rotation on a red-black tree node.
@@ -314,23 +273,26 @@ class RedBlackTree {
314
273
  * rotated.
315
274
  */
316
275
  _rightRotate(x) {
317
- const y = x.left;
318
- x.left = y.right;
319
- if (y.right !== exports.NIL) {
320
- y.right.parent = x;
321
- }
322
- y.parent = x.parent;
323
- if (x.parent === null) {
324
- this._root = y;
325
- }
326
- else if (x === x.parent.right) {
327
- x.parent.right = y;
328
- }
329
- else {
330
- x.parent.left = y;
276
+ if (x.left) {
277
+ const y = x.left;
278
+ x.left = y.right;
279
+ if (y.right !== this.NIL) {
280
+ if (y.right)
281
+ y.right.parent = x;
282
+ }
283
+ y.parent = x.parent;
284
+ if (x.parent === undefined) {
285
+ this._setRoot(y);
286
+ }
287
+ else if (x === x.parent.right) {
288
+ x.parent.right = y;
289
+ }
290
+ else {
291
+ x.parent.left = y;
292
+ }
293
+ y.right = x;
294
+ x.parent = y;
331
295
  }
332
- y.right = x;
333
- x.parent = y;
334
296
  }
335
297
  /**
336
298
  * The _fixDelete function is used to rebalance the Red-Black Tree after a node deletion.
@@ -340,7 +302,7 @@ class RedBlackTree {
340
302
  _fixDelete(x) {
341
303
  let s;
342
304
  while (x !== this.root && x.color === types_1.RBTNColor.BLACK) {
343
- if (x === x.parent.left) {
305
+ if (x.parent && x === x.parent.left) {
344
306
  s = x.parent.right;
345
307
  if (s.color === 1) {
346
308
  s.color = types_1.RBTNColor.BLACK;
@@ -348,20 +310,23 @@ class RedBlackTree {
348
310
  this._leftRotate(x.parent);
349
311
  s = x.parent.right;
350
312
  }
351
- if (s.left !== null && s.left.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
313
+ if (s.left !== undefined && s.left.color === types_1.RBTNColor.BLACK && s.right && s.right.color === types_1.RBTNColor.BLACK) {
352
314
  s.color = types_1.RBTNColor.RED;
353
315
  x = x.parent;
354
316
  }
355
317
  else {
356
- if (s.right.color === types_1.RBTNColor.BLACK) {
357
- s.left.color = types_1.RBTNColor.BLACK;
318
+ if (s.right && s.right.color === types_1.RBTNColor.BLACK) {
319
+ if (s.left)
320
+ s.left.color = types_1.RBTNColor.BLACK;
358
321
  s.color = types_1.RBTNColor.RED;
359
322
  this._rightRotate(s);
360
323
  s = x.parent.right;
361
324
  }
362
- s.color = x.parent.color;
325
+ if (s)
326
+ s.color = x.parent.color;
363
327
  x.parent.color = types_1.RBTNColor.BLACK;
364
- s.right.color = types_1.RBTNColor.BLACK;
328
+ if (s && s.right)
329
+ s.right.color = types_1.RBTNColor.BLACK;
365
330
  this._leftRotate(x.parent);
366
331
  x = this.root;
367
332
  }
@@ -374,20 +339,23 @@ class RedBlackTree {
374
339
  this._rightRotate(x.parent);
375
340
  s = x.parent.left;
376
341
  }
377
- if (s.right.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
342
+ if (s && s.right && s.right.color === types_1.RBTNColor.BLACK && s.right.color === types_1.RBTNColor.BLACK) {
378
343
  s.color = types_1.RBTNColor.RED;
379
344
  x = x.parent;
380
345
  }
381
346
  else {
382
- if (s.left.color === types_1.RBTNColor.BLACK) {
383
- s.right.color = types_1.RBTNColor.BLACK;
347
+ if (s && s.left && s.left.color === types_1.RBTNColor.BLACK) {
348
+ if (s.right)
349
+ s.right.color = types_1.RBTNColor.BLACK;
384
350
  s.color = types_1.RBTNColor.RED;
385
351
  this._leftRotate(s);
386
352
  s = x.parent.left;
387
353
  }
388
- s.color = x.parent.color;
354
+ if (s)
355
+ s.color = x.parent.color;
389
356
  x.parent.color = types_1.RBTNColor.BLACK;
390
- s.left.color = types_1.RBTNColor.BLACK;
357
+ if (s && s.left)
358
+ s.left.color = types_1.RBTNColor.BLACK;
391
359
  this._rightRotate(x.parent);
392
360
  x = this.root;
393
361
  }
@@ -401,8 +369,8 @@ class RedBlackTree {
401
369
  * @param {RBTreeNode} v - The parameter "v" is a RBTreeNode object.
402
370
  */
403
371
  _rbTransplant(u, v) {
404
- if (u.parent === null) {
405
- this._root = v;
372
+ if (u.parent === undefined) {
373
+ this._setRoot(v);
406
374
  }
407
375
  else if (u === u.parent.left) {
408
376
  u.parent.left = v;
@@ -419,10 +387,10 @@ class RedBlackTree {
419
387
  */
420
388
  _fixInsert(k) {
421
389
  let u;
422
- while (k.parent.color === 1) {
423
- if (k.parent === k.parent.parent.right) {
390
+ while (k.parent && k.parent.color === 1) {
391
+ if (k.parent.parent && k.parent === k.parent.parent.right) {
424
392
  u = k.parent.parent.left;
425
- if (u.color === 1) {
393
+ if (u && u.color === 1) {
426
394
  u.color = types_1.RBTNColor.BLACK;
427
395
  k.parent.color = types_1.RBTNColor.BLACK;
428
396
  k.parent.parent.color = types_1.RBTNColor.RED;
@@ -440,7 +408,7 @@ class RedBlackTree {
440
408
  }
441
409
  else {
442
410
  u = k.parent.parent.right;
443
- if (u.color === 1) {
411
+ if (u && u.color === 1) {
444
412
  u.color = types_1.RBTNColor.BLACK;
445
413
  k.parent.color = types_1.RBTNColor.BLACK;
446
414
  k.parent.parent.color = types_1.RBTNColor.RED;