deque-typed 1.50.7 → 1.50.8
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/binary-tree/avl-tree-multi-map.d.ts +1 -2
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +3 -4
- package/dist/data-structures/binary-tree/binary-tree.d.ts +3 -3
- package/dist/data-structures/binary-tree/binary-tree.js +23 -24
- package/dist/data-structures/binary-tree/bst.d.ts +7 -5
- package/dist/data-structures/binary-tree/bst.js +59 -38
- package/dist/data-structures/binary-tree/rb-tree.js +6 -7
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +1 -2
- package/dist/data-structures/binary-tree/tree-multi-map.js +1 -1
- package/dist/types/common.d.ts +5 -28
- package/dist/types/common.js +0 -40
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +3 -4
- package/src/data-structures/binary-tree/binary-tree.ts +23 -26
- package/src/data-structures/binary-tree/bst.ts +59 -36
- package/src/data-structures/binary-tree/rb-tree.ts +6 -6
- package/src/data-structures/binary-tree/tree-multi-map.ts +2 -2
- package/src/types/common.ts +5 -29
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
import type { AVLTreeMultiMapNested, AVLTreeMultiMapNodeNested, AVLTreeMultiMapOptions, BinaryTreeDeleteResult, BSTNKeyOrNode, BTNCallback, KeyOrNodeOrEntry } from '../../types';
|
|
9
|
-
import { IterationType } from '../../types';
|
|
10
9
|
import { IBinaryTree } from '../../interfaces';
|
|
11
10
|
import { AVLTree, AVLTreeNode } from './avl-tree';
|
|
12
11
|
export declare class AVLTreeMultiMapNode<K = any, V = any, NODE extends AVLTreeMultiMapNode<K, V, NODE> = AVLTreeMultiMapNodeNested<K, V>> extends AVLTreeNode<K, V, NODE> {
|
|
@@ -157,7 +156,7 @@ export declare class AVLTreeMultiMap<K = any, V = any, NODE extends AVLTreeMulti
|
|
|
157
156
|
* values:
|
|
158
157
|
* @returns a boolean value.
|
|
159
158
|
*/
|
|
160
|
-
perfectlyBalance(iterationType?: IterationType): boolean;
|
|
159
|
+
perfectlyBalance(iterationType?: import("../../types").IterationType): boolean;
|
|
161
160
|
/**
|
|
162
161
|
* Time complexity: O(n)
|
|
163
162
|
* Space complexity: O(n)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AVLTreeMultiMap = exports.AVLTreeMultiMapNode = void 0;
|
|
4
|
-
const types_1 = require("../../types");
|
|
5
4
|
const avl_tree_1 = require("./avl-tree");
|
|
6
5
|
class AVLTreeMultiMapNode extends avl_tree_1.AVLTreeNode {
|
|
7
6
|
/**
|
|
@@ -205,10 +204,10 @@ class AVLTreeMultiMap extends avl_tree_1.AVLTree {
|
|
|
205
204
|
}
|
|
206
205
|
else {
|
|
207
206
|
const { familyPosition: fp } = curr;
|
|
208
|
-
if (fp ===
|
|
207
|
+
if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
|
|
209
208
|
parent.left = curr.right;
|
|
210
209
|
}
|
|
211
|
-
else if (fp ===
|
|
210
|
+
else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {
|
|
212
211
|
parent.right = curr.right;
|
|
213
212
|
}
|
|
214
213
|
needBalanced = parent;
|
|
@@ -275,7 +274,7 @@ class AVLTreeMultiMap extends avl_tree_1.AVLTree {
|
|
|
275
274
|
if (sorted.length < 1)
|
|
276
275
|
return false;
|
|
277
276
|
this.clear();
|
|
278
|
-
if (iterationType ===
|
|
277
|
+
if (iterationType === 'RECURSIVE') {
|
|
279
278
|
const buildBalanceBST = (l, r) => {
|
|
280
279
|
if (l > r)
|
|
281
280
|
return;
|
|
@@ -135,11 +135,11 @@ export declare class BinaryTree<K = any, V = any, NODE extends BinaryTreeNode<K,
|
|
|
135
135
|
* `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
|
|
136
136
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
137
137
|
* type of iteration to be used when searching for a node by key. It has a default value of
|
|
138
|
-
* `
|
|
138
|
+
* `'ITERATIVE'`.
|
|
139
139
|
* @returns either the node corresponding to the given key if it is a valid node key, or the key
|
|
140
140
|
* itself if it is not a valid node key.
|
|
141
141
|
*/
|
|
142
|
-
ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, iterationType?:
|
|
142
|
+
ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, iterationType?: string): NODE | null | undefined;
|
|
143
143
|
/**
|
|
144
144
|
* The function "isNode" checks if an keyOrNodeOrEntry is an instance of the BinaryTreeNode class.
|
|
145
145
|
* @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is a variable of type `KeyOrNodeOrEntry<K, V,NODE>`.
|
|
@@ -248,7 +248,7 @@ export declare class BinaryTree<K = any, V = any, NODE extends BinaryTreeNode<K,
|
|
|
248
248
|
* @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
|
|
249
249
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
250
250
|
*/
|
|
251
|
-
getNodeByKey(key: K, iterationType?:
|
|
251
|
+
getNodeByKey(key: K, iterationType?: string): NODE | undefined;
|
|
252
252
|
get<C extends BTNCallback<NODE, K>>(identifier: K, callback?: C, beginRoot?: KeyOrNodeOrEntry<K, V, NODE>, iterationType?: IterationType): V | undefined;
|
|
253
253
|
get<C extends BTNCallback<NODE, NODE>>(identifier: NODE | null | undefined, callback?: C, beginRoot?: KeyOrNodeOrEntry<K, V, NODE>, iterationType?: IterationType): V | undefined;
|
|
254
254
|
get<C extends BTNCallback<NODE>>(identifier: ReturnType<C>, callback: C, beginRoot?: KeyOrNodeOrEntry<K, V, NODE>, iterationType?: IterationType): V | undefined;
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.BinaryTree = exports.BinaryTreeNode = void 0;
|
|
11
|
-
const types_1 = require("../../types");
|
|
12
11
|
const utils_1 = require("../../utils");
|
|
13
12
|
const queue_1 = require("../queue");
|
|
14
13
|
const base_1 = require("../base");
|
|
@@ -75,15 +74,15 @@ class BinaryTreeNode {
|
|
|
75
74
|
get familyPosition() {
|
|
76
75
|
const that = this;
|
|
77
76
|
if (!this.parent) {
|
|
78
|
-
return this.left || this.right ?
|
|
77
|
+
return this.left || this.right ? 'ROOT' : 'ISOLATED';
|
|
79
78
|
}
|
|
80
79
|
if (this.parent.left === that) {
|
|
81
|
-
return this.left || this.right ?
|
|
80
|
+
return this.left || this.right ? 'ROOT_LEFT' : 'LEFT';
|
|
82
81
|
}
|
|
83
82
|
else if (this.parent.right === that) {
|
|
84
|
-
return this.left || this.right ?
|
|
83
|
+
return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';
|
|
85
84
|
}
|
|
86
|
-
return
|
|
85
|
+
return 'MAL_NODE';
|
|
87
86
|
}
|
|
88
87
|
}
|
|
89
88
|
exports.BinaryTreeNode = BinaryTreeNode;
|
|
@@ -106,8 +105,8 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
106
105
|
*/
|
|
107
106
|
constructor(keysOrNodesOrEntries = [], options) {
|
|
108
107
|
super();
|
|
109
|
-
this.iterationType =
|
|
110
|
-
this._extractor = (key) => Number(key);
|
|
108
|
+
this.iterationType = 'ITERATIVE';
|
|
109
|
+
this._extractor = (key) => (typeof key === 'number' ? key : Number(key));
|
|
111
110
|
this._defaultOneParamCallback = (node) => (node ? node.key : undefined);
|
|
112
111
|
if (options) {
|
|
113
112
|
const { iterationType, extractor } = options;
|
|
@@ -213,11 +212,11 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
213
212
|
* `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
|
|
214
213
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
215
214
|
* type of iteration to be used when searching for a node by key. It has a default value of
|
|
216
|
-
* `
|
|
215
|
+
* `'ITERATIVE'`.
|
|
217
216
|
* @returns either the node corresponding to the given key if it is a valid node key, or the key
|
|
218
217
|
* itself if it is not a valid node key.
|
|
219
218
|
*/
|
|
220
|
-
ensureNode(keyOrNodeOrEntry, iterationType =
|
|
219
|
+
ensureNode(keyOrNodeOrEntry, iterationType = 'ITERATIVE') {
|
|
221
220
|
let res;
|
|
222
221
|
if (this.isRealNode(keyOrNodeOrEntry)) {
|
|
223
222
|
res = keyOrNodeOrEntry;
|
|
@@ -444,10 +443,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
444
443
|
}
|
|
445
444
|
else if (parent) {
|
|
446
445
|
const { familyPosition: fp } = curr;
|
|
447
|
-
if (fp ===
|
|
446
|
+
if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
|
|
448
447
|
parent.left = curr.right;
|
|
449
448
|
}
|
|
450
|
-
else if (fp ===
|
|
449
|
+
else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {
|
|
451
450
|
parent.right = curr.right;
|
|
452
451
|
}
|
|
453
452
|
needBalanced = parent;
|
|
@@ -496,7 +495,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
496
495
|
if (!beginRoot)
|
|
497
496
|
return [];
|
|
498
497
|
const ans = [];
|
|
499
|
-
if (iterationType ===
|
|
498
|
+
if (iterationType === 'RECURSIVE') {
|
|
500
499
|
const _traverse = (cur) => {
|
|
501
500
|
if (callback(cur) === identifier) {
|
|
502
501
|
ans.push(cur);
|
|
@@ -576,10 +575,10 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
576
575
|
* @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
|
|
577
576
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
578
577
|
*/
|
|
579
|
-
getNodeByKey(key, iterationType =
|
|
578
|
+
getNodeByKey(key, iterationType = 'ITERATIVE') {
|
|
580
579
|
if (!this.root)
|
|
581
580
|
return undefined;
|
|
582
|
-
if (iterationType ===
|
|
581
|
+
if (iterationType === 'RECURSIVE') {
|
|
583
582
|
const _dfs = (cur) => {
|
|
584
583
|
if (cur.key === key)
|
|
585
584
|
return cur;
|
|
@@ -734,7 +733,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
734
733
|
beginRoot = this.ensureNode(beginRoot);
|
|
735
734
|
if (!beginRoot)
|
|
736
735
|
return true;
|
|
737
|
-
if (iterationType ===
|
|
736
|
+
if (iterationType === 'RECURSIVE') {
|
|
738
737
|
const dfs = (cur, min, max) => {
|
|
739
738
|
if (!this.isRealNode(cur))
|
|
740
739
|
return true;
|
|
@@ -823,7 +822,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
823
822
|
beginRoot = this.ensureNode(beginRoot);
|
|
824
823
|
if (!this.isRealNode(beginRoot))
|
|
825
824
|
return -1;
|
|
826
|
-
if (iterationType ===
|
|
825
|
+
if (iterationType === 'RECURSIVE') {
|
|
827
826
|
const _getMaxHeight = (cur) => {
|
|
828
827
|
if (!this.isRealNode(cur))
|
|
829
828
|
return -1;
|
|
@@ -869,7 +868,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
869
868
|
beginRoot = this.ensureNode(beginRoot);
|
|
870
869
|
if (!beginRoot)
|
|
871
870
|
return -1;
|
|
872
|
-
if (iterationType ===
|
|
871
|
+
if (iterationType === 'RECURSIVE') {
|
|
873
872
|
const _getMinHeight = (cur) => {
|
|
874
873
|
if (!this.isRealNode(cur))
|
|
875
874
|
return 0;
|
|
@@ -967,7 +966,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
967
966
|
beginRoot = this.ensureNode(beginRoot);
|
|
968
967
|
if (!this.isRealNode(beginRoot))
|
|
969
968
|
return beginRoot;
|
|
970
|
-
if (iterationType ===
|
|
969
|
+
if (iterationType === 'RECURSIVE') {
|
|
971
970
|
const _traverse = (cur) => {
|
|
972
971
|
if (!this.isRealNode(cur.left))
|
|
973
972
|
return cur;
|
|
@@ -1011,7 +1010,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1011
1010
|
beginRoot = this.ensureNode(beginRoot);
|
|
1012
1011
|
if (!beginRoot)
|
|
1013
1012
|
return beginRoot;
|
|
1014
|
-
if (iterationType ===
|
|
1013
|
+
if (iterationType === 'RECURSIVE') {
|
|
1015
1014
|
const _traverse = (cur) => {
|
|
1016
1015
|
if (!this.isRealNode(cur.right))
|
|
1017
1016
|
return cur;
|
|
@@ -1111,12 +1110,12 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1111
1110
|
* `false`, null or undefined
|
|
1112
1111
|
* @returns an array of values that are the return values of the callback function.
|
|
1113
1112
|
*/
|
|
1114
|
-
dfs(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root, iterationType =
|
|
1113
|
+
dfs(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root, iterationType = 'ITERATIVE', includeNull = false) {
|
|
1115
1114
|
beginRoot = this.ensureNode(beginRoot);
|
|
1116
1115
|
if (!beginRoot)
|
|
1117
1116
|
return [];
|
|
1118
1117
|
const ans = [];
|
|
1119
|
-
if (iterationType ===
|
|
1118
|
+
if (iterationType === 'RECURSIVE') {
|
|
1120
1119
|
const _traverse = (node) => {
|
|
1121
1120
|
switch (pattern) {
|
|
1122
1121
|
case 'in':
|
|
@@ -1247,7 +1246,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1247
1246
|
if (!beginRoot)
|
|
1248
1247
|
return [];
|
|
1249
1248
|
const ans = [];
|
|
1250
|
-
if (iterationType ===
|
|
1249
|
+
if (iterationType === 'RECURSIVE') {
|
|
1251
1250
|
const queue = new queue_1.Queue([beginRoot]);
|
|
1252
1251
|
const traverse = (level) => {
|
|
1253
1252
|
if (queue.size === 0)
|
|
@@ -1324,7 +1323,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1324
1323
|
const levelsNodes = [];
|
|
1325
1324
|
if (!beginRoot)
|
|
1326
1325
|
return levelsNodes;
|
|
1327
|
-
if (iterationType ===
|
|
1326
|
+
if (iterationType === 'RECURSIVE') {
|
|
1328
1327
|
const _recursive = (node, level) => {
|
|
1329
1328
|
if (!levelsNodes[level])
|
|
1330
1329
|
levelsNodes[level] = [];
|
|
@@ -1611,7 +1610,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1611
1610
|
*_getIterator(node = this.root) {
|
|
1612
1611
|
if (!node)
|
|
1613
1612
|
return;
|
|
1614
|
-
if (this.iterationType ===
|
|
1613
|
+
if (this.iterationType === 'ITERATIVE') {
|
|
1615
1614
|
const stack = [];
|
|
1616
1615
|
let current = node;
|
|
1617
1616
|
while (current || stack.length > 0) {
|
|
@@ -109,10 +109,10 @@ export declare class BST<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BS
|
|
|
109
109
|
* @param {K | NODE | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `NODE`, or
|
|
110
110
|
* `undefined`.
|
|
111
111
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
112
|
-
* type of iteration to be performed. It has a default value of `
|
|
112
|
+
* type of iteration to be performed. It has a default value of `'ITERATIVE'`.
|
|
113
113
|
* @returns either a node object (NODE) or undefined.
|
|
114
114
|
*/
|
|
115
|
-
ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, iterationType?:
|
|
115
|
+
ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, iterationType?: string): NODE | undefined;
|
|
116
116
|
/**
|
|
117
117
|
* The function checks if an keyOrNodeOrEntry is an instance of BSTNode.
|
|
118
118
|
* @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter is a variable of type `KeyOrNodeOrEntry<K, V, NODE>`.
|
|
@@ -179,7 +179,7 @@ export declare class BST<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BS
|
|
|
179
179
|
* @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
|
|
180
180
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
181
181
|
*/
|
|
182
|
-
getNodeByKey(key: K, iterationType?:
|
|
182
|
+
getNodeByKey(key: K, iterationType?: string): NODE | undefined;
|
|
183
183
|
/**
|
|
184
184
|
* Time Complexity: O(log n)
|
|
185
185
|
* Space Complexity: O(k + log n)
|
|
@@ -372,8 +372,10 @@ export declare class BST<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BS
|
|
|
372
372
|
* is greater than, less than, or equal to the second value.
|
|
373
373
|
* @param {K} a - The parameter "a" is of type K.
|
|
374
374
|
* @param {K} b - The parameter "b" in the above code represents a K.
|
|
375
|
-
* @returns a value of type CP (ComparisonResult). The possible return values are
|
|
376
|
-
* than),
|
|
375
|
+
* @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater
|
|
376
|
+
* than), 'LT' (less than), or 'EQ' (equal).
|
|
377
377
|
*/
|
|
378
378
|
protected _compare(a: K, b: K): CP;
|
|
379
|
+
protected _lt(a: K, b: K): boolean;
|
|
380
|
+
protected _gt(a: K, b: K): boolean;
|
|
379
381
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BST = exports.BSTNode = void 0;
|
|
4
|
-
const types_1 = require("../../types");
|
|
5
4
|
const binary_tree_1 = require("./binary-tree");
|
|
6
5
|
const queue_1 = require("../queue");
|
|
7
6
|
class BSTNode extends binary_tree_1.BinaryTreeNode {
|
|
@@ -70,7 +69,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
70
69
|
*/
|
|
71
70
|
constructor(keysOrNodesOrEntries = [], options) {
|
|
72
71
|
super([], options);
|
|
73
|
-
this._variant =
|
|
72
|
+
this._variant = 'STANDARD';
|
|
74
73
|
if (options) {
|
|
75
74
|
const { variant } = options;
|
|
76
75
|
if (variant)
|
|
@@ -162,10 +161,10 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
162
161
|
* @param {K | NODE | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `NODE`, or
|
|
163
162
|
* `undefined`.
|
|
164
163
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
165
|
-
* type of iteration to be performed. It has a default value of `
|
|
164
|
+
* type of iteration to be performed. It has a default value of `'ITERATIVE'`.
|
|
166
165
|
* @returns either a node object (NODE) or undefined.
|
|
167
166
|
*/
|
|
168
|
-
ensureNode(keyOrNodeOrEntry, iterationType =
|
|
167
|
+
ensureNode(keyOrNodeOrEntry, iterationType = 'ITERATIVE') {
|
|
169
168
|
let res;
|
|
170
169
|
if (this.isRealNode(keyOrNodeOrEntry)) {
|
|
171
170
|
res = keyOrNodeOrEntry;
|
|
@@ -215,7 +214,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
215
214
|
}
|
|
216
215
|
let current = this.root;
|
|
217
216
|
while (current !== undefined) {
|
|
218
|
-
if (this._compare(current.key, newNode.key) ===
|
|
217
|
+
if (this._compare(current.key, newNode.key) === 'EQ') {
|
|
219
218
|
// if (current !== newNode) {
|
|
220
219
|
// The key value is the same but the reference is different, update the value of the existing node
|
|
221
220
|
this._replaceNode(current, newNode);
|
|
@@ -226,7 +225,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
226
225
|
// return;
|
|
227
226
|
// }
|
|
228
227
|
}
|
|
229
|
-
else if (this._compare(current.key, newNode.key) ===
|
|
228
|
+
else if (this._compare(current.key, newNode.key) === 'GT') {
|
|
230
229
|
if (current.left === undefined) {
|
|
231
230
|
current.left = newNode;
|
|
232
231
|
this._size++;
|
|
@@ -335,7 +334,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
335
334
|
}
|
|
336
335
|
}
|
|
337
336
|
};
|
|
338
|
-
if (iterationType ===
|
|
337
|
+
if (iterationType === 'RECURSIVE') {
|
|
339
338
|
_dfs(sorted);
|
|
340
339
|
}
|
|
341
340
|
else {
|
|
@@ -361,18 +360,18 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
361
360
|
* @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
|
|
362
361
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
363
362
|
*/
|
|
364
|
-
getNodeByKey(key, iterationType =
|
|
363
|
+
getNodeByKey(key, iterationType = 'ITERATIVE') {
|
|
365
364
|
if (!this.isRealNode(this.root))
|
|
366
365
|
return undefined;
|
|
367
|
-
if (iterationType ===
|
|
366
|
+
if (iterationType === 'RECURSIVE') {
|
|
368
367
|
const _dfs = (cur) => {
|
|
369
368
|
if (cur.key === key)
|
|
370
369
|
return cur;
|
|
371
370
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right))
|
|
372
371
|
return;
|
|
373
|
-
if (this._compare(cur.key, key) ===
|
|
372
|
+
if (this._compare(cur.key, key) === 'GT' && this.isRealNode(cur.left))
|
|
374
373
|
return _dfs(cur.left);
|
|
375
|
-
if (this._compare(cur.key, key) ===
|
|
374
|
+
if (this._compare(cur.key, key) === 'LT' && this.isRealNode(cur.right))
|
|
376
375
|
return _dfs(cur.right);
|
|
377
376
|
};
|
|
378
377
|
return _dfs(this.root);
|
|
@@ -382,11 +381,11 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
382
381
|
while (queue.size > 0) {
|
|
383
382
|
const cur = queue.shift();
|
|
384
383
|
if (this.isRealNode(cur)) {
|
|
385
|
-
if (this._compare(cur.key, key) ===
|
|
384
|
+
if (this._compare(cur.key, key) === 'EQ')
|
|
386
385
|
return cur;
|
|
387
|
-
if (this._compare(cur.key, key) ===
|
|
386
|
+
if (this._compare(cur.key, key) === 'GT')
|
|
388
387
|
this.isRealNode(cur.left) && queue.push(cur.left);
|
|
389
|
-
if (this._compare(cur.key, key) ===
|
|
388
|
+
if (this._compare(cur.key, key) === 'LT')
|
|
390
389
|
this.isRealNode(cur.right) && queue.push(cur.right);
|
|
391
390
|
}
|
|
392
391
|
}
|
|
@@ -425,7 +424,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
425
424
|
if (!beginRoot)
|
|
426
425
|
return [];
|
|
427
426
|
const ans = [];
|
|
428
|
-
if (iterationType ===
|
|
427
|
+
if (iterationType === 'RECURSIVE') {
|
|
429
428
|
const _traverse = (cur) => {
|
|
430
429
|
const callbackResult = callback(cur);
|
|
431
430
|
if (callbackResult === identifier) {
|
|
@@ -437,10 +436,10 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
437
436
|
return;
|
|
438
437
|
// TODO potential bug
|
|
439
438
|
if (callback === this._defaultOneParamCallback) {
|
|
440
|
-
if (this._compare(cur.key, identifier) ===
|
|
441
|
-
|
|
442
|
-
if (this._compare(cur.key, identifier) ===
|
|
443
|
-
|
|
439
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier) === 'GT')
|
|
440
|
+
_traverse(cur.left);
|
|
441
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier) === 'LT')
|
|
442
|
+
_traverse(cur.right);
|
|
444
443
|
}
|
|
445
444
|
else {
|
|
446
445
|
this.isRealNode(cur.left) && _traverse(cur.left);
|
|
@@ -450,9 +449,9 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
450
449
|
_traverse(beginRoot);
|
|
451
450
|
}
|
|
452
451
|
else {
|
|
453
|
-
const
|
|
454
|
-
while (
|
|
455
|
-
const cur =
|
|
452
|
+
const stack = [beginRoot];
|
|
453
|
+
while (stack.length > 0) {
|
|
454
|
+
const cur = stack.pop();
|
|
456
455
|
if (this.isRealNode(cur)) {
|
|
457
456
|
const callbackResult = callback(cur);
|
|
458
457
|
if (callbackResult === identifier) {
|
|
@@ -462,14 +461,20 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
462
461
|
}
|
|
463
462
|
// TODO potential bug
|
|
464
463
|
if (callback === this._defaultOneParamCallback) {
|
|
465
|
-
if (this._compare(cur.key, identifier) ===
|
|
466
|
-
|
|
467
|
-
if (this._compare(cur.key, identifier) ===
|
|
468
|
-
|
|
464
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier) === 'LT')
|
|
465
|
+
stack.push(cur.right);
|
|
466
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier) === 'GT')
|
|
467
|
+
stack.push(cur.left);
|
|
468
|
+
// if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
|
|
469
|
+
// if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
|
|
470
|
+
// // @ts-ignore
|
|
471
|
+
// if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right);
|
|
472
|
+
// // @ts-ignore
|
|
473
|
+
// if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left);
|
|
469
474
|
}
|
|
470
475
|
else {
|
|
471
|
-
this.isRealNode(cur.
|
|
472
|
-
this.isRealNode(cur.
|
|
476
|
+
this.isRealNode(cur.right) && stack.push(cur.right);
|
|
477
|
+
this.isRealNode(cur.left) && stack.push(cur.left);
|
|
473
478
|
}
|
|
474
479
|
}
|
|
475
480
|
}
|
|
@@ -499,7 +504,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
499
504
|
* following values:
|
|
500
505
|
* @returns The method is returning an array of the return type of the callback function.
|
|
501
506
|
*/
|
|
502
|
-
dfs(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root, iterationType =
|
|
507
|
+
dfs(callback = this._defaultOneParamCallback, pattern = 'in', beginRoot = this.root, iterationType = 'ITERATIVE') {
|
|
503
508
|
return super.dfs(callback, pattern, beginRoot, iterationType, false);
|
|
504
509
|
}
|
|
505
510
|
/**
|
|
@@ -572,7 +577,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
572
577
|
let current = this.ensureNode(beginRoot);
|
|
573
578
|
if (!current)
|
|
574
579
|
return undefined;
|
|
575
|
-
if (this._variant ===
|
|
580
|
+
if (this._variant === 'STANDARD') {
|
|
576
581
|
// For BSTVariant.MIN, find the rightmost node
|
|
577
582
|
while (current.right !== undefined) {
|
|
578
583
|
current = current.right;
|
|
@@ -611,7 +616,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
611
616
|
* @returns The function `lesserOrGreaterTraverse` returns an array of values of type
|
|
612
617
|
* `ReturnType<C>`, which is the return type of the callback function passed as an argument.
|
|
613
618
|
*/
|
|
614
|
-
lesserOrGreaterTraverse(callback = this._defaultOneParamCallback, lesserOrGreater =
|
|
619
|
+
lesserOrGreaterTraverse(callback = this._defaultOneParamCallback, lesserOrGreater = 'LT', targetNode = this.root, iterationType = this.iterationType) {
|
|
615
620
|
targetNode = this.ensureNode(targetNode);
|
|
616
621
|
const ans = [];
|
|
617
622
|
if (!targetNode)
|
|
@@ -619,7 +624,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
619
624
|
if (!this.root)
|
|
620
625
|
return ans;
|
|
621
626
|
const targetKey = targetNode.key;
|
|
622
|
-
if (iterationType ===
|
|
627
|
+
if (iterationType === 'RECURSIVE') {
|
|
623
628
|
const _traverse = (cur) => {
|
|
624
629
|
const compared = this._compare(cur.key, targetKey);
|
|
625
630
|
if (compared === lesserOrGreater)
|
|
@@ -669,7 +674,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
669
674
|
this.clear();
|
|
670
675
|
if (sorted.length < 1)
|
|
671
676
|
return false;
|
|
672
|
-
if (iterationType ===
|
|
677
|
+
if (iterationType === 'RECURSIVE') {
|
|
673
678
|
const buildBalanceBST = (l, r) => {
|
|
674
679
|
if (l > r)
|
|
675
680
|
return;
|
|
@@ -727,7 +732,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
727
732
|
if (!this.root)
|
|
728
733
|
return true;
|
|
729
734
|
let balanced = true;
|
|
730
|
-
if (iterationType ===
|
|
735
|
+
if (iterationType === 'RECURSIVE') {
|
|
731
736
|
const _height = (cur) => {
|
|
732
737
|
if (!cur)
|
|
733
738
|
return 0;
|
|
@@ -784,14 +789,30 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
784
789
|
* is greater than, less than, or equal to the second value.
|
|
785
790
|
* @param {K} a - The parameter "a" is of type K.
|
|
786
791
|
* @param {K} b - The parameter "b" in the above code represents a K.
|
|
787
|
-
* @returns a value of type CP (ComparisonResult). The possible return values are
|
|
788
|
-
* than),
|
|
792
|
+
* @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater
|
|
793
|
+
* than), 'LT' (less than), or 'EQ' (equal).
|
|
789
794
|
*/
|
|
790
795
|
_compare(a, b) {
|
|
791
796
|
const extractedA = this.extractor(a);
|
|
792
797
|
const extractedB = this.extractor(b);
|
|
793
|
-
const compared = this.variant ===
|
|
794
|
-
return compared > 0 ?
|
|
798
|
+
const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA;
|
|
799
|
+
return compared > 0 ? 'GT' : compared < 0 ? 'LT' : 'EQ';
|
|
800
|
+
}
|
|
801
|
+
_lt(a, b) {
|
|
802
|
+
const extractedA = this.extractor(a);
|
|
803
|
+
const extractedB = this.extractor(b);
|
|
804
|
+
// return this.variant === BSTVariant.STANDARD ? extractedA < extractedB : extractedA > extractedB;
|
|
805
|
+
return this.variant === 'STANDARD' ? extractedA < extractedB : extractedA > extractedB;
|
|
806
|
+
// return extractedA < extractedB;
|
|
807
|
+
// return a < b;
|
|
808
|
+
}
|
|
809
|
+
_gt(a, b) {
|
|
810
|
+
const extractedA = this.extractor(a);
|
|
811
|
+
const extractedB = this.extractor(b);
|
|
812
|
+
// return this.variant === BSTVariant.STANDARD ? extractedA > extractedB : extractedA < extractedB;
|
|
813
|
+
return this.variant === 'STANDARD' ? extractedA > extractedB : extractedA < extractedB;
|
|
814
|
+
// return extractedA > extractedB;
|
|
815
|
+
// return a > b;
|
|
795
816
|
}
|
|
796
817
|
}
|
|
797
818
|
exports.BST = BST;
|
|
@@ -193,9 +193,8 @@ class RedBlackTree extends bst_1.BST {
|
|
|
193
193
|
*/
|
|
194
194
|
getNode(identifier, callback = this._defaultOneParamCallback, beginRoot = this.root, iterationType = this.iterationType) {
|
|
195
195
|
var _a;
|
|
196
|
-
if (identifier instanceof RedBlackTreeNode)
|
|
197
|
-
|
|
198
|
-
return (_a = super.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : undefined;
|
|
196
|
+
// if ((identifier as any) instanceof RedBlackTreeNode) callback = (node => node) as C;
|
|
197
|
+
return (_a = this.getNodes(identifier, callback, true, beginRoot, iterationType)[0]) !== null && _a !== void 0 ? _a : undefined;
|
|
199
198
|
}
|
|
200
199
|
/**
|
|
201
200
|
* Time Complexity: O(1)
|
|
@@ -234,7 +233,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
234
233
|
if (!this.isRealNode(newNode))
|
|
235
234
|
return false;
|
|
236
235
|
const insertStatus = this._insert(newNode);
|
|
237
|
-
if (insertStatus ===
|
|
236
|
+
if (insertStatus === 'CREATED') {
|
|
238
237
|
// Ensure the root is black
|
|
239
238
|
if (this.isRealNode(this._root)) {
|
|
240
239
|
this._root.color = types_1.RBTNColor.BLACK;
|
|
@@ -246,7 +245,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
246
245
|
return true;
|
|
247
246
|
}
|
|
248
247
|
else
|
|
249
|
-
return insertStatus ===
|
|
248
|
+
return insertStatus === 'UPDATED';
|
|
250
249
|
}
|
|
251
250
|
/**
|
|
252
251
|
* Time Complexity: O(log n)
|
|
@@ -379,7 +378,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
379
378
|
}
|
|
380
379
|
else {
|
|
381
380
|
this._replaceNode(current, node);
|
|
382
|
-
return
|
|
381
|
+
return 'UPDATED';
|
|
383
382
|
}
|
|
384
383
|
}
|
|
385
384
|
node.parent = parent;
|
|
@@ -396,7 +395,7 @@ class RedBlackTree extends bst_1.BST {
|
|
|
396
395
|
node.right = this.SENTINEL;
|
|
397
396
|
node.color = types_1.RBTNColor.RED;
|
|
398
397
|
this._insertFixup(node);
|
|
399
|
-
return
|
|
398
|
+
return 'CREATED';
|
|
400
399
|
}
|
|
401
400
|
/**
|
|
402
401
|
* Time Complexity: O(1)
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
import type { BinaryTreeDeleteResult, BSTNKeyOrNode, BTNCallback, KeyOrNodeOrEntry, TreeMultiMapNested, TreeMultiMapNodeNested, TreeMultiMapOptions } from '../../types';
|
|
9
|
-
import { IterationType } from '../../types';
|
|
10
9
|
import { IBinaryTree } from '../../interfaces';
|
|
11
10
|
import { RedBlackTree, RedBlackTreeNode } from './rb-tree';
|
|
12
11
|
export declare class TreeMultiMapNode<K = any, V = any, NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNodeNested<K, V>> extends RedBlackTreeNode<K, V, NODE> {
|
|
@@ -164,7 +163,7 @@ export declare class TreeMultiMap<K = any, V = any, NODE extends TreeMultiMapNod
|
|
|
164
163
|
* values:
|
|
165
164
|
* @returns a boolean value.
|
|
166
165
|
*/
|
|
167
|
-
perfectlyBalance(iterationType?: IterationType): boolean;
|
|
166
|
+
perfectlyBalance(iterationType?: import("../../types").IterationType): boolean;
|
|
168
167
|
/**
|
|
169
168
|
* Time complexity: O(n)
|
|
170
169
|
* Space complexity: O(n)
|
|
@@ -312,7 +312,7 @@ class TreeMultiMap extends rb_tree_1.RedBlackTree {
|
|
|
312
312
|
if (sorted.length < 1)
|
|
313
313
|
return false;
|
|
314
314
|
this.clear();
|
|
315
|
-
if (iterationType ===
|
|
315
|
+
if (iterationType === 'RECURSIVE') {
|
|
316
316
|
const buildBalanceBST = (l, r) => {
|
|
317
317
|
if (l > r)
|
|
318
318
|
return;
|
package/dist/types/common.d.ts
CHANGED
|
@@ -1,31 +1,13 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
INVERSE = "INVERSE"
|
|
4
|
-
}
|
|
5
|
-
export declare enum CP {
|
|
6
|
-
lt = "lt",
|
|
7
|
-
eq = "eq",
|
|
8
|
-
gt = "gt"
|
|
9
|
-
}
|
|
1
|
+
export type BSTVariant = 'STANDARD' | 'INVERSE';
|
|
2
|
+
export type CP = 'LT' | 'EQ' | 'GT';
|
|
10
3
|
/**
|
|
11
4
|
* Enum representing different loop types.
|
|
12
5
|
*
|
|
13
6
|
* - `iterative`: Indicates the iterative loop type (with loops that use iterations).
|
|
14
7
|
* - `recursive`: Indicates the recursive loop type (with loops that call themselves).
|
|
15
8
|
*/
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
RECURSIVE = "RECURSIVE"
|
|
19
|
-
}
|
|
20
|
-
export declare enum FamilyPosition {
|
|
21
|
-
ROOT = "ROOT",
|
|
22
|
-
LEFT = "LEFT",
|
|
23
|
-
RIGHT = "RIGHT",
|
|
24
|
-
ROOT_LEFT = "ROOT_LEFT",
|
|
25
|
-
ROOT_RIGHT = "ROOT_RIGHT",
|
|
26
|
-
ISOLATED = "ISOLATED",
|
|
27
|
-
MAL_NODE = "MAL_NODE"
|
|
28
|
-
}
|
|
9
|
+
export type IterationType = 'ITERATIVE' | 'RECURSIVE';
|
|
10
|
+
export type FamilyPosition = 'ROOT' | 'LEFT' | 'RIGHT' | 'ROOT_LEFT' | 'ROOT_RIGHT' | 'ISOLATED' | 'MAL_NODE';
|
|
29
11
|
export type Comparator<K> = (a: K, b: K) => number;
|
|
30
12
|
export type DFSOrderPattern = 'pre' | 'in' | 'post';
|
|
31
13
|
export type NodeDisplayLayout = [string[], number, number, number];
|
|
@@ -52,9 +34,4 @@ export type BinaryTreeDeleteResult<N> = {
|
|
|
52
34
|
deleted: N | null | undefined;
|
|
53
35
|
needBalanced: N | null | undefined;
|
|
54
36
|
};
|
|
55
|
-
export
|
|
56
|
-
CREATED = "CREATED",
|
|
57
|
-
READ = "READ",
|
|
58
|
-
UPDATED = "UPDATED",
|
|
59
|
-
DELETED = "DELETED"
|
|
60
|
-
}
|
|
37
|
+
export type CRUD = 'CREATED' | 'READ' | 'UPDATED' | 'DELETED';
|
package/dist/types/common.js
CHANGED
|
@@ -1,42 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CRUD = exports.FamilyPosition = exports.IterationType = exports.CP = exports.BSTVariant = void 0;
|
|
4
|
-
var BSTVariant;
|
|
5
|
-
(function (BSTVariant) {
|
|
6
|
-
BSTVariant["STANDARD"] = "STANDARD";
|
|
7
|
-
BSTVariant["INVERSE"] = "INVERSE";
|
|
8
|
-
})(BSTVariant = exports.BSTVariant || (exports.BSTVariant = {}));
|
|
9
|
-
var CP;
|
|
10
|
-
(function (CP) {
|
|
11
|
-
CP["lt"] = "lt";
|
|
12
|
-
CP["eq"] = "eq";
|
|
13
|
-
CP["gt"] = "gt";
|
|
14
|
-
})(CP = exports.CP || (exports.CP = {}));
|
|
15
|
-
/**
|
|
16
|
-
* Enum representing different loop types.
|
|
17
|
-
*
|
|
18
|
-
* - `iterative`: Indicates the iterative loop type (with loops that use iterations).
|
|
19
|
-
* - `recursive`: Indicates the recursive loop type (with loops that call themselves).
|
|
20
|
-
*/
|
|
21
|
-
var IterationType;
|
|
22
|
-
(function (IterationType) {
|
|
23
|
-
IterationType["ITERATIVE"] = "ITERATIVE";
|
|
24
|
-
IterationType["RECURSIVE"] = "RECURSIVE";
|
|
25
|
-
})(IterationType = exports.IterationType || (exports.IterationType = {}));
|
|
26
|
-
var FamilyPosition;
|
|
27
|
-
(function (FamilyPosition) {
|
|
28
|
-
FamilyPosition["ROOT"] = "ROOT";
|
|
29
|
-
FamilyPosition["LEFT"] = "LEFT";
|
|
30
|
-
FamilyPosition["RIGHT"] = "RIGHT";
|
|
31
|
-
FamilyPosition["ROOT_LEFT"] = "ROOT_LEFT";
|
|
32
|
-
FamilyPosition["ROOT_RIGHT"] = "ROOT_RIGHT";
|
|
33
|
-
FamilyPosition["ISOLATED"] = "ISOLATED";
|
|
34
|
-
FamilyPosition["MAL_NODE"] = "MAL_NODE";
|
|
35
|
-
})(FamilyPosition = exports.FamilyPosition || (exports.FamilyPosition = {}));
|
|
36
|
-
var CRUD;
|
|
37
|
-
(function (CRUD) {
|
|
38
|
-
CRUD["CREATED"] = "CREATED";
|
|
39
|
-
CRUD["READ"] = "READ";
|
|
40
|
-
CRUD["UPDATED"] = "UPDATED";
|
|
41
|
-
CRUD["DELETED"] = "DELETED";
|
|
42
|
-
})(CRUD = exports.CRUD || (exports.CRUD = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deque-typed",
|
|
3
|
-
"version": "1.50.
|
|
3
|
+
"version": "1.50.8",
|
|
4
4
|
"description": "Deque. Javascript & Typescript Data Structure.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -119,6 +119,6 @@
|
|
|
119
119
|
"typescript": "^4.9.5"
|
|
120
120
|
},
|
|
121
121
|
"dependencies": {
|
|
122
|
-
"data-structure-typed": "^1.50.
|
|
122
|
+
"data-structure-typed": "^1.50.8"
|
|
123
123
|
}
|
|
124
124
|
}
|
|
@@ -14,7 +14,6 @@ import type {
|
|
|
14
14
|
BTNCallback,
|
|
15
15
|
KeyOrNodeOrEntry
|
|
16
16
|
} from '../../types';
|
|
17
|
-
import { FamilyPosition, IterationType } from '../../types';
|
|
18
17
|
import { IBinaryTree } from '../../interfaces';
|
|
19
18
|
import { AVLTree, AVLTreeNode } from './avl-tree';
|
|
20
19
|
|
|
@@ -249,9 +248,9 @@ export class AVLTreeMultiMap<
|
|
|
249
248
|
if (curr.right !== undefined) this._setRoot(curr.right);
|
|
250
249
|
} else {
|
|
251
250
|
const { familyPosition: fp } = curr;
|
|
252
|
-
if (fp ===
|
|
251
|
+
if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
|
|
253
252
|
parent.left = curr.right;
|
|
254
|
-
} else if (fp ===
|
|
253
|
+
} else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {
|
|
255
254
|
parent.right = curr.right;
|
|
256
255
|
}
|
|
257
256
|
needBalanced = parent;
|
|
@@ -324,7 +323,7 @@ export class AVLTreeMultiMap<
|
|
|
324
323
|
|
|
325
324
|
this.clear();
|
|
326
325
|
|
|
327
|
-
if (iterationType ===
|
|
326
|
+
if (iterationType === 'RECURSIVE') {
|
|
328
327
|
const buildBalanceBST = (l: number, r: number) => {
|
|
329
328
|
if (l > r) return;
|
|
330
329
|
const m = l + Math.floor((r - l) / 2);
|
|
@@ -107,16 +107,16 @@ export class BinaryTreeNode<
|
|
|
107
107
|
get familyPosition(): FamilyPosition {
|
|
108
108
|
const that = this as unknown as NODE;
|
|
109
109
|
if (!this.parent) {
|
|
110
|
-
return this.left || this.right ?
|
|
110
|
+
return this.left || this.right ? 'ROOT' : 'ISOLATED';
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
if (this.parent.left === that) {
|
|
114
|
-
return this.left || this.right ?
|
|
114
|
+
return this.left || this.right ? 'ROOT_LEFT' : 'LEFT';
|
|
115
115
|
} else if (this.parent.right === that) {
|
|
116
|
-
return this.left || this.right ?
|
|
116
|
+
return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
return
|
|
119
|
+
return 'MAL_NODE';
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
|
|
@@ -136,7 +136,7 @@ export class BinaryTree<
|
|
|
136
136
|
>
|
|
137
137
|
extends IterableEntryBase<K, V | undefined>
|
|
138
138
|
implements IBinaryTree<K, V, NODE, TREE> {
|
|
139
|
-
iterationType =
|
|
139
|
+
iterationType: IterationType = 'ITERATIVE';
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
142
|
* The constructor function initializes a binary tree object with optional keysOrNodesOrEntries and options.
|
|
@@ -160,7 +160,7 @@ export class BinaryTree<
|
|
|
160
160
|
if (keysOrNodesOrEntries) this.addMany(keysOrNodesOrEntries);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
protected _extractor = (key: K) => Number(key);
|
|
163
|
+
protected _extractor = (key: K) => (typeof key === 'number' ? key : Number(key));
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
166
|
* The function returns the value of the `_extractor` property.
|
|
@@ -260,14 +260,11 @@ export class BinaryTree<
|
|
|
260
260
|
* `null`, or `undefined`. It represents a key used to identify a node in a binary tree.
|
|
261
261
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
262
262
|
* type of iteration to be used when searching for a node by key. It has a default value of
|
|
263
|
-
* `
|
|
263
|
+
* `'ITERATIVE'`.
|
|
264
264
|
* @returns either the node corresponding to the given key if it is a valid node key, or the key
|
|
265
265
|
* itself if it is not a valid node key.
|
|
266
266
|
*/
|
|
267
|
-
ensureNode(
|
|
268
|
-
keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
|
|
269
|
-
iterationType = IterationType.ITERATIVE
|
|
270
|
-
): NODE | null | undefined {
|
|
267
|
+
ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, iterationType = 'ITERATIVE'): NODE | null | undefined {
|
|
271
268
|
let res: NODE | null | undefined;
|
|
272
269
|
if (this.isRealNode(keyOrNodeOrEntry)) {
|
|
273
270
|
res = keyOrNodeOrEntry;
|
|
@@ -521,9 +518,9 @@ export class BinaryTree<
|
|
|
521
518
|
}
|
|
522
519
|
} else if (parent) {
|
|
523
520
|
const { familyPosition: fp } = curr;
|
|
524
|
-
if (fp ===
|
|
521
|
+
if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
|
|
525
522
|
parent.left = curr.right;
|
|
526
|
-
} else if (fp ===
|
|
523
|
+
} else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {
|
|
527
524
|
parent.right = curr.right;
|
|
528
525
|
}
|
|
529
526
|
needBalanced = parent;
|
|
@@ -606,7 +603,7 @@ export class BinaryTree<
|
|
|
606
603
|
|
|
607
604
|
const ans: NODE[] = [];
|
|
608
605
|
|
|
609
|
-
if (iterationType ===
|
|
606
|
+
if (iterationType === 'RECURSIVE') {
|
|
610
607
|
const _traverse = (cur: NODE) => {
|
|
611
608
|
if (callback(cur) === identifier) {
|
|
612
609
|
ans.push(cur);
|
|
@@ -714,9 +711,9 @@ export class BinaryTree<
|
|
|
714
711
|
* @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
|
|
715
712
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
716
713
|
*/
|
|
717
|
-
getNodeByKey(key: K, iterationType =
|
|
714
|
+
getNodeByKey(key: K, iterationType = 'ITERATIVE'): NODE | undefined {
|
|
718
715
|
if (!this.root) return undefined;
|
|
719
|
-
if (iterationType ===
|
|
716
|
+
if (iterationType === 'RECURSIVE') {
|
|
720
717
|
const _dfs = (cur: NODE): NODE | undefined => {
|
|
721
718
|
if (cur.key === key) return cur;
|
|
722
719
|
|
|
@@ -932,7 +929,7 @@ export class BinaryTree<
|
|
|
932
929
|
beginRoot = this.ensureNode(beginRoot);
|
|
933
930
|
if (!beginRoot) return true;
|
|
934
931
|
|
|
935
|
-
if (iterationType ===
|
|
932
|
+
if (iterationType === 'RECURSIVE') {
|
|
936
933
|
const dfs = (cur: NODE | null | undefined, min: number, max: number): boolean => {
|
|
937
934
|
if (!this.isRealNode(cur)) return true;
|
|
938
935
|
const numKey = this.extractor(cur.key);
|
|
@@ -1023,7 +1020,7 @@ export class BinaryTree<
|
|
|
1023
1020
|
beginRoot = this.ensureNode(beginRoot);
|
|
1024
1021
|
if (!this.isRealNode(beginRoot)) return -1;
|
|
1025
1022
|
|
|
1026
|
-
if (iterationType ===
|
|
1023
|
+
if (iterationType === 'RECURSIVE') {
|
|
1027
1024
|
const _getMaxHeight = (cur: NODE | null | undefined): number => {
|
|
1028
1025
|
if (!this.isRealNode(cur)) return -1;
|
|
1029
1026
|
const leftHeight = _getMaxHeight(cur.left);
|
|
@@ -1071,7 +1068,7 @@ export class BinaryTree<
|
|
|
1071
1068
|
beginRoot = this.ensureNode(beginRoot);
|
|
1072
1069
|
if (!beginRoot) return -1;
|
|
1073
1070
|
|
|
1074
|
-
if (iterationType ===
|
|
1071
|
+
if (iterationType === 'RECURSIVE') {
|
|
1075
1072
|
const _getMinHeight = (cur: NODE | null | undefined): number => {
|
|
1076
1073
|
if (!this.isRealNode(cur)) return 0;
|
|
1077
1074
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return 0;
|
|
@@ -1174,7 +1171,7 @@ export class BinaryTree<
|
|
|
1174
1171
|
|
|
1175
1172
|
if (!this.isRealNode(beginRoot)) return beginRoot;
|
|
1176
1173
|
|
|
1177
|
-
if (iterationType ===
|
|
1174
|
+
if (iterationType === 'RECURSIVE') {
|
|
1178
1175
|
const _traverse = (cur: NODE): NODE => {
|
|
1179
1176
|
if (!this.isRealNode(cur.left)) return cur;
|
|
1180
1177
|
return _traverse(cur.left);
|
|
@@ -1221,7 +1218,7 @@ export class BinaryTree<
|
|
|
1221
1218
|
beginRoot = this.ensureNode(beginRoot);
|
|
1222
1219
|
if (!beginRoot) return beginRoot;
|
|
1223
1220
|
|
|
1224
|
-
if (iterationType ===
|
|
1221
|
+
if (iterationType === 'RECURSIVE') {
|
|
1225
1222
|
const _traverse = (cur: NODE): NODE => {
|
|
1226
1223
|
if (!this.isRealNode(cur.right)) return cur;
|
|
1227
1224
|
return _traverse(cur.right);
|
|
@@ -1345,13 +1342,13 @@ export class BinaryTree<
|
|
|
1345
1342
|
callback: C = this._defaultOneParamCallback as C,
|
|
1346
1343
|
pattern: DFSOrderPattern = 'in',
|
|
1347
1344
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
1348
|
-
iterationType: IterationType =
|
|
1345
|
+
iterationType: IterationType = 'ITERATIVE',
|
|
1349
1346
|
includeNull = false
|
|
1350
1347
|
): ReturnType<C>[] {
|
|
1351
1348
|
beginRoot = this.ensureNode(beginRoot);
|
|
1352
1349
|
if (!beginRoot) return [];
|
|
1353
1350
|
const ans: ReturnType<C>[] = [];
|
|
1354
|
-
if (iterationType ===
|
|
1351
|
+
if (iterationType === 'RECURSIVE') {
|
|
1355
1352
|
const _traverse = (node: NODE | null | undefined) => {
|
|
1356
1353
|
switch (pattern) {
|
|
1357
1354
|
case 'in':
|
|
@@ -1487,7 +1484,7 @@ export class BinaryTree<
|
|
|
1487
1484
|
|
|
1488
1485
|
const ans: ReturnType<BTNCallback<NODE>>[] = [];
|
|
1489
1486
|
|
|
1490
|
-
if (iterationType ===
|
|
1487
|
+
if (iterationType === 'RECURSIVE') {
|
|
1491
1488
|
const queue: Queue<NODE | null | undefined> = new Queue<NODE | null | undefined>([beginRoot]);
|
|
1492
1489
|
|
|
1493
1490
|
const traverse = (level: number) => {
|
|
@@ -1580,7 +1577,7 @@ export class BinaryTree<
|
|
|
1580
1577
|
const levelsNodes: ReturnType<C>[][] = [];
|
|
1581
1578
|
if (!beginRoot) return levelsNodes;
|
|
1582
1579
|
|
|
1583
|
-
if (iterationType ===
|
|
1580
|
+
if (iterationType === 'RECURSIVE') {
|
|
1584
1581
|
const _recursive = (node: NODE | null, level: number) => {
|
|
1585
1582
|
if (!levelsNodes[level]) levelsNodes[level] = [];
|
|
1586
1583
|
levelsNodes[level].push(callback(node));
|
|
@@ -1876,7 +1873,7 @@ export class BinaryTree<
|
|
|
1876
1873
|
protected* _getIterator(node = this.root): IterableIterator<[K, V | undefined]> {
|
|
1877
1874
|
if (!node) return;
|
|
1878
1875
|
|
|
1879
|
-
if (this.iterationType ===
|
|
1876
|
+
if (this.iterationType === 'ITERATIVE') {
|
|
1880
1877
|
const stack: (NODE | null | undefined)[] = [];
|
|
1881
1878
|
let current: NODE | null | undefined = node;
|
|
1882
1879
|
|
|
@@ -126,7 +126,7 @@ export class BST<
|
|
|
126
126
|
return this._root;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
protected _variant =
|
|
129
|
+
protected _variant: BSTVariant = 'STANDARD';
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
132
|
* The function returns the value of the _variant property.
|
|
@@ -207,13 +207,10 @@ export class BST<
|
|
|
207
207
|
* @param {K | NODE | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `NODE`, or
|
|
208
208
|
* `undefined`.
|
|
209
209
|
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
|
|
210
|
-
* type of iteration to be performed. It has a default value of `
|
|
210
|
+
* type of iteration to be performed. It has a default value of `'ITERATIVE'`.
|
|
211
211
|
* @returns either a node object (NODE) or undefined.
|
|
212
212
|
*/
|
|
213
|
-
override ensureNode(
|
|
214
|
-
keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
|
|
215
|
-
iterationType = IterationType.ITERATIVE
|
|
216
|
-
): NODE | undefined {
|
|
213
|
+
override ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, iterationType = 'ITERATIVE'): NODE | undefined {
|
|
217
214
|
let res: NODE | undefined;
|
|
218
215
|
if (this.isRealNode(keyOrNodeOrEntry)) {
|
|
219
216
|
res = keyOrNodeOrEntry;
|
|
@@ -263,7 +260,7 @@ export class BST<
|
|
|
263
260
|
|
|
264
261
|
let current = this.root;
|
|
265
262
|
while (current !== undefined) {
|
|
266
|
-
if (this._compare(current.key, newNode.key) ===
|
|
263
|
+
if (this._compare(current.key, newNode.key) === 'EQ') {
|
|
267
264
|
// if (current !== newNode) {
|
|
268
265
|
// The key value is the same but the reference is different, update the value of the existing node
|
|
269
266
|
this._replaceNode(current, newNode);
|
|
@@ -275,7 +272,7 @@ export class BST<
|
|
|
275
272
|
|
|
276
273
|
// return;
|
|
277
274
|
// }
|
|
278
|
-
} else if (this._compare(current.key, newNode.key) ===
|
|
275
|
+
} else if (this._compare(current.key, newNode.key) === 'GT') {
|
|
279
276
|
if (current.left === undefined) {
|
|
280
277
|
current.left = newNode;
|
|
281
278
|
this._size++;
|
|
@@ -397,7 +394,7 @@ export class BST<
|
|
|
397
394
|
}
|
|
398
395
|
};
|
|
399
396
|
|
|
400
|
-
if (iterationType ===
|
|
397
|
+
if (iterationType === 'RECURSIVE') {
|
|
401
398
|
_dfs(sorted);
|
|
402
399
|
} else {
|
|
403
400
|
_iterate();
|
|
@@ -425,15 +422,15 @@ export class BST<
|
|
|
425
422
|
* @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is
|
|
426
423
|
* found in the binary tree. If no node is found, it returns `undefined`.
|
|
427
424
|
*/
|
|
428
|
-
override getNodeByKey(key: K, iterationType =
|
|
425
|
+
override getNodeByKey(key: K, iterationType = 'ITERATIVE'): NODE | undefined {
|
|
429
426
|
if (!this.isRealNode(this.root)) return undefined;
|
|
430
|
-
if (iterationType ===
|
|
427
|
+
if (iterationType === 'RECURSIVE') {
|
|
431
428
|
const _dfs = (cur: NODE): NODE | undefined => {
|
|
432
429
|
if (cur.key === key) return cur;
|
|
433
430
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
|
|
434
431
|
|
|
435
|
-
if (this._compare(cur.key, key) ===
|
|
436
|
-
if (this._compare(cur.key, key) ===
|
|
432
|
+
if (this._compare(cur.key, key) === 'GT' && this.isRealNode(cur.left)) return _dfs(cur.left);
|
|
433
|
+
if (this._compare(cur.key, key) === 'LT' && this.isRealNode(cur.right)) return _dfs(cur.right);
|
|
437
434
|
};
|
|
438
435
|
|
|
439
436
|
return _dfs(this.root);
|
|
@@ -442,9 +439,9 @@ export class BST<
|
|
|
442
439
|
while (queue.size > 0) {
|
|
443
440
|
const cur = queue.shift();
|
|
444
441
|
if (this.isRealNode(cur)) {
|
|
445
|
-
if (this._compare(cur.key, key) ===
|
|
446
|
-
if (this._compare(cur.key, key) ===
|
|
447
|
-
if (this._compare(cur.key, key) ===
|
|
442
|
+
if (this._compare(cur.key, key) === 'EQ') return cur;
|
|
443
|
+
if (this._compare(cur.key, key) === 'GT') this.isRealNode(cur.left) && queue.push(cur.left);
|
|
444
|
+
if (this._compare(cur.key, key) === 'LT') this.isRealNode(cur.right) && queue.push(cur.right);
|
|
448
445
|
}
|
|
449
446
|
}
|
|
450
447
|
}
|
|
@@ -489,7 +486,7 @@ export class BST<
|
|
|
489
486
|
if (!beginRoot) return [];
|
|
490
487
|
const ans: NODE[] = [];
|
|
491
488
|
|
|
492
|
-
if (iterationType ===
|
|
489
|
+
if (iterationType === 'RECURSIVE') {
|
|
493
490
|
const _traverse = (cur: NODE) => {
|
|
494
491
|
const callbackResult = callback(cur);
|
|
495
492
|
if (callbackResult === identifier) {
|
|
@@ -500,8 +497,8 @@ export class BST<
|
|
|
500
497
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
|
|
501
498
|
// TODO potential bug
|
|
502
499
|
if (callback === this._defaultOneParamCallback) {
|
|
503
|
-
if (this._compare(cur.key, identifier as K) ===
|
|
504
|
-
if (this._compare(cur.key, identifier as K) ===
|
|
500
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') _traverse(cur.left);
|
|
501
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') _traverse(cur.right);
|
|
505
502
|
} else {
|
|
506
503
|
this.isRealNode(cur.left) && _traverse(cur.left);
|
|
507
504
|
this.isRealNode(cur.right) && _traverse(cur.right);
|
|
@@ -510,9 +507,9 @@ export class BST<
|
|
|
510
507
|
|
|
511
508
|
_traverse(beginRoot);
|
|
512
509
|
} else {
|
|
513
|
-
const
|
|
514
|
-
while (
|
|
515
|
-
const cur =
|
|
510
|
+
const stack = [beginRoot];
|
|
511
|
+
while (stack.length > 0) {
|
|
512
|
+
const cur = stack.pop();
|
|
516
513
|
if (this.isRealNode(cur)) {
|
|
517
514
|
const callbackResult = callback(cur);
|
|
518
515
|
if (callbackResult === identifier) {
|
|
@@ -521,11 +518,19 @@ export class BST<
|
|
|
521
518
|
}
|
|
522
519
|
// TODO potential bug
|
|
523
520
|
if (callback === this._defaultOneParamCallback) {
|
|
524
|
-
if (this._compare(cur.key, identifier as K) ===
|
|
525
|
-
if (this._compare(cur.key, identifier as K) ===
|
|
521
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') stack.push(cur.right);
|
|
522
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') stack.push(cur.left);
|
|
523
|
+
|
|
524
|
+
// if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
|
|
525
|
+
// if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
|
|
526
|
+
|
|
527
|
+
// // @ts-ignore
|
|
528
|
+
// if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right);
|
|
529
|
+
// // @ts-ignore
|
|
530
|
+
// if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left);
|
|
526
531
|
} else {
|
|
527
|
-
this.isRealNode(cur.
|
|
528
|
-
this.isRealNode(cur.
|
|
532
|
+
this.isRealNode(cur.right) && stack.push(cur.right);
|
|
533
|
+
this.isRealNode(cur.left) && stack.push(cur.left);
|
|
529
534
|
}
|
|
530
535
|
}
|
|
531
536
|
}
|
|
@@ -562,7 +567,7 @@ export class BST<
|
|
|
562
567
|
callback: C = this._defaultOneParamCallback as C,
|
|
563
568
|
pattern: DFSOrderPattern = 'in',
|
|
564
569
|
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
565
|
-
iterationType: IterationType =
|
|
570
|
+
iterationType: IterationType = 'ITERATIVE'
|
|
566
571
|
): ReturnType<C>[] {
|
|
567
572
|
return super.dfs(callback, pattern, beginRoot, iterationType, false);
|
|
568
573
|
}
|
|
@@ -650,7 +655,7 @@ export class BST<
|
|
|
650
655
|
let current = this.ensureNode(beginRoot);
|
|
651
656
|
if (!current) return undefined;
|
|
652
657
|
|
|
653
|
-
if (this._variant ===
|
|
658
|
+
if (this._variant === 'STANDARD') {
|
|
654
659
|
// For BSTVariant.MIN, find the rightmost node
|
|
655
660
|
while (current.right !== undefined) {
|
|
656
661
|
current = current.right;
|
|
@@ -692,7 +697,7 @@ export class BST<
|
|
|
692
697
|
*/
|
|
693
698
|
lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(
|
|
694
699
|
callback: C = this._defaultOneParamCallback as C,
|
|
695
|
-
lesserOrGreater: CP =
|
|
700
|
+
lesserOrGreater: CP = 'LT',
|
|
696
701
|
targetNode: KeyOrNodeOrEntry<K, V, NODE> = this.root,
|
|
697
702
|
iterationType = this.iterationType
|
|
698
703
|
): ReturnType<C>[] {
|
|
@@ -703,7 +708,7 @@ export class BST<
|
|
|
703
708
|
|
|
704
709
|
const targetKey = targetNode.key;
|
|
705
710
|
|
|
706
|
-
if (iterationType ===
|
|
711
|
+
if (iterationType === 'RECURSIVE') {
|
|
707
712
|
const _traverse = (cur: NODE) => {
|
|
708
713
|
const compared = this._compare(cur.key, targetKey);
|
|
709
714
|
if (compared === lesserOrGreater) ans.push(callback(cur));
|
|
@@ -752,7 +757,7 @@ export class BST<
|
|
|
752
757
|
this.clear();
|
|
753
758
|
|
|
754
759
|
if (sorted.length < 1) return false;
|
|
755
|
-
if (iterationType ===
|
|
760
|
+
if (iterationType === 'RECURSIVE') {
|
|
756
761
|
const buildBalanceBST = (l: number, r: number) => {
|
|
757
762
|
if (l > r) return;
|
|
758
763
|
const m = l + Math.floor((r - l) / 2);
|
|
@@ -812,7 +817,7 @@ export class BST<
|
|
|
812
817
|
|
|
813
818
|
let balanced = true;
|
|
814
819
|
|
|
815
|
-
if (iterationType ===
|
|
820
|
+
if (iterationType === 'RECURSIVE') {
|
|
816
821
|
const _height = (cur: NODE | undefined): number => {
|
|
817
822
|
if (!cur) return 0;
|
|
818
823
|
const leftHeight = _height(cur.left),
|
|
@@ -868,14 +873,32 @@ export class BST<
|
|
|
868
873
|
* is greater than, less than, or equal to the second value.
|
|
869
874
|
* @param {K} a - The parameter "a" is of type K.
|
|
870
875
|
* @param {K} b - The parameter "b" in the above code represents a K.
|
|
871
|
-
* @returns a value of type CP (ComparisonResult). The possible return values are
|
|
872
|
-
* than),
|
|
876
|
+
* @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater
|
|
877
|
+
* than), 'LT' (less than), or 'EQ' (equal).
|
|
873
878
|
*/
|
|
874
879
|
protected _compare(a: K, b: K): CP {
|
|
875
880
|
const extractedA = this.extractor(a);
|
|
876
881
|
const extractedB = this.extractor(b);
|
|
877
|
-
const compared = this.variant ===
|
|
882
|
+
const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA;
|
|
883
|
+
|
|
884
|
+
return compared > 0 ? 'GT' : compared < 0 ? 'LT' : 'EQ';
|
|
885
|
+
}
|
|
878
886
|
|
|
879
|
-
|
|
887
|
+
protected _lt(a: K, b: K): boolean {
|
|
888
|
+
const extractedA = this.extractor(a);
|
|
889
|
+
const extractedB = this.extractor(b);
|
|
890
|
+
// return this.variant === BSTVariant.STANDARD ? extractedA < extractedB : extractedA > extractedB;
|
|
891
|
+
return this.variant === 'STANDARD' ? extractedA < extractedB : extractedA > extractedB;
|
|
892
|
+
// return extractedA < extractedB;
|
|
893
|
+
// return a < b;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
protected _gt(a: K, b: K): boolean {
|
|
897
|
+
const extractedA = this.extractor(a);
|
|
898
|
+
const extractedB = this.extractor(b);
|
|
899
|
+
// return this.variant === BSTVariant.STANDARD ? extractedA > extractedB : extractedA < extractedB;
|
|
900
|
+
return this.variant === 'STANDARD' ? extractedA > extractedB : extractedA < extractedB;
|
|
901
|
+
// return extractedA > extractedB;
|
|
902
|
+
// return a > b;
|
|
880
903
|
}
|
|
881
904
|
}
|
|
@@ -234,8 +234,8 @@ export class RedBlackTree<
|
|
|
234
234
|
beginRoot: BSTNKeyOrNode<K, NODE> = this.root,
|
|
235
235
|
iterationType = this.iterationType
|
|
236
236
|
): NODE | null | undefined {
|
|
237
|
-
if ((identifier as any) instanceof RedBlackTreeNode) callback = (node => node) as C;
|
|
238
|
-
return
|
|
237
|
+
// if ((identifier as any) instanceof RedBlackTreeNode) callback = (node => node) as C;
|
|
238
|
+
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
/**
|
|
@@ -279,7 +279,7 @@ export class RedBlackTree<
|
|
|
279
279
|
|
|
280
280
|
const insertStatus = this._insert(newNode);
|
|
281
281
|
|
|
282
|
-
if (insertStatus ===
|
|
282
|
+
if (insertStatus === 'CREATED') {
|
|
283
283
|
// Ensure the root is black
|
|
284
284
|
if (this.isRealNode(this._root)) {
|
|
285
285
|
this._root.color = RBTNColor.BLACK;
|
|
@@ -288,7 +288,7 @@ export class RedBlackTree<
|
|
|
288
288
|
}
|
|
289
289
|
this._size++;
|
|
290
290
|
return true;
|
|
291
|
-
} else return insertStatus ===
|
|
291
|
+
} else return insertStatus === 'UPDATED';
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
/**
|
|
@@ -435,7 +435,7 @@ export class RedBlackTree<
|
|
|
435
435
|
current = current.right ?? this.SENTINEL;
|
|
436
436
|
} else {
|
|
437
437
|
this._replaceNode(current, node);
|
|
438
|
-
return
|
|
438
|
+
return 'UPDATED';
|
|
439
439
|
}
|
|
440
440
|
}
|
|
441
441
|
|
|
@@ -454,7 +454,7 @@ export class RedBlackTree<
|
|
|
454
454
|
node.color = RBTNColor.RED;
|
|
455
455
|
|
|
456
456
|
this._insertFixup(node);
|
|
457
|
-
return
|
|
457
|
+
return 'CREATED';
|
|
458
458
|
}
|
|
459
459
|
|
|
460
460
|
/**
|
|
@@ -14,7 +14,7 @@ import type {
|
|
|
14
14
|
TreeMultiMapNodeNested,
|
|
15
15
|
TreeMultiMapOptions
|
|
16
16
|
} from '../../types';
|
|
17
|
-
import {
|
|
17
|
+
import { RBTNColor } from '../../types';
|
|
18
18
|
import { IBinaryTree } from '../../interfaces';
|
|
19
19
|
import { RedBlackTree, RedBlackTreeNode } from './rb-tree';
|
|
20
20
|
|
|
@@ -363,7 +363,7 @@ export class TreeMultiMap<
|
|
|
363
363
|
|
|
364
364
|
this.clear();
|
|
365
365
|
|
|
366
|
-
if (iterationType ===
|
|
366
|
+
if (iterationType === 'RECURSIVE') {
|
|
367
367
|
const buildBalanceBST = (l: number, r: number) => {
|
|
368
368
|
if (l > r) return;
|
|
369
369
|
const m = l + Math.floor((r - l) / 2);
|
package/src/types/common.ts
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
INVERSE = 'INVERSE'
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export enum CP {
|
|
7
|
-
lt = 'lt',
|
|
8
|
-
eq = 'eq',
|
|
9
|
-
gt = 'gt'
|
|
10
|
-
}
|
|
1
|
+
export type BSTVariant = 'STANDARD' | 'INVERSE';
|
|
2
|
+
export type CP = 'LT' | 'EQ' | 'GT';
|
|
11
3
|
|
|
12
4
|
/**
|
|
13
5
|
* Enum representing different loop types.
|
|
@@ -15,20 +7,9 @@ export enum CP {
|
|
|
15
7
|
* - `iterative`: Indicates the iterative loop type (with loops that use iterations).
|
|
16
8
|
* - `recursive`: Indicates the recursive loop type (with loops that call themselves).
|
|
17
9
|
*/
|
|
18
|
-
export
|
|
19
|
-
ITERATIVE = 'ITERATIVE',
|
|
20
|
-
RECURSIVE = 'RECURSIVE'
|
|
21
|
-
}
|
|
10
|
+
export type IterationType = 'ITERATIVE' | 'RECURSIVE';
|
|
22
11
|
|
|
23
|
-
export
|
|
24
|
-
ROOT = 'ROOT',
|
|
25
|
-
LEFT = 'LEFT',
|
|
26
|
-
RIGHT = 'RIGHT',
|
|
27
|
-
ROOT_LEFT = 'ROOT_LEFT',
|
|
28
|
-
ROOT_RIGHT = 'ROOT_RIGHT',
|
|
29
|
-
ISOLATED = 'ISOLATED',
|
|
30
|
-
MAL_NODE = 'MAL_NODE'
|
|
31
|
-
}
|
|
12
|
+
export type FamilyPosition = 'ROOT' | 'LEFT' | 'RIGHT' | 'ROOT_LEFT' | 'ROOT_RIGHT' | 'ISOLATED' | 'MAL_NODE';
|
|
32
13
|
|
|
33
14
|
export type Comparator<K> = (a: K, b: K) => number;
|
|
34
15
|
|
|
@@ -64,9 +45,4 @@ export type BSTNKeyOrNode<K, N> = K | undefined | N;
|
|
|
64
45
|
|
|
65
46
|
export type BinaryTreeDeleteResult<N> = { deleted: N | null | undefined; needBalanced: N | null | undefined };
|
|
66
47
|
|
|
67
|
-
export
|
|
68
|
-
CREATED = 'CREATED',
|
|
69
|
-
READ = 'READ',
|
|
70
|
-
UPDATED = 'UPDATED',
|
|
71
|
-
DELETED = 'DELETED'
|
|
72
|
-
}
|
|
48
|
+
export type CRUD = 'CREATED' | 'READ' | 'UPDATED' | 'DELETED';
|