red-black-tree-typed 1.53.7 → 1.54.1

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 (114) hide show
  1. package/README.md +52 -0
  2. package/dist/common/index.js +5 -0
  3. package/dist/data-structures/base/iterable-entry-base.js +4 -4
  4. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +213 -0
  5. package/dist/data-structures/binary-tree/avl-tree-counter.js +407 -0
  6. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +71 -170
  7. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +133 -328
  8. package/dist/data-structures/binary-tree/avl-tree.d.ts +103 -69
  9. package/dist/data-structures/binary-tree/avl-tree.js +130 -70
  10. package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +3 -0
  11. package/dist/data-structures/binary-tree/binary-indexed-tree.js +3 -0
  12. package/dist/data-structures/binary-tree/binary-tree.d.ts +268 -202
  13. package/dist/data-structures/binary-tree/binary-tree.js +311 -263
  14. package/dist/data-structures/binary-tree/bst.d.ts +193 -139
  15. package/dist/data-structures/binary-tree/bst.js +248 -164
  16. package/dist/data-structures/binary-tree/index.d.ts +3 -1
  17. package/dist/data-structures/binary-tree/index.js +3 -1
  18. package/dist/data-structures/binary-tree/red-black-tree.d.ts +286 -0
  19. package/dist/data-structures/binary-tree/{rb-tree.js → red-black-tree.js} +176 -107
  20. package/dist/data-structures/binary-tree/tree-counter.d.ts +212 -0
  21. package/dist/data-structures/binary-tree/tree-counter.js +444 -0
  22. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +78 -170
  23. package/dist/data-structures/binary-tree/tree-multi-map.js +145 -367
  24. package/dist/data-structures/graph/abstract-graph.js +2 -2
  25. package/dist/data-structures/graph/directed-graph.d.ts +3 -0
  26. package/dist/data-structures/graph/directed-graph.js +3 -0
  27. package/dist/data-structures/graph/map-graph.d.ts +3 -0
  28. package/dist/data-structures/graph/map-graph.js +3 -0
  29. package/dist/data-structures/graph/undirected-graph.d.ts +3 -0
  30. package/dist/data-structures/graph/undirected-graph.js +3 -0
  31. package/dist/data-structures/hash/hash-map.d.ts +31 -1
  32. package/dist/data-structures/hash/hash-map.js +35 -5
  33. package/dist/data-structures/heap/heap.d.ts +20 -3
  34. package/dist/data-structures/heap/heap.js +31 -11
  35. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +46 -11
  36. package/dist/data-structures/linked-list/doubly-linked-list.js +68 -21
  37. package/dist/data-structures/linked-list/singly-linked-list.d.ts +47 -11
  38. package/dist/data-structures/linked-list/singly-linked-list.js +73 -26
  39. package/dist/data-structures/linked-list/skip-linked-list.d.ts +3 -0
  40. package/dist/data-structures/linked-list/skip-linked-list.js +3 -0
  41. package/dist/data-structures/matrix/matrix.d.ts +3 -0
  42. package/dist/data-structures/matrix/matrix.js +3 -0
  43. package/dist/data-structures/matrix/navigator.d.ts +3 -0
  44. package/dist/data-structures/matrix/navigator.js +3 -0
  45. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +3 -0
  46. package/dist/data-structures/priority-queue/max-priority-queue.js +3 -0
  47. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +3 -0
  48. package/dist/data-structures/priority-queue/min-priority-queue.js +3 -0
  49. package/dist/data-structures/queue/deque.d.ts +37 -8
  50. package/dist/data-structures/queue/deque.js +73 -29
  51. package/dist/data-structures/queue/queue.d.ts +41 -1
  52. package/dist/data-structures/queue/queue.js +51 -9
  53. package/dist/data-structures/stack/stack.d.ts +27 -10
  54. package/dist/data-structures/stack/stack.js +39 -20
  55. package/dist/data-structures/trie/trie.d.ts +8 -7
  56. package/dist/data-structures/trie/trie.js +8 -7
  57. package/dist/interfaces/binary-tree.d.ts +8 -8
  58. package/dist/types/data-structures/base/base.d.ts +1 -1
  59. package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +2 -0
  60. package/dist/types/data-structures/binary-tree/avl-tree-counter.js +2 -0
  61. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -4
  62. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +0 -3
  63. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +0 -3
  64. package/dist/types/data-structures/binary-tree/bst.d.ts +4 -4
  65. package/dist/types/data-structures/binary-tree/index.d.ts +2 -0
  66. package/dist/types/data-structures/binary-tree/index.js +2 -0
  67. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +2 -5
  68. package/dist/types/data-structures/binary-tree/tree-counter.d.ts +2 -0
  69. package/dist/types/data-structures/binary-tree/tree-counter.js +2 -0
  70. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -5
  71. package/package.json +2 -2
  72. package/src/common/index.ts +7 -1
  73. package/src/data-structures/base/iterable-entry-base.ts +4 -4
  74. package/src/data-structures/binary-tree/avl-tree-counter.ts +463 -0
  75. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +151 -370
  76. package/src/data-structures/binary-tree/avl-tree.ts +162 -105
  77. package/src/data-structures/binary-tree/binary-indexed-tree.ts +3 -0
  78. package/src/data-structures/binary-tree/binary-tree.ts +488 -416
  79. package/src/data-structures/binary-tree/bst.ts +326 -251
  80. package/src/data-structures/binary-tree/index.ts +3 -1
  81. package/src/data-structures/binary-tree/{rb-tree.ts → red-black-tree.ts} +219 -145
  82. package/src/data-structures/binary-tree/tree-counter.ts +504 -0
  83. package/src/data-structures/binary-tree/tree-multi-map.ts +159 -401
  84. package/src/data-structures/graph/abstract-graph.ts +2 -2
  85. package/src/data-structures/graph/directed-graph.ts +3 -0
  86. package/src/data-structures/graph/map-graph.ts +3 -0
  87. package/src/data-structures/graph/undirected-graph.ts +3 -0
  88. package/src/data-structures/hash/hash-map.ts +37 -7
  89. package/src/data-structures/heap/heap.ts +33 -10
  90. package/src/data-structures/linked-list/doubly-linked-list.ts +75 -21
  91. package/src/data-structures/linked-list/singly-linked-list.ts +80 -27
  92. package/src/data-structures/linked-list/skip-linked-list.ts +3 -0
  93. package/src/data-structures/matrix/matrix.ts +3 -0
  94. package/src/data-structures/matrix/navigator.ts +3 -0
  95. package/src/data-structures/priority-queue/max-priority-queue.ts +3 -0
  96. package/src/data-structures/priority-queue/min-priority-queue.ts +3 -0
  97. package/src/data-structures/queue/deque.ts +72 -28
  98. package/src/data-structures/queue/queue.ts +50 -7
  99. package/src/data-structures/stack/stack.ts +39 -20
  100. package/src/data-structures/trie/trie.ts +8 -7
  101. package/src/index.ts +2 -2
  102. package/src/interfaces/binary-tree.ts +10 -21
  103. package/src/types/data-structures/base/base.ts +1 -1
  104. package/src/types/data-structures/binary-tree/avl-tree-counter.ts +3 -0
  105. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -6
  106. package/src/types/data-structures/binary-tree/avl-tree.ts +0 -5
  107. package/src/types/data-structures/binary-tree/binary-tree.ts +0 -5
  108. package/src/types/data-structures/binary-tree/bst.ts +6 -6
  109. package/src/types/data-structures/binary-tree/index.ts +3 -1
  110. package/src/types/data-structures/binary-tree/red-black-tree.ts +5 -0
  111. package/src/types/data-structures/binary-tree/tree-counter.ts +3 -0
  112. package/src/types/data-structures/binary-tree/tree-multi-map.ts +2 -7
  113. package/dist/data-structures/binary-tree/rb-tree.d.ts +0 -209
  114. package/src/types/data-structures/binary-tree/rb-tree.ts +0 -10
