red-black-tree-typed 1.53.6 → 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.
- package/README.md +52 -0
- package/dist/common/index.d.ts +12 -0
- package/dist/common/index.js +28 -0
- package/dist/data-structures/base/iterable-entry-base.js +4 -4
- package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +213 -0
- package/dist/data-structures/binary-tree/avl-tree-counter.js +407 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +71 -170
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +133 -331
- package/dist/data-structures/binary-tree/avl-tree.d.ts +103 -69
- package/dist/data-structures/binary-tree/avl-tree.js +131 -71
- package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +3 -0
- package/dist/data-structures/binary-tree/binary-indexed-tree.js +3 -0
- package/dist/data-structures/binary-tree/binary-tree.d.ts +309 -208
- package/dist/data-structures/binary-tree/binary-tree.js +382 -300
- package/dist/data-structures/binary-tree/bst.d.ts +245 -127
- package/dist/data-structures/binary-tree/bst.js +366 -163
- package/dist/data-structures/binary-tree/index.d.ts +3 -1
- package/dist/data-structures/binary-tree/index.js +3 -1
- package/dist/data-structures/binary-tree/red-black-tree.d.ts +286 -0
- package/dist/data-structures/binary-tree/{rb-tree.js → red-black-tree.js} +181 -108
- package/dist/data-structures/binary-tree/tree-counter.d.ts +212 -0
- package/dist/data-structures/binary-tree/tree-counter.js +444 -0
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +78 -170
- package/dist/data-structures/binary-tree/tree-multi-map.js +145 -367
- package/dist/data-structures/graph/abstract-graph.js +2 -2
- package/dist/data-structures/graph/directed-graph.d.ts +3 -0
- package/dist/data-structures/graph/directed-graph.js +3 -0
- package/dist/data-structures/graph/map-graph.d.ts +3 -0
- package/dist/data-structures/graph/map-graph.js +3 -0
- package/dist/data-structures/graph/undirected-graph.d.ts +3 -0
- package/dist/data-structures/graph/undirected-graph.js +3 -0
- package/dist/data-structures/hash/hash-map.d.ts +31 -1
- package/dist/data-structures/hash/hash-map.js +35 -5
- package/dist/data-structures/heap/heap.d.ts +26 -9
- package/dist/data-structures/heap/heap.js +37 -17
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +64 -19
- package/dist/data-structures/linked-list/doubly-linked-list.js +92 -31
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +48 -12
- package/dist/data-structures/linked-list/singly-linked-list.js +74 -27
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +3 -0
- package/dist/data-structures/linked-list/skip-linked-list.js +3 -0
- package/dist/data-structures/matrix/matrix.d.ts +3 -0
- package/dist/data-structures/matrix/matrix.js +3 -0
- package/dist/data-structures/matrix/navigator.d.ts +3 -0
- package/dist/data-structures/matrix/navigator.js +3 -0
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +3 -0
- package/dist/data-structures/priority-queue/max-priority-queue.js +3 -0
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +3 -0
- package/dist/data-structures/priority-queue/min-priority-queue.js +3 -0
- package/dist/data-structures/queue/deque.d.ts +37 -8
- package/dist/data-structures/queue/deque.js +73 -29
- package/dist/data-structures/queue/queue.d.ts +41 -1
- package/dist/data-structures/queue/queue.js +51 -9
- package/dist/data-structures/stack/stack.d.ts +27 -10
- package/dist/data-structures/stack/stack.js +39 -20
- package/dist/data-structures/trie/trie.d.ts +111 -10
- package/dist/data-structures/trie/trie.js +123 -18
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/interfaces/binary-tree.d.ts +8 -8
- package/dist/types/data-structures/base/base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +2 -0
- package/dist/types/data-structures/binary-tree/avl-tree-counter.js +2 -0
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -4
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +0 -3
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -4
- package/dist/types/data-structures/binary-tree/bst.d.ts +6 -5
- package/dist/types/data-structures/binary-tree/index.d.ts +2 -0
- package/dist/types/data-structures/binary-tree/index.js +2 -0
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +2 -5
- package/dist/types/data-structures/binary-tree/tree-counter.d.ts +2 -0
- package/dist/types/data-structures/binary-tree/tree-counter.js +2 -0
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -5
- package/dist/types/utils/utils.d.ts +10 -6
- package/dist/utils/utils.js +4 -2
- package/package.json +2 -2
- package/src/common/index.ts +25 -0
- package/src/data-structures/base/iterable-entry-base.ts +4 -4
- package/src/data-structures/binary-tree/avl-tree-counter.ts +463 -0
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +152 -373
- package/src/data-structures/binary-tree/avl-tree.ts +164 -106
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +3 -0
- package/src/data-structures/binary-tree/binary-tree.ts +563 -447
- package/src/data-structures/binary-tree/bst.ts +433 -237
- package/src/data-structures/binary-tree/index.ts +3 -1
- package/src/data-structures/binary-tree/{rb-tree.ts → red-black-tree.ts} +224 -146
- package/src/data-structures/binary-tree/tree-counter.ts +504 -0
- package/src/data-structures/binary-tree/tree-multi-map.ts +159 -401
- package/src/data-structures/graph/abstract-graph.ts +2 -2
- package/src/data-structures/graph/directed-graph.ts +3 -0
- package/src/data-structures/graph/map-graph.ts +3 -0
- package/src/data-structures/graph/undirected-graph.ts +3 -0
- package/src/data-structures/hash/hash-map.ts +37 -7
- package/src/data-structures/heap/heap.ts +72 -49
- package/src/data-structures/linked-list/doubly-linked-list.ts +186 -118
- package/src/data-structures/linked-list/singly-linked-list.ts +81 -28
- package/src/data-structures/linked-list/skip-linked-list.ts +3 -0
- package/src/data-structures/matrix/matrix.ts +3 -0
- package/src/data-structures/matrix/navigator.ts +3 -0
- package/src/data-structures/priority-queue/max-priority-queue.ts +3 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +3 -0
- package/src/data-structures/queue/deque.ts +72 -28
- package/src/data-structures/queue/queue.ts +50 -7
- package/src/data-structures/stack/stack.ts +39 -20
- package/src/data-structures/trie/trie.ts +123 -17
- package/src/index.ts +4 -3
- package/src/interfaces/binary-tree.ts +10 -21
- package/src/types/data-structures/base/base.ts +1 -1
- package/src/types/data-structures/binary-tree/avl-tree-counter.ts +3 -0
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -6
- package/src/types/data-structures/binary-tree/avl-tree.ts +0 -5
- package/src/types/data-structures/binary-tree/binary-tree.ts +1 -6
- package/src/types/data-structures/binary-tree/bst.ts +8 -7
- package/src/types/data-structures/binary-tree/index.ts +3 -1
- package/src/types/data-structures/binary-tree/red-black-tree.ts +5 -0
- package/src/types/data-structures/binary-tree/tree-counter.ts +3 -0
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +2 -7
- package/src/types/utils/utils.ts +16 -10
- package/src/utils/utils.ts +4 -2
- package/dist/data-structures/binary-tree/rb-tree.d.ts +0 -205
- 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 './
|
|
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,76 +2,132 @@ import type {
|
|
|
2
2
|
BinaryTreeDeleteResult,
|
|
3
3
|
BTNRep,
|
|
4
4
|
CRUD,
|
|
5
|
+
EntryCallback,
|
|
5
6
|
OptNode,
|
|
7
|
+
OptNodeOrNull,
|
|
6
8
|
RBTNColor,
|
|
7
|
-
|
|
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
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
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
|
-
|
|
30
|
+
override parent?: RedBlackTreeNode<K, V> = undefined;
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
/**
|
|
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.
|
|
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']
|
|
111
|
+
*/
|
|
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>
|
|
63
115
|
{
|
|
64
116
|
/**
|
|
65
|
-
* This
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
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
|
|
73
126
|
*/
|
|
74
|
-
constructor(
|
|
127
|
+
constructor(
|
|
128
|
+
keysNodesEntriesOrRaws: Iterable<BTNRep<K, V, RedBlackTreeNode<K, V>> | R> = [],
|
|
129
|
+
options?: RedBlackTreeOptions<K, V, R>
|
|
130
|
+
) {
|
|
75
131
|
super([], options);
|
|
76
132
|
|
|
77
133
|
this._root = this.NIL;
|
|
@@ -81,17 +137,16 @@ export class RedBlackTree<
|
|
|
81
137
|
}
|
|
82
138
|
}
|
|
83
139
|
|
|
84
|
-
protected override _root:
|
|
140
|
+
protected override _root: RedBlackTreeNode<K, V> | undefined;
|
|
85
141
|
|
|
86
|
-
|
|
87
|
-
* The function returns the root node of a tree or undefined if there is no root.
|
|
88
|
-
* @returns The root node of the tree structure, or undefined if there is no root node.
|
|
89
|
-
*/
|
|
90
|
-
override get root(): NODE | undefined {
|
|
142
|
+
override get root(): RedBlackTreeNode<K, V> | undefined {
|
|
91
143
|
return this._root;
|
|
92
144
|
}
|
|
93
145
|
|
|
94
146
|
/**
|
|
147
|
+
* Time Complexity: O(1)
|
|
148
|
+
* Space Complexity: O(1)
|
|
149
|
+
*
|
|
95
150
|
* The function creates a new Red-Black Tree node with the specified key, value, and color.
|
|
96
151
|
* @param {K} key - The key parameter represents the key value of the node being created. It is of
|
|
97
152
|
* type K, which is a generic type that can be replaced with any specific type when using the
|
|
@@ -105,24 +160,27 @@ export class RedBlackTree<
|
|
|
105
160
|
* @returns A new instance of a RedBlackTreeNode with the specified key, value, and color is being
|
|
106
161
|
* returned.
|
|
107
162
|
*/
|
|
108
|
-
override createNode(key: K, value?: V, color: RBTNColor = 'BLACK'):
|
|
109
|
-
return new RedBlackTreeNode<K, V
|
|
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);
|
|
110
165
|
}
|
|
111
166
|
|
|
112
167
|
/**
|
|
168
|
+
* Time Complexity: O(1)
|
|
169
|
+
* Space Complexity: O(1)
|
|
170
|
+
*
|
|
113
171
|
* The function creates a new Red-Black Tree with the specified options.
|
|
114
172
|
* @param [options] - The `options` parameter is an optional object that contains additional
|
|
115
173
|
* configuration options for creating the Red-Black Tree. It has the following properties:
|
|
116
174
|
* @returns a new instance of a RedBlackTree object.
|
|
117
175
|
*/
|
|
118
|
-
override createTree(options?:
|
|
119
|
-
return new RedBlackTree<K, V, R,
|
|
176
|
+
override createTree(options?: RedBlackTreeOptions<K, V, R>) {
|
|
177
|
+
return new RedBlackTree<K, V, R, MK, MV, MR>([], {
|
|
120
178
|
iterationType: this.iterationType,
|
|
121
179
|
isMapMode: this._isMapMode,
|
|
122
|
-
|
|
180
|
+
specifyComparable: this._specifyComparable,
|
|
123
181
|
toEntryFn: this._toEntryFn,
|
|
124
182
|
...options
|
|
125
|
-
})
|
|
183
|
+
});
|
|
126
184
|
}
|
|
127
185
|
|
|
128
186
|
/**
|
|
@@ -130,51 +188,15 @@ export class RedBlackTree<
|
|
|
130
188
|
* Space Complexity: O(1)
|
|
131
189
|
*
|
|
132
190
|
* The function checks if the input is an instance of the RedBlackTreeNode class.
|
|
133
|
-
* @param {BTNRep<K, V,
|
|
134
|
-
* `
|
|
135
|
-
* @returns a boolean value indicating whether the input parameter `
|
|
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
|
|
136
194
|
* an instance of the `RedBlackTreeNode` class.
|
|
137
195
|
*/
|
|
138
|
-
override isNode(
|
|
139
|
-
return
|
|
196
|
+
override isNode(keyNodeOrEntry: BTNRep<K, V, RedBlackTreeNode<K, V>>): keyNodeOrEntry is RedBlackTreeNode<K, V> {
|
|
197
|
+
return keyNodeOrEntry instanceof RedBlackTreeNode;
|
|
140
198
|
}
|
|
141
199
|
|
|
142
|
-
// /**
|
|
143
|
-
// * Time Complexity: O(1)
|
|
144
|
-
// * Space Complexity: O(1)
|
|
145
|
-
// */
|
|
146
|
-
//
|
|
147
|
-
// /**
|
|
148
|
-
// * Time Complexity: O(1)
|
|
149
|
-
// * Space Complexity: O(1)
|
|
150
|
-
// *
|
|
151
|
-
// * The function `keyValueNodeEntryRawToNodeAndValue` takes a key, value, or entry and returns a node if it is
|
|
152
|
-
// * valid, otherwise it returns undefined.
|
|
153
|
-
// * @param {BTNRep<K, V, NODE>} keyNodeEntryOrRaw - The key, value, or entry to convert.
|
|
154
|
-
// * @param {V} [value] - The value associated with the key (if `keyNodeEntryOrRaw` is a key).
|
|
155
|
-
// * @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails.
|
|
156
|
-
// */
|
|
157
|
-
// override keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): NODE | undefined {
|
|
158
|
-
//
|
|
159
|
-
// if (keyNodeEntryOrRaw === null || keyNodeEntryOrRaw === undefined) return;
|
|
160
|
-
// if (this.isNode(keyNodeEntryOrRaw)) return keyNodeEntryOrRaw;
|
|
161
|
-
//
|
|
162
|
-
// if (this._toEntryFn) {
|
|
163
|
-
// const [key, entryValue] = this._toEntryFn(keyNodeEntryOrRaw as R);
|
|
164
|
-
// if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'RED');
|
|
165
|
-
// }
|
|
166
|
-
//
|
|
167
|
-
// if (this.isEntry(keyNodeEntryOrRaw)) {
|
|
168
|
-
// const [key, value] = keyNodeEntryOrRaw;
|
|
169
|
-
// if (key === undefined || key === null) return;
|
|
170
|
-
// else return this.createNode(key, value, 'RED');
|
|
171
|
-
// }
|
|
172
|
-
//
|
|
173
|
-
// if (this.isKey(keyNodeEntryOrRaw)) return this.createNode(keyNodeEntryOrRaw, value, 'RED');
|
|
174
|
-
//
|
|
175
|
-
// return ;
|
|
176
|
-
// }
|
|
177
|
-
|
|
178
200
|
/**
|
|
179
201
|
* Time Complexity: O(1)
|
|
180
202
|
* Space Complexity: O(1)
|
|
@@ -189,12 +211,12 @@ export class RedBlackTree<
|
|
|
189
211
|
|
|
190
212
|
/**
|
|
191
213
|
* Time Complexity: O(log n)
|
|
192
|
-
* Space Complexity: O(
|
|
214
|
+
* Space Complexity: O(log n)
|
|
193
215
|
*
|
|
194
216
|
* The function adds a new node to a binary search tree and returns true if the node was successfully
|
|
195
217
|
* added.
|
|
196
|
-
* @param {BTNRep<K, V,
|
|
197
|
-
* `
|
|
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>>`.
|
|
198
220
|
* @param {V} [value] - The `value` parameter is an optional value that you want to associate with
|
|
199
221
|
* the key in the data structure. It represents the value that you want to add or update in the data
|
|
200
222
|
* structure.
|
|
@@ -202,8 +224,8 @@ export class RedBlackTree<
|
|
|
202
224
|
* the method returns true. If the node already exists and its value is updated, the method also
|
|
203
225
|
* returns true. If the node cannot be added or updated, the method returns false.
|
|
204
226
|
*/
|
|
205
|
-
override add(
|
|
206
|
-
const [newNode, newValue] = this.
|
|
227
|
+
override add(keyNodeOrEntry: BTNRep<K, V, RedBlackTreeNode<K, V>>, value?: V): boolean {
|
|
228
|
+
const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
207
229
|
if (!this.isRealNode(newNode)) return false;
|
|
208
230
|
|
|
209
231
|
const insertStatus = this._insert(newNode);
|
|
@@ -228,36 +250,40 @@ export class RedBlackTree<
|
|
|
228
250
|
|
|
229
251
|
/**
|
|
230
252
|
* Time Complexity: O(log n)
|
|
231
|
-
* Space Complexity: O(
|
|
253
|
+
* Space Complexity: O(log n)
|
|
232
254
|
*
|
|
233
255
|
* The function overrides the delete method in a binary tree data structure to remove a node based on
|
|
234
256
|
* a given predicate and maintain the binary search tree properties.
|
|
235
|
-
* @param {BTNRep<K, V,
|
|
257
|
+
* @param {BTNRep<K, V, RedBlackTreeNode<K, V>>} keyNodeOrEntry - The `keyNodeOrEntry`
|
|
236
258
|
* parameter in the `override delete` method is used to specify the condition or key based on which a
|
|
237
259
|
* node should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate
|
|
238
260
|
* function that determines which node(s) should be deleted.
|
|
239
|
-
* @returns The `override delete` method is returning an array of `BinaryTreeDeleteResult<
|
|
261
|
+
* @returns The `override delete` method is returning an array of `BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>`
|
|
240
262
|
* objects. Each object in the array contains information about the deleted node and whether
|
|
241
263
|
* balancing is needed.
|
|
242
264
|
*/
|
|
243
|
-
override delete(
|
|
244
|
-
|
|
265
|
+
override delete(
|
|
266
|
+
keyNodeOrEntry: BTNRep<K, V, RedBlackTreeNode<K, V>>
|
|
267
|
+
): BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>[] {
|
|
268
|
+
if (keyNodeOrEntry === null) return [];
|
|
245
269
|
|
|
246
|
-
const results: BinaryTreeDeleteResult<
|
|
247
|
-
let nodeToDelete: OptNode<
|
|
248
|
-
if (this._isPredicate(
|
|
249
|
-
else nodeToDelete = this.isRealNode(
|
|
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);
|
|
250
274
|
|
|
251
275
|
if (!nodeToDelete) {
|
|
252
276
|
return results;
|
|
253
277
|
}
|
|
254
278
|
|
|
255
279
|
let originalColor = nodeToDelete.color;
|
|
256
|
-
let replacementNode:
|
|
280
|
+
let replacementNode: RedBlackTreeNode<K, V> | undefined;
|
|
257
281
|
|
|
258
282
|
if (!this.isRealNode(nodeToDelete.left)) {
|
|
259
|
-
|
|
260
|
-
|
|
283
|
+
if (nodeToDelete.right !== null) {
|
|
284
|
+
replacementNode = nodeToDelete.right;
|
|
285
|
+
this._transplant(nodeToDelete, nodeToDelete.right);
|
|
286
|
+
}
|
|
261
287
|
} else if (!this.isRealNode(nodeToDelete.right)) {
|
|
262
288
|
replacementNode = nodeToDelete.left;
|
|
263
289
|
this._transplant(nodeToDelete, nodeToDelete.left);
|
|
@@ -265,15 +291,17 @@ export class RedBlackTree<
|
|
|
265
291
|
const successor = this.getLeftMost(node => node, nodeToDelete.right);
|
|
266
292
|
if (successor) {
|
|
267
293
|
originalColor = successor.color;
|
|
268
|
-
replacementNode = successor.right;
|
|
294
|
+
if (successor.right !== null) replacementNode = successor.right;
|
|
269
295
|
|
|
270
296
|
if (successor.parent === nodeToDelete) {
|
|
271
297
|
if (this.isRealNode(replacementNode)) {
|
|
272
298
|
replacementNode.parent = successor;
|
|
273
299
|
}
|
|
274
300
|
} else {
|
|
275
|
-
|
|
276
|
-
|
|
301
|
+
if (successor.right !== null) {
|
|
302
|
+
this._transplant(successor, successor.right);
|
|
303
|
+
successor.right = nodeToDelete.right;
|
|
304
|
+
}
|
|
277
305
|
if (this.isRealNode(successor.right)) {
|
|
278
306
|
successor.right.parent = successor;
|
|
279
307
|
}
|
|
@@ -300,15 +328,62 @@ export class RedBlackTree<
|
|
|
300
328
|
return results;
|
|
301
329
|
}
|
|
302
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
|
+
|
|
303
378
|
/**
|
|
304
379
|
* Time Complexity: O(1)
|
|
305
380
|
* Space Complexity: O(1)
|
|
306
381
|
*
|
|
307
382
|
* The function sets the root of a tree-like structure and updates the parent property of the new
|
|
308
383
|
* root.
|
|
309
|
-
* @param {
|
|
384
|
+
* @param {RedBlackTreeNode<K, V> | undefined} v - v is a parameter of type RedBlackTreeNode<K, V> or undefined.
|
|
310
385
|
*/
|
|
311
|
-
protected override _setRoot(v:
|
|
386
|
+
protected override _setRoot(v: RedBlackTreeNode<K, V> | undefined) {
|
|
312
387
|
if (v) {
|
|
313
388
|
v.parent = undefined;
|
|
314
389
|
}
|
|
@@ -320,14 +395,17 @@ export class RedBlackTree<
|
|
|
320
395
|
* Space Complexity: O(1)
|
|
321
396
|
*
|
|
322
397
|
* The function replaces an old node with a new node while preserving the color of the old node.
|
|
323
|
-
* @param {
|
|
398
|
+
* @param {RedBlackTreeNode<K, V>} oldNode - The `oldNode` parameter represents the node that needs to be replaced in
|
|
324
399
|
* the data structure.
|
|
325
|
-
* @param {
|
|
400
|
+
* @param {RedBlackTreeNode<K, V>} newNode - The `newNode` parameter is of type `RedBlackTreeNode<K, V>`, which represents a node in a
|
|
326
401
|
* data structure.
|
|
327
402
|
* @returns The method is returning the result of calling the `_replaceNode` method from the
|
|
328
403
|
* superclass, with the `oldNode` and `newNode` parameters.
|
|
329
404
|
*/
|
|
330
|
-
protected override _replaceNode(
|
|
405
|
+
protected override _replaceNode(
|
|
406
|
+
oldNode: RedBlackTreeNode<K, V>,
|
|
407
|
+
newNode: RedBlackTreeNode<K, V>
|
|
408
|
+
): RedBlackTreeNode<K, V> {
|
|
331
409
|
newNode.color = oldNode.color;
|
|
332
410
|
|
|
333
411
|
return super._replaceNode(oldNode, newNode);
|
|
@@ -335,23 +413,23 @@ export class RedBlackTree<
|
|
|
335
413
|
|
|
336
414
|
/**
|
|
337
415
|
* Time Complexity: O(log n)
|
|
338
|
-
* Space Complexity: O(
|
|
416
|
+
* Space Complexity: O(log n)
|
|
339
417
|
*
|
|
340
418
|
* The `_insert` function inserts a node into a binary search tree and performs necessary fix-ups to
|
|
341
419
|
* maintain the red-black tree properties.
|
|
342
|
-
* @param {
|
|
420
|
+
* @param {RedBlackTreeNode<K, V>} node - The `node` parameter represents the node that needs to be inserted into the
|
|
343
421
|
* binary search tree.
|
|
344
422
|
* @returns a string value indicating the result of the insertion operation. It can return either
|
|
345
423
|
* 'UPDATED' if the node with the same key already exists and was updated, or 'CREATED' if a new node
|
|
346
424
|
* was created and inserted into the tree.
|
|
347
425
|
*/
|
|
348
|
-
protected _insert(node:
|
|
426
|
+
protected _insert(node: RedBlackTreeNode<K, V>): CRUD {
|
|
349
427
|
let current = this.root;
|
|
350
|
-
let parent:
|
|
428
|
+
let parent: RedBlackTreeNode<K, V> | undefined = undefined;
|
|
351
429
|
|
|
352
430
|
while (this.isRealNode(current)) {
|
|
353
431
|
parent = current;
|
|
354
|
-
const compared = this.
|
|
432
|
+
const compared = this._compare(node.key, current.key);
|
|
355
433
|
if (compared < 0) {
|
|
356
434
|
current = current.left ?? this.NIL;
|
|
357
435
|
} else if (compared > 0) {
|
|
@@ -366,7 +444,7 @@ export class RedBlackTree<
|
|
|
366
444
|
|
|
367
445
|
if (!parent) {
|
|
368
446
|
this._setRoot(node);
|
|
369
|
-
} else if (node.key
|
|
447
|
+
} else if (this._compare(node.key, parent.key) < 0) {
|
|
370
448
|
parent.left = node;
|
|
371
449
|
} else {
|
|
372
450
|
parent.right = node;
|
|
@@ -385,11 +463,11 @@ export class RedBlackTree<
|
|
|
385
463
|
* Space Complexity: O(1)
|
|
386
464
|
*
|
|
387
465
|
* The function `_transplant` is used to replace a node `u` with another node `v` in a binary tree.
|
|
388
|
-
* @param {
|
|
389
|
-
* @param {
|
|
390
|
-
* either be a `
|
|
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`.
|
|
391
469
|
*/
|
|
392
|
-
protected _transplant(u:
|
|
470
|
+
protected _transplant(u: RedBlackTreeNode<K, V>, v: RedBlackTreeNode<K, V> | undefined): void {
|
|
393
471
|
if (!u.parent) {
|
|
394
472
|
this._setRoot(v);
|
|
395
473
|
} else if (u === u.parent.left) {
|
|
@@ -408,10 +486,10 @@ export class RedBlackTree<
|
|
|
408
486
|
* Space Complexity: O(1)
|
|
409
487
|
*
|
|
410
488
|
* The `_insertFixup` function is used to fix the Red-Black Tree after inserting a new node.
|
|
411
|
-
* @param {
|
|
489
|
+
* @param {RedBlackTreeNode<K, V> | undefined} z - The parameter `z` represents a node in the Red-Black Tree data
|
|
412
490
|
* structure. It can either be a valid node or `undefined`.
|
|
413
491
|
*/
|
|
414
|
-
protected _insertFixup(z:
|
|
492
|
+
protected _insertFixup(z: RedBlackTreeNode<K, V> | undefined): void {
|
|
415
493
|
// Continue fixing the tree as long as the parent of z is red
|
|
416
494
|
while (z?.parent?.color === 'RED') {
|
|
417
495
|
// Check if the parent of z is the left child of its parent
|
|
@@ -444,7 +522,7 @@ export class RedBlackTree<
|
|
|
444
522
|
} else {
|
|
445
523
|
// Symmetric case for the right child (left and right exchanged)
|
|
446
524
|
// Follow the same logic as above with left and right exchanged
|
|
447
|
-
const y:
|
|
525
|
+
const y: RedBlackTreeNode<K, V> | undefined = z?.parent?.parent?.left ?? undefined;
|
|
448
526
|
if (y?.color === 'RED') {
|
|
449
527
|
z.parent.color = 'BLACK';
|
|
450
528
|
y.color = 'BLACK';
|
|
@@ -475,12 +553,12 @@ export class RedBlackTree<
|
|
|
475
553
|
*
|
|
476
554
|
* The `_deleteFixup` function is used to fix the red-black tree after a node deletion by adjusting
|
|
477
555
|
* the colors and performing rotations.
|
|
478
|
-
* @param {
|
|
556
|
+
* @param {RedBlackTreeNode<K, V> | undefined} node - The `node` parameter represents a node in a binary tree. It can
|
|
479
557
|
* be either a valid node object or `undefined`.
|
|
480
558
|
* @returns The function does not return any value. It has a return type of `void`, which means it
|
|
481
559
|
* does not return anything.
|
|
482
560
|
*/
|
|
483
|
-
protected _deleteFixup(node:
|
|
561
|
+
protected _deleteFixup(node: RedBlackTreeNode<K, V> | undefined): void {
|
|
484
562
|
// Early exit condition
|
|
485
563
|
if (!node || node === this.root || node.color === 'BLACK') {
|
|
486
564
|
if (node) {
|
|
@@ -490,7 +568,7 @@ export class RedBlackTree<
|
|
|
490
568
|
}
|
|
491
569
|
|
|
492
570
|
while (node && node !== this.root && node.color === 'BLACK') {
|
|
493
|
-
const parent:
|
|
571
|
+
const parent: RedBlackTreeNode<K, V> | undefined = node.parent;
|
|
494
572
|
|
|
495
573
|
if (!parent) {
|
|
496
574
|
break; // Ensure the loop terminates if there's an issue with the tree structure
|
|
@@ -557,11 +635,11 @@ export class RedBlackTree<
|
|
|
557
635
|
* Space Complexity: O(1)
|
|
558
636
|
*
|
|
559
637
|
* The `_leftRotate` function performs a left rotation on a given node in a binary tree.
|
|
560
|
-
* @param {
|
|
638
|
+
* @param {RedBlackTreeNode<K, V> | undefined} x - The parameter `x` is of type `RedBlackTreeNode<K, V> | undefined`. It represents a
|
|
561
639
|
* node in a binary tree or `undefined` if there is no node.
|
|
562
640
|
* @returns void, which means it does not return any value.
|
|
563
641
|
*/
|
|
564
|
-
protected _leftRotate(x:
|
|
642
|
+
protected _leftRotate(x: RedBlackTreeNode<K, V> | undefined): void {
|
|
565
643
|
if (!x || !x.right) {
|
|
566
644
|
return;
|
|
567
645
|
}
|
|
@@ -592,11 +670,11 @@ export class RedBlackTree<
|
|
|
592
670
|
* Space Complexity: O(1)
|
|
593
671
|
*
|
|
594
672
|
* The `_rightRotate` function performs a right rotation on a given node in a binary tree.
|
|
595
|
-
* @param {
|
|
673
|
+
* @param {RedBlackTreeNode<K, V> | undefined} y - The parameter `y` is of type `RedBlackTreeNode<K, V> | undefined`. It represents a
|
|
596
674
|
* node in a binary tree or `undefined` if there is no node.
|
|
597
675
|
* @returns void, which means it does not return any value.
|
|
598
676
|
*/
|
|
599
|
-
protected _rightRotate(y:
|
|
677
|
+
protected _rightRotate(y: RedBlackTreeNode<K, V> | undefined): void {
|
|
600
678
|
if (!y || !y.left) {
|
|
601
679
|
return;
|
|
602
680
|
}
|