deque-typed 1.48.1 → 1.48.3
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/dist/data-structures/base/index.d.ts +1 -0
- package/dist/data-structures/base/index.js +17 -0
- package/dist/data-structures/base/iterable-base.d.ts +232 -0
- package/dist/data-structures/base/iterable-base.js +312 -0
- package/dist/data-structures/binary-tree/avl-tree.d.ts +16 -16
- package/dist/data-structures/binary-tree/avl-tree.js +7 -7
- package/dist/data-structures/binary-tree/binary-tree.d.ts +121 -152
- package/dist/data-structures/binary-tree/binary-tree.js +140 -182
- package/dist/data-structures/binary-tree/bst.d.ts +28 -47
- package/dist/data-structures/binary-tree/bst.js +54 -57
- package/dist/data-structures/binary-tree/rb-tree.d.ts +15 -15
- package/dist/data-structures/binary-tree/rb-tree.js +7 -7
- package/dist/data-structures/binary-tree/tree-multimap.d.ts +22 -22
- package/dist/data-structures/binary-tree/tree-multimap.js +11 -11
- package/dist/data-structures/graph/abstract-graph.d.ts +44 -6
- package/dist/data-structures/graph/abstract-graph.js +50 -27
- package/dist/data-structures/hash/hash-map.d.ts +59 -100
- package/dist/data-structures/hash/hash-map.js +69 -173
- package/dist/data-structures/heap/heap.d.ts +50 -7
- package/dist/data-structures/heap/heap.js +60 -30
- package/dist/data-structures/index.d.ts +1 -0
- package/dist/data-structures/index.js +1 -0
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +38 -51
- package/dist/data-structures/linked-list/doubly-linked-list.js +46 -73
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +32 -51
- package/dist/data-structures/linked-list/singly-linked-list.js +40 -73
- package/dist/data-structures/queue/deque.d.ts +29 -51
- package/dist/data-structures/queue/deque.js +36 -71
- package/dist/data-structures/queue/queue.d.ts +49 -48
- package/dist/data-structures/queue/queue.js +69 -82
- package/dist/data-structures/stack/stack.d.ts +43 -10
- package/dist/data-structures/stack/stack.js +50 -31
- package/dist/data-structures/trie/trie.d.ts +41 -6
- package/dist/data-structures/trie/trie.js +53 -32
- package/dist/interfaces/binary-tree.d.ts +6 -6
- package/dist/types/common.d.ts +11 -8
- package/dist/types/common.js +6 -1
- package/dist/types/data-structures/base/base.d.ts +5 -0
- package/dist/types/data-structures/base/base.js +2 -0
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/index.js +17 -0
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +4 -4
- package/dist/types/data-structures/binary-tree/bst.d.ts +6 -6
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/tree-multimap.d.ts +3 -3
- package/dist/types/data-structures/index.d.ts +1 -0
- package/dist/types/data-structures/index.js +1 -0
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-base.ts +329 -0
- package/src/data-structures/binary-tree/avl-tree.ts +20 -21
- package/src/data-structures/binary-tree/binary-tree.ts +222 -267
- package/src/data-structures/binary-tree/bst.ts +86 -82
- package/src/data-structures/binary-tree/rb-tree.ts +25 -26
- package/src/data-structures/binary-tree/tree-multimap.ts +30 -35
- package/src/data-structures/graph/abstract-graph.ts +55 -28
- package/src/data-structures/hash/hash-map.ts +76 -185
- package/src/data-structures/heap/heap.ts +63 -36
- package/src/data-structures/index.ts +1 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +50 -79
- package/src/data-structures/linked-list/singly-linked-list.ts +45 -80
- package/src/data-structures/queue/deque.ts +40 -82
- package/src/data-structures/queue/queue.ts +72 -87
- package/src/data-structures/stack/stack.ts +53 -34
- package/src/data-structures/trie/trie.ts +58 -35
- package/src/interfaces/binary-tree.ts +5 -6
- package/src/types/common.ts +11 -8
- package/src/types/data-structures/base/base.ts +6 -0
- package/src/types/data-structures/base/index.ts +1 -0
- package/src/types/data-structures/binary-tree/avl-tree.ts +3 -3
- package/src/types/data-structures/binary-tree/binary-tree.ts +6 -5
- package/src/types/data-structures/binary-tree/bst.ts +6 -6
- package/src/types/data-structures/binary-tree/rb-tree.ts +3 -3
- package/src/types/data-structures/binary-tree/tree-multimap.ts +3 -3
- package/src/types/data-structures/index.ts +1 -0
|
@@ -11,20 +11,18 @@ import type {
|
|
|
11
11
|
BSTNodeNested,
|
|
12
12
|
BSTOptions,
|
|
13
13
|
BTNCallback,
|
|
14
|
-
BTNKey,
|
|
15
14
|
BTNodeExemplar,
|
|
16
|
-
BTNodePureExemplar
|
|
17
|
-
Comparator
|
|
15
|
+
BTNodePureExemplar
|
|
18
16
|
} from '../../types';
|
|
19
|
-
import { CP, IterationType } from '../../types';
|
|
17
|
+
import { BSTVariant, CP, IterationType } from '../../types';
|
|
20
18
|
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
21
19
|
import { IBinaryTree } from '../../interfaces';
|
|
22
20
|
import { Queue } from '../queue';
|
|
23
21
|
|
|
24
|
-
export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
|
|
22
|
+
export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<K, V, N> {
|
|
25
23
|
override parent?: N;
|
|
26
24
|
|
|
27
|
-
constructor(key:
|
|
25
|
+
constructor(key: K, value?: V) {
|
|
28
26
|
super(key, value);
|
|
29
27
|
this.parent = undefined;
|
|
30
28
|
this._left = undefined;
|
|
@@ -81,9 +79,9 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
|
|
|
81
79
|
* 6. Balance Variability: Can become unbalanced; special types maintain balance.
|
|
82
80
|
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
|
|
83
81
|
*/
|
|
84
|
-
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>, TREE extends BST<V, N, TREE> = BST<V, N, BSTNested<V, N>>>
|
|
85
|
-
extends BinaryTree<V, N, TREE>
|
|
86
|
-
implements IBinaryTree<V, N, TREE> {
|
|
82
|
+
export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BSTNodeNested<K, V>>, TREE extends BST<K, V, N, TREE> = BST<K, V, N, BSTNested<K, V, N>>>
|
|
83
|
+
extends BinaryTree<K, V, N, TREE>
|
|
84
|
+
implements IBinaryTree<K, V, N, TREE> {
|
|
87
85
|
|
|
88
86
|
|
|
89
87
|
/**
|
|
@@ -94,13 +92,13 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
94
92
|
* @param [options] - The `options` parameter is an optional object that can contain additional
|
|
95
93
|
* configuration options for the binary search tree. It can have the following properties:
|
|
96
94
|
*/
|
|
97
|
-
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<BSTOptions
|
|
95
|
+
constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<BSTOptions<K>>) {
|
|
98
96
|
super([], options);
|
|
99
97
|
|
|
100
98
|
if (options) {
|
|
101
|
-
const {
|
|
102
|
-
if (
|
|
103
|
-
this.
|
|
99
|
+
const { variant } = options;
|
|
100
|
+
if (variant) {
|
|
101
|
+
this._variant = variant;
|
|
104
102
|
}
|
|
105
103
|
}
|
|
106
104
|
|
|
@@ -115,18 +113,22 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
115
113
|
return this._root;
|
|
116
114
|
}
|
|
117
115
|
|
|
118
|
-
|
|
116
|
+
protected _variant = BSTVariant.MIN
|
|
117
|
+
|
|
118
|
+
get variant() {
|
|
119
|
+
return this._variant;
|
|
120
|
+
}
|
|
119
121
|
|
|
120
122
|
/**
|
|
121
123
|
* The function creates a new binary search tree node with the given key and value.
|
|
122
|
-
* @param {
|
|
124
|
+
* @param {K} key - The key parameter is the key value that will be associated with
|
|
123
125
|
* the new node. It is used to determine the position of the node in the binary search tree.
|
|
124
126
|
* @param [value] - The parameter `value` is an optional value that can be assigned to the node. It
|
|
125
127
|
* represents the value associated with the node in a binary search tree.
|
|
126
128
|
* @returns a new instance of the BSTNode class with the specified key and value.
|
|
127
129
|
*/
|
|
128
|
-
override createNode(key:
|
|
129
|
-
return new BSTNode<V, N>(key, value) as N;
|
|
130
|
+
override createNode(key: K, value?: V): N {
|
|
131
|
+
return new BSTNode<K, V, N>(key, value) as N;
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
/**
|
|
@@ -136,29 +138,29 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
136
138
|
* that defines various options for creating a binary search tree.
|
|
137
139
|
* @returns a new instance of the BST class with the specified options.
|
|
138
140
|
*/
|
|
139
|
-
override createTree(options?: Partial<BSTOptions
|
|
140
|
-
return new BST<V, N, TREE>([], {
|
|
141
|
+
override createTree(options?: Partial<BSTOptions<K>>): TREE {
|
|
142
|
+
return new BST<K, V, N, TREE>([], {
|
|
141
143
|
iterationType: this.iterationType,
|
|
142
|
-
|
|
144
|
+
variant: this.variant, ...options
|
|
143
145
|
}) as TREE;
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
/**
|
|
147
149
|
* The function checks if an exemplar is an instance of BSTNode.
|
|
148
|
-
* @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<V, N>`.
|
|
150
|
+
* @param exemplar - The `exemplar` parameter is a variable of type `BTNodeExemplar<K, V, N>`.
|
|
149
151
|
* @returns a boolean value indicating whether the exemplar is an instance of the BSTNode class.
|
|
150
152
|
*/
|
|
151
|
-
override isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
|
|
153
|
+
override isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
|
|
152
154
|
return exemplar instanceof BSTNode;
|
|
153
155
|
}
|
|
154
156
|
|
|
155
157
|
/**
|
|
156
158
|
* The function `exemplarToNode` takes an exemplar and returns a corresponding node if the exemplar
|
|
157
159
|
* is valid, otherwise it returns undefined.
|
|
158
|
-
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`.
|
|
160
|
+
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`.
|
|
159
161
|
* @returns a variable `node` which is of type `N` or `undefined`.
|
|
160
162
|
*/
|
|
161
|
-
override exemplarToNode(exemplar: BTNodeExemplar<V, N>): N | undefined {
|
|
163
|
+
override exemplarToNode(exemplar: BTNodeExemplar<K, V, N>): N | undefined {
|
|
162
164
|
let node: N | undefined;
|
|
163
165
|
if (exemplar === null || exemplar === undefined) {
|
|
164
166
|
return;
|
|
@@ -171,7 +173,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
171
173
|
} else {
|
|
172
174
|
node = this.createNode(key, value);
|
|
173
175
|
}
|
|
174
|
-
} else if (this.
|
|
176
|
+
} else if (this.isNotNodeInstance(exemplar)) {
|
|
175
177
|
node = this.createNode(exemplar);
|
|
176
178
|
} else {
|
|
177
179
|
return;
|
|
@@ -194,7 +196,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
194
196
|
* @returns The method returns either the newly added node (`newNode`) or `undefined` if the input
|
|
195
197
|
* (`keyOrNodeOrEntry`) is null, undefined, or does not match any of the expected types.
|
|
196
198
|
*/
|
|
197
|
-
override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | undefined {
|
|
199
|
+
override add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>): N | undefined {
|
|
198
200
|
const newNode = this.exemplarToNode(keyOrNodeOrEntry);
|
|
199
201
|
if (newNode === undefined) return;
|
|
200
202
|
|
|
@@ -262,7 +264,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
262
264
|
* @returns The `addMany` function returns an array of `N` or `undefined` values.
|
|
263
265
|
*/
|
|
264
266
|
override addMany(
|
|
265
|
-
keysOrNodesOrEntries: Iterable<BTNodeExemplar<V, N>>,
|
|
267
|
+
keysOrNodesOrEntries: Iterable<BTNodeExemplar<K, V, N>>,
|
|
266
268
|
isBalanceAdd = true,
|
|
267
269
|
iterationType = this.iterationType
|
|
268
270
|
): (N | undefined)[] {
|
|
@@ -274,9 +276,9 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
274
276
|
}
|
|
275
277
|
return inserted;
|
|
276
278
|
}
|
|
277
|
-
const realBTNExemplars: BTNodePureExemplar<V, N>[] = [];
|
|
279
|
+
const realBTNExemplars: BTNodePureExemplar<K, V, N>[] = [];
|
|
278
280
|
|
|
279
|
-
const isRealBTNExemplar = (kve: BTNodeExemplar<V, N>): kve is BTNodePureExemplar<V, N> => {
|
|
281
|
+
const isRealBTNExemplar = (kve: BTNodeExemplar<K, V, N>): kve is BTNodePureExemplar<K, V, N> => {
|
|
280
282
|
if (kve === undefined || kve === null) return false;
|
|
281
283
|
return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
|
|
282
284
|
}
|
|
@@ -286,23 +288,23 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
286
288
|
}
|
|
287
289
|
|
|
288
290
|
// TODO this addMany function is inefficient, it should be optimized
|
|
289
|
-
let sorted: BTNodePureExemplar<V, N>[] = [];
|
|
291
|
+
let sorted: BTNodePureExemplar<K, V, N>[] = [];
|
|
290
292
|
|
|
291
293
|
sorted = realBTNExemplars.sort((a, b) => {
|
|
292
294
|
let aR: number, bR: number;
|
|
293
|
-
if (this.isEntry(a)) aR = a[0]
|
|
294
|
-
else if (this.isRealNode(a)) aR = a.key
|
|
295
|
-
else aR = a;
|
|
295
|
+
if (this.isEntry(a)) aR = this.extractor(a[0])
|
|
296
|
+
else if (this.isRealNode(a)) aR = this.extractor(a.key)
|
|
297
|
+
else aR = this.extractor(a);
|
|
296
298
|
|
|
297
|
-
if (this.isEntry(b)) bR = b[0]
|
|
298
|
-
else if (this.isRealNode(b)) bR = b.key
|
|
299
|
-
else bR = b;
|
|
299
|
+
if (this.isEntry(b)) bR = this.extractor(b[0])
|
|
300
|
+
else if (this.isRealNode(b)) bR = this.extractor(b.key)
|
|
301
|
+
else bR = this.extractor(b);
|
|
300
302
|
|
|
301
303
|
return aR - bR;
|
|
302
304
|
})
|
|
303
305
|
|
|
304
306
|
|
|
305
|
-
const _dfs = (arr: BTNodePureExemplar<V, N>[]) => {
|
|
307
|
+
const _dfs = (arr: BTNodePureExemplar<K, V, N>[]) => {
|
|
306
308
|
if (arr.length === 0) return;
|
|
307
309
|
|
|
308
310
|
const mid = Math.floor((arr.length - 1) / 2);
|
|
@@ -337,31 +339,31 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
337
339
|
return inserted;
|
|
338
340
|
}
|
|
339
341
|
|
|
340
|
-
/**
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
lastKey(beginRoot: BSTNodeKeyOrNode<N> = this.root, iterationType = this.iterationType):
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
}
|
|
342
|
+
// /**
|
|
343
|
+
// * Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
|
|
344
|
+
// * Space Complexity: O(n) - Additional space is required for the sorted array.
|
|
345
|
+
// */
|
|
346
|
+
//
|
|
347
|
+
// /**
|
|
348
|
+
// * Time Complexity: O(log n) - Average case for a balanced tree.
|
|
349
|
+
// * Space Complexity: O(1) - Constant space is used.
|
|
350
|
+
// *
|
|
351
|
+
// * The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the
|
|
352
|
+
// * leftmost node if the comparison result is greater than.
|
|
353
|
+
// * @param {K | N | undefined} beginRoot - The `beginRoot` parameter is optional and can be of
|
|
354
|
+
// * type `K`, `N`, or `undefined`. It represents the starting point for finding the last key in
|
|
355
|
+
// * the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).
|
|
356
|
+
// * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
|
|
357
|
+
// * be performed. It can have one of the following values:
|
|
358
|
+
// * @returns the key of the rightmost node in the binary tree if the comparison result is less than,
|
|
359
|
+
// * the key of the leftmost node if the comparison result is greater than, and the key of the
|
|
360
|
+
// * rightmost node otherwise. If no node is found, it returns 0.
|
|
361
|
+
// */
|
|
362
|
+
// lastKey(beginRoot: BSTNodeKeyOrNode<K,N> = this.root, iterationType = this.iterationType): K {
|
|
363
|
+
// if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
|
|
364
|
+
// else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
|
|
365
|
+
// else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
|
|
366
|
+
// }
|
|
365
367
|
|
|
366
368
|
/**
|
|
367
369
|
* Time Complexity: O(log n) - Average case for a balanced tree.
|
|
@@ -374,7 +376,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
374
376
|
*
|
|
375
377
|
* The function `getNodeByKey` searches for a node in a binary tree based on a given key, using
|
|
376
378
|
* either recursive or iterative methods.
|
|
377
|
-
* @param {
|
|
379
|
+
* @param {K} key - The `key` parameter is the key value that we are searching for in the tree.
|
|
378
380
|
* It is used to identify the node that we want to retrieve.
|
|
379
381
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
380
382
|
* type of iteration to use when searching for a node in the binary tree. It can have two possible
|
|
@@ -382,7 +384,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
382
384
|
* @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is
|
|
383
385
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
384
386
|
*/
|
|
385
|
-
override getNodeByKey(key:
|
|
387
|
+
override getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): N | undefined {
|
|
386
388
|
if (!this.root) return undefined;
|
|
387
389
|
if (iterationType === IterationType.RECURSIVE) {
|
|
388
390
|
const _dfs = (cur: N): N | undefined => {
|
|
@@ -415,14 +417,14 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
415
417
|
/**
|
|
416
418
|
* The function `ensureNode` returns the node corresponding to the given key if it is a node key,
|
|
417
419
|
* otherwise it returns the key itself.
|
|
418
|
-
* @param {
|
|
420
|
+
* @param {K | N | undefined} key - The `key` parameter can be of type `K`, `N`, or
|
|
419
421
|
* `undefined`.
|
|
420
422
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
421
423
|
* type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
|
|
422
424
|
* @returns either a node object (N) or undefined.
|
|
423
425
|
*/
|
|
424
|
-
override ensureNode(key: BSTNodeKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | undefined {
|
|
425
|
-
return this.
|
|
426
|
+
override ensureNode(key: BSTNodeKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | undefined {
|
|
427
|
+
return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;
|
|
426
428
|
}
|
|
427
429
|
|
|
428
430
|
/**
|
|
@@ -441,7 +443,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
441
443
|
* first node that matches the identifier. If set to true, the function will return an array
|
|
442
444
|
* containing only the first matching node. If set to false (default), the function will continue
|
|
443
445
|
* searching for all nodes that match the identifier and return an array containing
|
|
444
|
-
* @param {
|
|
446
|
+
* @param {K | N | undefined} beginRoot - The `beginRoot` parameter represents the starting node
|
|
445
447
|
* for the traversal. It can be either a key value or a node object. If it is undefined, the
|
|
446
448
|
* traversal will start from the root of the tree.
|
|
447
449
|
* @param iterationType - The `iterationType` parameter determines the type of iteration to be
|
|
@@ -452,7 +454,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
452
454
|
identifier: ReturnType<C> | undefined,
|
|
453
455
|
callback: C = this._defaultOneParamCallback as C,
|
|
454
456
|
onlyOne = false,
|
|
455
|
-
beginRoot: BSTNodeKeyOrNode<N> = this.root,
|
|
457
|
+
beginRoot: BSTNodeKeyOrNode<K, N> = this.root,
|
|
456
458
|
iterationType = this.iterationType
|
|
457
459
|
): N[] {
|
|
458
460
|
beginRoot = this.ensureNode(beginRoot);
|
|
@@ -470,8 +472,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
470
472
|
if (!cur.left && !cur.right) return;
|
|
471
473
|
// TODO potential bug
|
|
472
474
|
if (callback === this._defaultOneParamCallback) {
|
|
473
|
-
if (this._compare(cur.key, identifier as
|
|
474
|
-
if (this._compare(cur.key, identifier as
|
|
475
|
+
if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && _traverse(cur.left);
|
|
476
|
+
if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && _traverse(cur.right);
|
|
475
477
|
} else {
|
|
476
478
|
cur.left && _traverse(cur.left);
|
|
477
479
|
cur.right && _traverse(cur.right);
|
|
@@ -491,8 +493,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
491
493
|
}
|
|
492
494
|
// TODO potential bug
|
|
493
495
|
if (callback === this._defaultOneParamCallback) {
|
|
494
|
-
if (this._compare(cur.key, identifier as
|
|
495
|
-
if (this._compare(cur.key, identifier as
|
|
496
|
+
if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && queue.push(cur.left);
|
|
497
|
+
if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && queue.push(cur.right);
|
|
496
498
|
} else {
|
|
497
499
|
cur.left && queue.push(cur.left);
|
|
498
500
|
cur.right && queue.push(cur.right);
|
|
@@ -522,7 +524,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
522
524
|
* traverse nodes that are lesser than, greater than, or equal to the `targetNode`. It is of type
|
|
523
525
|
* `CP`, which is a custom type representing the comparison operator. The possible values for
|
|
524
526
|
* `lesserOrGreater` are
|
|
525
|
-
* @param {
|
|
527
|
+
* @param {K | N | undefined} targetNode - The `targetNode` parameter represents the node in the
|
|
526
528
|
* binary tree that you want to traverse from. It can be specified either by its key, by the node
|
|
527
529
|
* object itself, or it can be left undefined to start the traversal from the root of the tree.
|
|
528
530
|
* @param iterationType - The `iterationType` parameter determines the type of traversal to be
|
|
@@ -533,7 +535,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
533
535
|
lesserOrGreaterTraverse<C extends BTNCallback<N>>(
|
|
534
536
|
callback: C = this._defaultOneParamCallback as C,
|
|
535
537
|
lesserOrGreater: CP = CP.lt,
|
|
536
|
-
targetNode: BSTNodeKeyOrNode<N> = this.root,
|
|
538
|
+
targetNode: BSTNodeKeyOrNode<K, N> = this.root,
|
|
537
539
|
iterationType = this.iterationType
|
|
538
540
|
): ReturnType<C>[] {
|
|
539
541
|
targetNode = this.ensureNode(targetNode);
|
|
@@ -704,15 +706,17 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|
|
704
706
|
/**
|
|
705
707
|
* The function compares two values using a comparator function and returns whether the first value
|
|
706
708
|
* is greater than, less than, or equal to the second value.
|
|
707
|
-
* @param {
|
|
708
|
-
* @param {
|
|
709
|
+
* @param {K} a - The parameter "a" is of type K.
|
|
710
|
+
* @param {K} b - The parameter "b" in the above code represents a K.
|
|
709
711
|
* @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater
|
|
710
712
|
* than), CP.lt (less than), or CP.eq (equal).
|
|
711
713
|
*/
|
|
712
|
-
protected _compare(a:
|
|
713
|
-
const
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
714
|
+
protected _compare(a: K, b: K): CP {
|
|
715
|
+
const extractedA = this.extractor(a);
|
|
716
|
+
const extractedB = this.extractor(b);
|
|
717
|
+
const compared = this.variant === BSTVariant.MIN ? extractedA - extractedB : extractedB - extractedA;
|
|
718
|
+
|
|
719
|
+
return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq;
|
|
717
720
|
}
|
|
721
|
+
|
|
718
722
|
}
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
BiTreeDeleteResult,
|
|
11
11
|
BSTNodeKeyOrNode,
|
|
12
12
|
BTNCallback,
|
|
13
|
-
BTNKey,
|
|
14
13
|
BTNodeExemplar,
|
|
15
14
|
IterationType,
|
|
16
15
|
RBTNColor,
|
|
@@ -22,13 +21,13 @@ import { BST, BSTNode } from './bst';
|
|
|
22
21
|
import { IBinaryTree } from '../../interfaces';
|
|
23
22
|
import { BinaryTreeNode } from './binary-tree';
|
|
24
23
|
|
|
25
|
-
export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNodeNested<V>> extends BSTNode<
|
|
26
|
-
V,
|
|
24
|
+
export class RedBlackTreeNode<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNodeNested<K, V>> extends BSTNode<
|
|
25
|
+
K, V,
|
|
27
26
|
N
|
|
28
27
|
> {
|
|
29
28
|
color: RBTNColor;
|
|
30
29
|
|
|
31
|
-
constructor(key:
|
|
30
|
+
constructor(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK) {
|
|
32
31
|
super(key, value);
|
|
33
32
|
this.color = color;
|
|
34
33
|
}
|
|
@@ -41,15 +40,15 @@ export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBla
|
|
|
41
40
|
* 4. Red nodes must have black children.
|
|
42
41
|
* 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
|
|
43
42
|
*/
|
|
44
|
-
export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNode<V, RedBlackTreeNodeNested<V>>, TREE extends RedBlackTree<V, N, TREE> = RedBlackTree<V, N, RedBlackTreeNested<V, N>>>
|
|
45
|
-
extends BST<V, N, TREE>
|
|
46
|
-
implements IBinaryTree<V, N, TREE> {
|
|
47
|
-
Sentinel: N = new RedBlackTreeNode<V>(NaN) as unknown as N;
|
|
43
|
+
export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>, TREE extends RedBlackTree<K, V, N, TREE> = RedBlackTree<K, V, N, RedBlackTreeNested<K, V, N>>>
|
|
44
|
+
extends BST<K, V, N, TREE>
|
|
45
|
+
implements IBinaryTree<K, V, N, TREE> {
|
|
46
|
+
Sentinel: N = new RedBlackTreeNode<K, V>(NaN as K) as unknown as N;
|
|
48
47
|
|
|
49
48
|
/**
|
|
50
49
|
* This is the constructor function for a Red-Black Tree data structure in TypeScript, which
|
|
51
50
|
* initializes the tree with optional elements and options.
|
|
52
|
-
* @param [elements] - The `elements` parameter is an optional iterable of `BTNodeExemplar<V, N>`
|
|
51
|
+
* @param [elements] - The `elements` parameter is an optional iterable of `BTNodeExemplar<K, V, N>`
|
|
53
52
|
* objects. It represents the initial elements that will be added to the RBTree during its
|
|
54
53
|
* construction. If this parameter is provided, the `addMany` method is called to add all the
|
|
55
54
|
* elements to the
|
|
@@ -57,7 +56,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
57
56
|
* behavior of the RBTree. It is of type `Partial<RBTreeOptions>`, which means that you can provide
|
|
58
57
|
* only a subset of the properties defined in the `RBTreeOptions` interface.
|
|
59
58
|
*/
|
|
60
|
-
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<RBTreeOptions
|
|
59
|
+
constructor(elements?: Iterable<BTNodeExemplar<K, V, N>>, options?: Partial<RBTreeOptions<K>>) {
|
|
61
60
|
super([], options);
|
|
62
61
|
|
|
63
62
|
this._root = this.Sentinel;
|
|
@@ -78,7 +77,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
78
77
|
|
|
79
78
|
/**
|
|
80
79
|
* The function creates a new Red-Black Tree node with the specified key, value, and color.
|
|
81
|
-
* @param {
|
|
80
|
+
* @param {K} key - The key parameter is the key value associated with the node. It is used to
|
|
82
81
|
* identify and compare nodes in the Red-Black Tree.
|
|
83
82
|
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
84
83
|
* associated with the node. It is of type `V`, which is a generic type that can be replaced with any
|
|
@@ -88,8 +87,8 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
88
87
|
* @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,
|
|
89
88
|
* value, and color.
|
|
90
89
|
*/
|
|
91
|
-
override createNode(key:
|
|
92
|
-
return new RedBlackTreeNode<V, N>(key, value, color) as N;
|
|
90
|
+
override createNode(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK): N {
|
|
91
|
+
return new RedBlackTreeNode<K, V, N>(key, value, color) as N;
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
/**
|
|
@@ -99,32 +98,32 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
99
98
|
* class.
|
|
100
99
|
* @returns a new instance of a RedBlackTree object.
|
|
101
100
|
*/
|
|
102
|
-
override createTree(options?: RBTreeOptions): TREE {
|
|
103
|
-
return new RedBlackTree<V, N, TREE>([], {
|
|
101
|
+
override createTree(options?: RBTreeOptions<K>): TREE {
|
|
102
|
+
return new RedBlackTree<K, V, N, TREE>([], {
|
|
104
103
|
iterationType: this.iterationType,
|
|
105
|
-
|
|
104
|
+
variant: this.variant, ...options
|
|
106
105
|
}) as TREE;
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
/**
|
|
110
109
|
* The function checks if an exemplar is an instance of the RedBlackTreeNode class.
|
|
111
|
-
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<V, N>`.
|
|
110
|
+
* @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar<K, V, N>`.
|
|
112
111
|
* @returns a boolean value indicating whether the exemplar is an instance of the RedBlackTreeNode
|
|
113
112
|
* class.
|
|
114
113
|
*/
|
|
115
|
-
override isNode(exemplar: BTNodeExemplar<V, N>): exemplar is N {
|
|
114
|
+
override isNode(exemplar: BTNodeExemplar<K, V, N>): exemplar is N {
|
|
116
115
|
return exemplar instanceof RedBlackTreeNode;
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
/**
|
|
120
119
|
* The function `exemplarToNode` takes an exemplar and returns a node if the exemplar is valid,
|
|
121
120
|
* otherwise it returns undefined.
|
|
122
|
-
* @param exemplar - BTNodeExemplar<V, N> - A generic type representing an exemplar of a binary tree
|
|
121
|
+
* @param exemplar - BTNodeExemplar<K, V, N> - A generic type representing an exemplar of a binary tree
|
|
123
122
|
* node. It can be either a node itself, an entry (key-value pair), a node key, or any other value
|
|
124
123
|
* that is not a valid exemplar.
|
|
125
124
|
* @returns a variable `node` which is of type `N | undefined`.
|
|
126
125
|
*/
|
|
127
|
-
override exemplarToNode(exemplar: BTNodeExemplar<V, N>): N | undefined {
|
|
126
|
+
override exemplarToNode(exemplar: BTNodeExemplar<K, V, N>): N | undefined {
|
|
128
127
|
let node: N | undefined;
|
|
129
128
|
|
|
130
129
|
if (exemplar === null || exemplar === undefined) {
|
|
@@ -138,7 +137,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
138
137
|
} else {
|
|
139
138
|
node = this.createNode(key, value, RBTNColor.RED);
|
|
140
139
|
}
|
|
141
|
-
} else if (this.
|
|
140
|
+
} else if (this.isNotNodeInstance(exemplar)) {
|
|
142
141
|
node = this.createNode(exemplar, undefined, RBTNColor.RED);
|
|
143
142
|
} else {
|
|
144
143
|
return;
|
|
@@ -157,7 +156,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
157
156
|
* @returns The method `add` returns either an instance of `N` (the node that was added) or
|
|
158
157
|
* `undefined`.
|
|
159
158
|
*/
|
|
160
|
-
override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | undefined {
|
|
159
|
+
override add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>): N | undefined {
|
|
161
160
|
const newNode = this.exemplarToNode(keyOrNodeOrEntry);
|
|
162
161
|
if (newNode === undefined) return;
|
|
163
162
|
|
|
@@ -298,8 +297,8 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
298
297
|
return node !== this.Sentinel && node !== undefined;
|
|
299
298
|
}
|
|
300
299
|
|
|
301
|
-
getNode<C extends BTNCallback<N,
|
|
302
|
-
identifier:
|
|
300
|
+
getNode<C extends BTNCallback<N, K>>(
|
|
301
|
+
identifier: K,
|
|
303
302
|
callback?: C,
|
|
304
303
|
beginRoot?: N | undefined,
|
|
305
304
|
iterationType?: IterationType
|
|
@@ -337,7 +336,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
337
336
|
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
|
|
338
337
|
* the binary tree. It is used to determine if a node matches the given identifier. The `callback`
|
|
339
338
|
* function should take a single parameter of type `N` (the type of the nodes in the binary tree) and
|
|
340
|
-
* @param {
|
|
339
|
+
* @param {K | N | undefined} beginRoot - The `beginRoot` parameter is the starting point for
|
|
341
340
|
* searching for a node in a binary tree. It can be either a key value or a node object. If it is not
|
|
342
341
|
* provided, the search will start from the root of the binary tree.
|
|
343
342
|
* @param iterationType - The `iterationType` parameter is a variable that determines the type of
|
|
@@ -348,7 +347,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|
|
348
347
|
getNode<C extends BTNCallback<N>>(
|
|
349
348
|
identifier: ReturnType<C> | undefined,
|
|
350
349
|
callback: C = this._defaultOneParamCallback as C,
|
|
351
|
-
beginRoot: BSTNodeKeyOrNode<N> = this.root,
|
|
350
|
+
beginRoot: BSTNodeKeyOrNode<K, N> = this.root,
|
|
352
351
|
iterationType = this.iterationType
|
|
353
352
|
): N | null | undefined {
|
|
354
353
|
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|