@@ -3,6 +3,8 @@ export * from './bst';
3
3
  export * from './binary-indexed-tree';
4
4
  export * from './segment-tree';
5
5
  export * from './avl-tree';
6
- export * from './rb-tree';
6
+ export * from './red-black-tree';
7
7
  export * from './avl-tree-multi-map';
8
8
  export * from './tree-multi-map';
9
+ export * from './tree-counter';
10
+ export * from './avl-tree-counter';
@@ -2,80 +2,132 @@ import type {
2
2
  BinaryTreeDeleteResult,
3
3
  BTNRep,
4
4
  CRUD,
5
+ EntryCallback,
5
6
  OptNode,
7
+ OptNodeOrNull,
6
8
  RBTNColor,
7
- RBTreeOptions,
8
- RedBlackTreeNested,
9
- RedBlackTreeNodeNested
9
+ RedBlackTreeOptions
10
10
  } from '../../types';
11
11
  import { BST, BSTNode } from './bst';
12
12
  import { IBinaryTree } from '../../interfaces';
13
13
 
14
- export class RedBlackTreeNode<
15
- K = any,
16
- V = any,
17
- NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNodeNested<K, V>
18
- > extends BSTNode<K, V, NODE> {
14
+ export class RedBlackTreeNode<K = any, V = any> extends BSTNode<K, V> {
19
15
  /**
20
- * The constructor function initializes a Red-Black Tree Node with a key, an optional value, and a
21
- * color.
22
- * @param {K} key - The key parameter is of type K and represents the key of the node in the
23
- * Red-Black Tree.
24
- * @param {V} [value] - The `value` parameter is an optional parameter that represents the value
25
- * associated with the key in the Red-Black Tree Node. It is not required and can be omitted when
26
- * creating a new instance of the Red-Black Tree Node.
27
- * @param {RBTNColor} color - The `color` parameter is used to specify the color of the Red-Black
28
- * Tree Node. It is an optional parameter with a default value of `'BLACK'`.
16
+ * The constructor initializes a node with a key, value, and color for a Red-Black Tree.
17
+ * @param {K} key - The `key` parameter is a key of type `K` that is used to identify the node in a
18
+ * Red-Black Tree data structure.
19
+ * @param {V} [value] - The `value` parameter in the constructor is an optional parameter of type
20
+ * `V`. It represents the value associated with the key in the data structure being constructed.
21
+ * @param {RBTNColor} [color=BLACK] - The `color` parameter in the constructor is used to specify the
22
+ * color of the node in a Red-Black Tree. It has a default value of 'BLACK' if not provided
23
+ * explicitly.
29
24
  */
30
25
  constructor(key: K, value?: V, color: RBTNColor = 'BLACK') {
31
26
  super(key, value);
32
27
  this._color = color;
33
28
  }
34
29
 
35
- protected _color: RBTNColor;
30
+ override parent?: RedBlackTreeNode<K, V> = undefined;
36
31
 
37
- /**
38
- * The function returns the color value of a variable.
39
- * @returns The color value stored in the private variable `_color`.
40
- */
41
- get color(): RBTNColor {
42
- return this._color;
32
+ override _left?: OptNodeOrNull<RedBlackTreeNode<K, V>> = undefined;
33
+
34
+ override get left(): OptNodeOrNull<RedBlackTreeNode<K, V>> {
35
+ return this._left;
43
36
  }
44
37
 
45
- /**
46
- * The function sets the color property to the specified value.
47
- * @param {RBTNColor} value - The value parameter is of type RBTNColor.
48
- */
49
- set color(value: RBTNColor) {
50
- this._color = value;
38
+ override set left(v: OptNodeOrNull<RedBlackTreeNode<K, V>>) {
39
+ if (v) {
40
+ v.parent = this;
41
+ }
42
+ this._left = v;
43
+ }
44
+
45
+ override _right?: OptNodeOrNull<RedBlackTreeNode<K, V>> = undefined;
46
+
47
+ override get right(): OptNodeOrNull<RedBlackTreeNode<K, V>> {
48
+ return this._right;
49
+ }
50
+
51
+ override set right(v: OptNodeOrNull<RedBlackTreeNode<K, V>>) {
52
+ if (v) {
53
+ v.parent = this;
54
+ }
55
+ this._right = v;
51
56
  }
52
57
  }
53
58
 
54
59
  /**
55
60
  * 1. Efficient self-balancing, but not completely balanced. Compared with AVLTree, the addition and deletion efficiency is high but the query efficiency is slightly lower.
56
61
  * 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
62
+ * @example
63
+ * // Find elements in a range
64
+ * const bst = new RedBlackTree<number>([10, 5, 15, 3, 7, 12, 18]);
65
+ * console.log(bst.search(new Range(5, 10))); // [5, 10, 7]
66
+ * console.log(bst.search(new Range(4, 12))); // [5, 10, 12, 7]
67
+ * console.log(bst.search(new Range(15, 20))); // [15, 18]
68
+ * @example
69
+ * // using Red-Black Tree as a price-based index for stock data
70
+ * // Define the structure of individual stock records
71
+ * interface StockRecord {
72
+ * price: number; // Stock price (key for indexing)
73
+ * symbol: string; // Stock ticker symbol
74
+ * volume: number; // Trade volume
75
+ * }
76
+ *
77
+ * // Simulate stock market data as it might come from an external feed
78
+ * const marketStockData: StockRecord[] = [
79
+ * { price: 142.5, symbol: 'AAPL', volume: 1000000 },
80
+ * { price: 335.2, symbol: 'MSFT', volume: 800000 },
81
+ * { price: 3285.04, symbol: 'AMZN', volume: 500000 },
82
+ * { price: 267.98, symbol: 'META', volume: 750000 },
83
+ * { price: 234.57, symbol: 'GOOGL', volume: 900000 }
84
+ * ];
85
+ *
86
+ * // Extend the stock record type to include metadata for database usage
87
+ * type StockTableRecord = StockRecord & { lastUpdated: Date };
88
+ *
89
+ * // Create a Red-Black Tree to index stock records by price
90
+ * // Simulates a database index with stock price as the key for quick lookups
91
+ * const priceIndex = new RedBlackTree<number, StockTableRecord, StockRecord>(marketStockData, {
92
+ * toEntryFn: stockRecord => [
93
+ * stockRecord.price, // Use stock price as the key
94
+ * {
95
+ * ...stockRecord,
96
+ * lastUpdated: new Date() // Add a timestamp for when the record was indexed
97
+ * }
98
+ * ]
99
+ * });
100
+ *
101
+ * // Query the stock with the highest price
102
+ * const highestPricedStock = priceIndex.getRightMost();
103
+ * console.log(priceIndex.get(highestPricedStock)?.symbol); // 'AMZN' // Amazon has the highest price
104
+ *
105
+ * // Query stocks within a specific price range (200 to 400)
106
+ * const stocksInRange = priceIndex.rangeSearch(
107
+ * [200, 400], // Price range
108
+ * node => priceIndex.get(node)?.symbol // Extract stock symbols for the result
109
+ * );
110
+ * console.log(stocksInRange); // ['GOOGL', 'MSFT', 'META']
57
111
  */
58
- export class RedBlackTree<
59
- K = any,
60
- V = any,
61
- R = object,
62
- NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>,
63
- TREE extends RedBlackTree<K, V, R, NODE, TREE> = RedBlackTree<K, V, R, NODE, RedBlackTreeNested<K, V, R, NODE>>
64
- >
65
- extends BST<K, V, R, NODE, TREE>
66
- implements IBinaryTree<K, V, R, NODE, TREE>
112
+ export class RedBlackTree<K = any, V = any, R = object, MK = any, MV = any, MR = object>
113
+ extends BST<K, V, R, MK, MV, MR>
114
+ implements IBinaryTree<K, V, R, MK, MV, MR>
67
115
  {
68
116
  /**
69
- * This is the constructor function for a Red-Black Tree data structure in TypeScript.
70
- * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter is an
71
- * iterable object that can contain either keys, nodes, entries, or raw elements. It is used to
72
- * initialize the RBTree with the provided elements.
73
- * @param [options] - The `options` parameter is an optional object that can be passed to the
74
- * constructor. It is of type `RBTreeOptions<K, V, R>`. This object can contain various options for
75
- * configuring the behavior of the Red-Black Tree. The specific properties and their meanings would
76
- * depend on the implementation
117
+ * This TypeScript constructor initializes a Red-Black Tree with optional keys, nodes, entries, or
118
+ * raw data.
119
+ * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an
120
+ * iterable that can contain either `BTNRep<K, V, RedBlackTreeNode<K, V>>` objects or `R` objects. It
121
+ * is used to initialize the Red-Black Tree with keys, nodes, entries, or
122
+ * @param [options] - The `options` parameter in the constructor is of type `RedBlackTreeOptions<K,
123
+ * V, R>`. It is an optional parameter that allows you to specify additional options for the
124
+ * RedBlackTree class. These options could include configuration settings, behavior customization, or
125
+ * any other parameters that are specific to
77
126
  */
78
- constructor(keysNodesEntriesOrRaws: Iterable<R | BTNRep<K, V, NODE>> = [], options?: RBTreeOptions<K, V, R>) {
127
+ constructor(
128
+ keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, RedBlackTreeNode<K, V>> | R> = [],
129
+ options?: RedBlackTreeOptions<K, V, R>
130
+ ) {
79
131
  super([], options);
80
132
 
81
133
  this._root = this.NIL;
@@ -85,17 +137,16 @@ export class RedBlackTree<
85
137
  }
86
138
  }
87
139
 
88
- protected override _root: NODE | undefined;
140
+ protected override _root: RedBlackTreeNode<K, V> | undefined;
89
141
 
90
- /**
91
- * The function returns the root node of a tree or undefined if there is no root.
92
- * @returns The root node of the tree structure, or undefined if there is no root node.
93
- */
94
- override get root(): NODE | undefined {
142
+ override get root(): RedBlackTreeNode<K, V> | undefined {
95
143
  return this._root;
96
144
  }
97
145
 
98
146
  /**
147
+ * Time Complexity: O(1)
148
+ * Space Complexity: O(1)
149
+ *
99
150
  * The function creates a new Red-Black Tree node with the specified key, value, and color.
100
151
  * @param {K} key - The key parameter represents the key value of the node being created. It is of
101
152
  * type K, which is a generic type that can be replaced with any specific type when using the
@@ -109,24 +160,27 @@ export class RedBlackTree<
109
160
  * @returns A new instance of a RedBlackTreeNode with the specified key, value, and color is being
110
161
  * returned.
111
162
  */
112
- override createNode(key: K, value?: V, color: RBTNColor = 'BLACK'): NODE {
113
- return new RedBlackTreeNode<K, V, NODE>(key, this._isMapMode ? undefined : value, color) as NODE;
163
+ override createNode(key: K, value?: V, color: RBTNColor = 'BLACK'): RedBlackTreeNode<K, V> {
164
+ return new RedBlackTreeNode<K, V>(key, this._isMapMode ? undefined : value, color);
114
165
  }
115
166
 
116
167
  /**
168
+ * Time Complexity: O(1)
169
+ * Space Complexity: O(1)
170
+ *
117
171
  * The function creates a new Red-Black Tree with the specified options.
118
172
  * @param [options] - The `options` parameter is an optional object that contains additional
119
173
  * configuration options for creating the Red-Black Tree. It has the following properties:
120
174
  * @returns a new instance of a RedBlackTree object.
121
175
  */
122
- override createTree(options?: RBTreeOptions<K, V, R>): TREE {
123
- return new RedBlackTree<K, V, R, NODE, TREE>([], {
176
+ override createTree(options?: RedBlackTreeOptions<K, V, R>) {
177
+ return new RedBlackTree<K, V, R, MK, MV, MR>([], {
124
178
  iterationType: this.iterationType,
125
179
  isMapMode: this._isMapMode,
126
- extractComparable: this._extractComparable,
180
+ specifyComparable: this._specifyComparable,
127
181
  toEntryFn: this._toEntryFn,
128
182
  ...options
129
- }) as TREE;
183
+ });
130
184
  }
131
185
 
132
186
  /**
@@ -134,51 +188,15 @@ export class RedBlackTree<
134
188
  * Space Complexity: O(1)
135
189
  *
136
190
  * The function checks if the input is an instance of the RedBlackTreeNode class.
137
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
138
- * `keyNodeEntryOrRaw` can be of type `R` or `BTNRep<K, V, NODE>`.
139
- * @returns a boolean value indicating whether the input parameter `keyNodeEntryOrRaw` is
191
+ * @param {BTNRep<K, V, RedBlackTreeNode<K, V>>} keyNodeOrEntry - The parameter
192
+ * `keyNodeOrEntry` can be of type `R` or `BTNRep<K, V, RedBlackTreeNode<K, V>>`.
193
+ * @returns a boolean value indicating whether the input parameter `keyNodeOrEntry` is
140
194
  * an instance of the `RedBlackTreeNode` class.
141
195
  */
142
- override isNode(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): keyNodeEntryOrRaw is NODE {
143
- return keyNodeEntryOrRaw instanceof RedBlackTreeNode;
196
+ override isNode(keyNodeOrEntry: BTNRep<K, V, RedBlackTreeNode<K, V>>): keyNodeOrEntry is RedBlackTreeNode<K, V> {
197
+ return keyNodeOrEntry instanceof RedBlackTreeNode;
144
198
  }
145
199
 
146
- // /**
147
- // * Time Complexity: O(1)
148
- // * Space Complexity: O(1)
149
- // */
150
- //
151
- // /**
152
- // * Time Complexity: O(1)
153
- // * Space Complexity: O(1)
154
- // *
155
- // * The function `keyValueNodeEntryRawToNodeAndValue` takes a key, value, or entry and returns a node if it is
156
- // * valid, otherwise it returns undefined.
157
- // * @param {BTNRep<K, V, NODE>} keyNodeEntryOrRaw - The key, value, or entry to convert.
158
- // * @param {V} [value] - The value associated with the key (if `keyNodeEntryOrRaw` is a key).
159
- // * @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails.
160
- // */
161
- // override keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): NODE | undefined {
162
- //
163
- // if (keyNodeEntryOrRaw === null || keyNodeEntryOrRaw === undefined) return;
164
- // if (this.isNode(keyNodeEntryOrRaw)) return keyNodeEntryOrRaw;
165
- //
166
- // if (this._toEntryFn) {
167
- // const [key, entryValue] = this._toEntryFn(keyNodeEntryOrRaw as R);
168
- // if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'RED');
169
- // }
170
- //
171
- // if (this.isEntry(keyNodeEntryOrRaw)) {
172
- // const [key, value] = keyNodeEntryOrRaw;
173
- // if (key === undefined || key === null) return;
174
- // else return this.createNode(key, value, 'RED');
175
- // }
176
- //
177
- // if (this.isKey(keyNodeEntryOrRaw)) return this.createNode(keyNodeEntryOrRaw, value, 'RED');
178
- //
179
- // return ;
180
- // }
181
-
182
200
  /**
183
201
  * Time Complexity: O(1)
184
202
  * Space Complexity: O(1)
@@ -193,12 +211,12 @@ export class RedBlackTree<
193
211
 
194
212
  /**
195
213
  * Time Complexity: O(log n)
196
- * Space Complexity: O(1)
214
+ * Space Complexity: O(log n)
197
215
  *
198
216
  * The function adds a new node to a binary search tree and returns true if the node was successfully
199
217
  * added.
200
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
201
- * `keyNodeEntryOrRaw` can accept a value of type `R` or `BTNRep<K, V, NODE>`.
218
+ * @param {BTNRep<K, V, RedBlackTreeNode<K, V>>} keyNodeOrEntry - The parameter
219
+ * `keyNodeOrEntry` can accept a value of type `R` or `BTNRep<K, V, RedBlackTreeNode<K, V>>`.
202
220
  * @param {V} [value] - The `value` parameter is an optional value that you want to associate with
203
221
  * the key in the data structure. It represents the value that you want to add or update in the data
204
222
  * structure.
@@ -206,8 +224,8 @@ export class RedBlackTree<
206
224
  * the method returns true. If the node already exists and its value is updated, the method also
207
225
  * returns true. If the node cannot be added or updated, the method returns false.
208
226
  */
209
- override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
210
- const [newNode, newValue] = this.keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
227
+ override add(keyNodeOrEntry: BTNRep<K, V, RedBlackTreeNode<K, V>>, value?: V): boolean {
228
+ const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
211
229
  if (!this.isRealNode(newNode)) return false;
212
230
 
213
231
  const insertStatus = this._insert(newNode);
@@ -232,36 +250,40 @@ export class RedBlackTree<
232
250
 
233
251
  /**
234
252
  * Time Complexity: O(log n)
235
- * Space Complexity: O(1)
253
+ * Space Complexity: O(log n)
236
254
  *
237
255
  * The function overrides the delete method in a binary tree data structure to remove a node based on
238
256
  * a given predicate and maintain the binary search tree properties.
239
- * @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The `keyNodeEntryOrRaw`
257
+ * @param {BTNRep<K, V, RedBlackTreeNode<K, V>>} keyNodeOrEntry - The `keyNodeOrEntry`
240
258
  * parameter in the `override delete` method is used to specify the condition or key based on which a
241
259
  * node should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate
242
260
  * function that determines which node(s) should be deleted.
243
- * @returns The `override delete` method is returning an array of `BinaryTreeDeleteResult<NODE>`
261
+ * @returns The `override delete` method is returning an array of `BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>`
244
262
  * objects. Each object in the array contains information about the deleted node and whether
245
263
  * balancing is needed.
246
264
  */
247
- override delete(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R): BinaryTreeDeleteResult<NODE>[] {
248
- if (keyNodeEntryOrRaw === null) return [];
265
+ override delete(
266
+ keyNodeOrEntry: BTNRep<K, V, RedBlackTreeNode<K, V>>
267
+ ): BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>[] {
268
+ if (keyNodeOrEntry === null) return [];
249
269
 
250
- const results: BinaryTreeDeleteResult<NODE>[] = [];
251
- let nodeToDelete: OptNode<NODE>;
252
- if (this._isPredicate(keyNodeEntryOrRaw)) nodeToDelete = this.getNode(keyNodeEntryOrRaw);
253
- else nodeToDelete = this.isRealNode(keyNodeEntryOrRaw) ? keyNodeEntryOrRaw : this.getNode(keyNodeEntryOrRaw);
270
+ const results: BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>[] = [];
271
+ let nodeToDelete: OptNode<RedBlackTreeNode<K, V>>;
272
+ if (this._isPredicate(keyNodeOrEntry)) nodeToDelete = this.getNode(keyNodeOrEntry);
273
+ else nodeToDelete = this.isRealNode(keyNodeOrEntry) ? keyNodeOrEntry : this.getNode(keyNodeOrEntry);
254
274
 
255
275
  if (!nodeToDelete) {
256
276
  return results;
257
277
  }
258
278
 
259
279
  let originalColor = nodeToDelete.color;
260
- let replacementNode: NODE | undefined;
280
+ let replacementNode: RedBlackTreeNode<K, V> | undefined;
261
281
 
262
282
  if (!this.isRealNode(nodeToDelete.left)) {
263
- replacementNode = nodeToDelete.right;
264
- this._transplant(nodeToDelete, nodeToDelete.right);
283
+ if (nodeToDelete.right !== null) {
284
+ replacementNode = nodeToDelete.right;
285
+ this._transplant(nodeToDelete, nodeToDelete.right);
286
+ }
265
287
  } else if (!this.isRealNode(nodeToDelete.right)) {
266
288
  replacementNode = nodeToDelete.left;
267
289
  this._transplant(nodeToDelete, nodeToDelete.left);
@@ -269,15 +291,17 @@ export class RedBlackTree<
269
291
  const successor = this.getLeftMost(node => node, nodeToDelete.right);
270
292
  if (successor) {
271
293
  originalColor = successor.color;
272
- replacementNode = successor.right;
294
+ if (successor.right !== null) replacementNode = successor.right;
273
295
 
274
296
  if (successor.parent === nodeToDelete) {
275
297
  if (this.isRealNode(replacementNode)) {
276
298
  replacementNode.parent = successor;
277
299
  }
278
300
  } else {
279
- this._transplant(successor, successor.right);
280
- successor.right = nodeToDelete.right;
301
+ if (successor.right !== null) {
302
+ this._transplant(successor, successor.right);
303
+ successor.right = nodeToDelete.right;
304
+ }
281
305
  if (this.isRealNode(successor.right)) {
282
306
  successor.right.parent = successor;
283
307
  }
@@ -304,15 +328,62 @@ export class RedBlackTree<
304
328
  return results;
305
329
  }
306
330
 
331
+ /**
332
+ * Time Complexity: O(n)
333
+ * Space Complexity: O(n)
334
+ *
335
+ * The `map` function in TypeScript overrides the default behavior to create a new Red-Black Tree by
336
+ * applying a callback to each entry in the original tree.
337
+ * @param callback - A function that will be called for each entry in the tree, with parameters
338
+ * representing the key, value, index, and the tree itself. It should return an entry for the new
339
+ * tree.
340
+ * @param [options] - The `options` parameter in the `map` method is of type `RedBlackTreeOptions<MK, MV,
341
+ * MR>`. This parameter allows you to specify additional options or configurations for the Red-Black
342
+ * Tree that will be created during the mapping process. These options could include things like
343
+ * custom comparators
344
+ * @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
345
+ * the value of `this` when executing the `callback` function. It allows you to set the context
346
+ * (value of `this`) for the callback function. This can be useful when you want to access properties
347
+ * or
348
+ * @returns A new Red-Black Tree is being returned, where each entry has been transformed using the
349
+ * provided callback function.
350
+ */
351
+ override map(
352
+ callback: EntryCallback<K, V | undefined, [MK, MV]>,
353
+ options?: RedBlackTreeOptions<MK, MV, MR>,
354
+ thisArg?: any
355
+ ): RedBlackTree<MK, MV, MR> {
356
+ const newTree = new RedBlackTree<MK, MV, MR>([], options);
357
+ let index = 0;
358
+ for (const [key, value] of this) {
359
+ newTree.add(callback.call(thisArg, key, value, index++, this));
360
+ }
361
+ return newTree;
362
+ }
363
+
364
+ /**
365
+ * Time Complexity: O(n)
366
+ * Space Complexity: O(n)
367
+ *
368
+ * The function `clone` overrides the default cloning behavior to create a deep copy of a tree
369
+ * structure.
370
+ * @returns The `cloned` object is being returned.
371
+ */
372
+ override clone() {
373
+ const cloned = this.createTree();
374
+ this._clone(cloned);
375
+ return cloned;
376
+ }
377
+
307
378
  /**
308
379
  * Time Complexity: O(1)
309
380
  * Space Complexity: O(1)
310
381
  *
311
382
  * The function sets the root of a tree-like structure and updates the parent property of the new
312
383
  * root.
313
- * @param {NODE | undefined} v - v is a parameter of type NODE or undefined.
384
+ * @param {RedBlackTreeNode<K, V> | undefined} v - v is a parameter of type RedBlackTreeNode<K, V> or undefined.
314
385
  */
315
- protected override _setRoot(v: NODE | undefined) {
386
+ protected override _setRoot(v: RedBlackTreeNode<K, V> | undefined) {
316
387
  if (v) {
317
388
  v.parent = undefined;
318
389
  }
@@ -324,14 +395,17 @@ export class RedBlackTree<
324
395
  * Space Complexity: O(1)
325
396
  *
326
397
  * The function replaces an old node with a new node while preserving the color of the old node.
327
- * @param {NODE} oldNode - The `oldNode` parameter represents the node that needs to be replaced in
398
+ * @param {RedBlackTreeNode<K, V>} oldNode - The `oldNode` parameter represents the node that needs to be replaced in
328
399
  * the data structure.
329
- * @param {NODE} newNode - The `newNode` parameter is of type `NODE`, which represents a node in a
400
+ * @param {RedBlackTreeNode<K, V>} newNode - The `newNode` parameter is of type `RedBlackTreeNode<K, V>`, which represents a node in a
330
401
  * data structure.
331
402
  * @returns The method is returning the result of calling the `_replaceNode` method from the
332
403
  * superclass, with the `oldNode` and `newNode` parameters.
333
404
  */
334
- protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {
405
+ protected override _replaceNode(
406
+ oldNode: RedBlackTreeNode<K, V>,
407
+ newNode: RedBlackTreeNode<K, V>
408
+ ): RedBlackTreeNode<K, V> {
335
409
  newNode.color = oldNode.color;
336
410
 
337
411
  return super._replaceNode(oldNode, newNode);
@@ -339,19 +413,19 @@ export class RedBlackTree<
339
413
 
340
414
  /**
341
415
  * Time Complexity: O(log n)
342
- * Space Complexity: O(1)
416
+ * Space Complexity: O(log n)
343
417
  *
344
418
  * The `_insert` function inserts a node into a binary search tree and performs necessary fix-ups to
345
419
  * maintain the red-black tree properties.
346
- * @param {NODE} node - The `node` parameter represents the node that needs to be inserted into the
420
+ * @param {RedBlackTreeNode<K, V>} node - The `node` parameter represents the node that needs to be inserted into the
347
421
  * binary search tree.
348
422
  * @returns a string value indicating the result of the insertion operation. It can return either
349
423
  * 'UPDATED' if the node with the same key already exists and was updated, or 'CREATED' if a new node
350
424
  * was created and inserted into the tree.
351
425
  */
352
- protected _insert(node: NODE): CRUD {
426
+ protected _insert(node: RedBlackTreeNode<K, V>): CRUD {
353
427
  let current = this.root;
354
- let parent: NODE | undefined = undefined;
428
+ let parent: RedBlackTreeNode<K, V> | undefined = undefined;
355
429
 
356
430
  while (this.isRealNode(current)) {
357
431
  parent = current;
@@ -370,7 +444,7 @@ export class RedBlackTree<
370
444
 
371
445
  if (!parent) {
372
446
  this._setRoot(node);
373
- } else if (node.key < parent.key) {
447
+ } else if (this._compare(node.key, parent.key) < 0) {
374
448
  parent.left = node;
375
449
  } else {
376
450
  parent.right = node;
@@ -389,11 +463,11 @@ export class RedBlackTree<
389
463
  * Space Complexity: O(1)
390
464
  *
391
465
  * The function `_transplant` is used to replace a node `u` with another node `v` in a binary tree.
392
- * @param {NODE} u - The parameter "u" represents a node in a binary tree.
393
- * @param {NODE | undefined} v - The parameter `v` is of type `NODE | undefined`, which means it can
394
- * either be a `NODE` object or `undefined`.
466
+ * @param {RedBlackTreeNode<K, V>} u - The parameter "u" represents a node in a binary tree.
467
+ * @param {RedBlackTreeNode<K, V> | undefined} v - The parameter `v` is of type `RedBlackTreeNode<K, V> | undefined`, which means it can
468
+ * either be a `RedBlackTreeNode<K, V>` object or `undefined`.
395
469
  */
396
- protected _transplant(u: NODE, v: NODE | undefined): void {
470
+ protected _transplant(u: RedBlackTreeNode<K, V>, v: RedBlackTreeNode<K, V> | undefined): void {
397
471
  if (!u.parent) {
398
472
  this._setRoot(v);
399
473
  } else if (u === u.parent.left) {
@@ -412,10 +486,10 @@ export class RedBlackTree<
412
486
  * Space Complexity: O(1)
413
487
  *
414
488
  * The `_insertFixup` function is used to fix the Red-Black Tree after inserting a new node.
415
- * @param {NODE | undefined} z - The parameter `z` represents a node in the Red-Black Tree data
489
+ * @param {RedBlackTreeNode<K, V> | undefined} z - The parameter `z` represents a node in the Red-Black Tree data
416
490
  * structure. It can either be a valid node or `undefined`.
417
491
  */
418
- protected _insertFixup(z: NODE | undefined): void {
492
+ protected _insertFixup(z: RedBlackTreeNode<K, V> | undefined): void {
419
493
  // Continue fixing the tree as long as the parent of z is red
420
494
  while (z?.parent?.color === 'RED') {
421
495
  // Check if the parent of z is the left child of its parent
@@ -448,7 +522,7 @@ export class RedBlackTree<
448
522
  } else {
449
523
  // Symmetric case for the right child (left and right exchanged)
450
524
  // Follow the same logic as above with left and right exchanged
451
- const y: NODE | undefined = z?.parent?.parent?.left;
525
+ const y: RedBlackTreeNode<K, V> | undefined = z?.parent?.parent?.left ?? undefined;
452
526
  if (y?.color === 'RED') {
453
527
  z.parent.color = 'BLACK';
454
528
  y.color = 'BLACK';
@@ -479,12 +553,12 @@ export class RedBlackTree<
479
553
  *
480
554
  * The `_deleteFixup` function is used to fix the red-black tree after a node deletion by adjusting
481
555
  * the colors and performing rotations.
482
- * @param {NODE | undefined} node - The `node` parameter represents a node in a binary tree. It can
556
+ * @param {RedBlackTreeNode<K, V> | undefined} node - The `node` parameter represents a node in a binary tree. It can
483
557
  * be either a valid node object or `undefined`.
484
558
  * @returns The function does not return any value. It has a return type of `void`, which means it
485
559
  * does not return anything.
486
560
  */
487
- protected _deleteFixup(node: NODE | undefined): void {
561
+ protected _deleteFixup(node: RedBlackTreeNode<K, V> | undefined): void {
488
562
  // Early exit condition
489
563
  if (!node || node === this.root || node.color === 'BLACK') {
490
564
  if (node) {
@@ -494,7 +568,7 @@ export class RedBlackTree<
494
568
  }
495
569
 
496
570
  while (node && node !== this.root && node.color === 'BLACK') {
497
- const parent: NODE | undefined = node.parent;
571
+ const parent: RedBlackTreeNode<K, V> | undefined = node.parent;
498
572
 
499
573
  if (!parent) {
500
574
  break; // Ensure the loop terminates if there's an issue with the tree structure
@@ -561,11 +635,11 @@ export class RedBlackTree<
561
635
  * Space Complexity: O(1)
562
636
  *
563
637
  * The `_leftRotate` function performs a left rotation on a given node in a binary tree.
564
- * @param {NODE | undefined} x - The parameter `x` is of type `NODE | undefined`. It represents a
638
+ * @param {RedBlackTreeNode<K, V> | undefined} x - The parameter `x` is of type `RedBlackTreeNode<K, V> | undefined`. It represents a
565
639
  * node in a binary tree or `undefined` if there is no node.
566
640
  * @returns void, which means it does not return any value.
567
641
  */
568
- protected _leftRotate(x: NODE | undefined): void {
642
+ protected _leftRotate(x: RedBlackTreeNode<K, V> | undefined): void {
569
643
  if (!x || !x.right) {
570
644
  return;
571
645
  }
@@ -596,11 +670,11 @@ export class RedBlackTree<
596
670
  * Space Complexity: O(1)
597
671
  *
598
672
  * The `_rightRotate` function performs a right rotation on a given node in a binary tree.
599
- * @param {NODE | undefined} y - The parameter `y` is of type `NODE | undefined`. It represents a
673
+ * @param {RedBlackTreeNode<K, V> | undefined} y - The parameter `y` is of type `RedBlackTreeNode<K, V> | undefined`. It represents a
600
674
  * node in a binary tree or `undefined` if there is no node.
601
675
  * @returns void, which means it does not return any value.
602
676
  */
603
- protected _rightRotate(y: NODE | undefined): void {
677
+ protected _rightRotate(y: RedBlackTreeNode<K, V> | undefined): void {
604
678
  if (!y || !y.left) {
605
679
  return;
606
680
  }