min-heap-typed 1.50.7 → 1.50.9
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 +14 -3
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +17 -6
- package/dist/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/data-structures/binary-tree/binary-tree.js +33 -34
- package/dist/data-structures/binary-tree/bst.d.ts +22 -3
- package/dist/data-structures/binary-tree/bst.js +78 -39
- package/dist/data-structures/binary-tree/rb-tree.d.ts +5 -5
- package/dist/data-structures/binary-tree/rb-tree.js +47 -50
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +40 -23
- package/dist/data-structures/binary-tree/tree-multi-map.js +44 -28
- package/dist/data-structures/heap/heap.d.ts +1 -1
- package/dist/data-structures/heap/heap.js +5 -5
- package/dist/types/common.d.ts +6 -29
- package/dist/types/common.js +0 -40
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +1 -4
- package/dist/types/data-structures/binary-tree/rb-tree.js +0 -6
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +20 -7
- package/src/data-structures/binary-tree/binary-tree.ts +54 -45
- package/src/data-structures/binary-tree/bst.ts +86 -42
- package/src/data-structures/binary-tree/rb-tree.ts +49 -49
- package/src/data-structures/binary-tree/tree-multi-map.ts +48 -29
- package/src/data-structures/heap/heap.ts +5 -5
- package/src/types/common.ts +6 -30
- package/src/types/data-structures/binary-tree/rb-tree.ts +1 -1
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import type { AVLTreeMultiMapNested, AVLTreeMultiMapNodeNested, AVLTreeMultiMapOptions, BinaryTreeDeleteResult, BSTNKeyOrNode, BTNCallback, KeyOrNodeOrEntry } from '../../types';
|
|
9
|
-
import { IterationType } from '../../types';
|
|
8
|
+
import type { AVLTreeMultiMapNested, AVLTreeMultiMapNodeNested, AVLTreeMultiMapOptions, BinaryTreeDeleteResult, BSTNKeyOrNode, BTNCallback, IterationType, KeyOrNodeOrEntry } 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> {
|
|
@@ -46,7 +45,19 @@ export declare class AVLTreeMultiMap<K = any, V = any, NODE extends AVLTreeMulti
|
|
|
46
45
|
* @returns the sum of the count property of all nodes in the tree.
|
|
47
46
|
*/
|
|
48
47
|
get count(): number;
|
|
49
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Time Complexity: O(n)
|
|
50
|
+
* Space Complexity: O(1)
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* Time Complexity: O(n)
|
|
54
|
+
* Space Complexity: O(1)
|
|
55
|
+
*
|
|
56
|
+
* The function calculates the sum of the count property of all nodes in a tree using depth-first
|
|
57
|
+
* search.
|
|
58
|
+
* @returns the sum of the count property of all nodes in the tree.
|
|
59
|
+
*/
|
|
60
|
+
getComputedCount(): number;
|
|
50
61
|
/**
|
|
51
62
|
* The function creates a new BSTNode with the given key, value, and count.
|
|
52
63
|
* @param {K} key - The key parameter is the unique identifier for the binary tree node. It is used to
|
|
@@ -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
|
/**
|
|
@@ -55,7 +54,19 @@ class AVLTreeMultiMap extends avl_tree_1.AVLTree {
|
|
|
55
54
|
get count() {
|
|
56
55
|
return this._count;
|
|
57
56
|
}
|
|
58
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Time Complexity: O(n)
|
|
59
|
+
* Space Complexity: O(1)
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* Time Complexity: O(n)
|
|
63
|
+
* Space Complexity: O(1)
|
|
64
|
+
*
|
|
65
|
+
* The function calculates the sum of the count property of all nodes in a tree using depth-first
|
|
66
|
+
* search.
|
|
67
|
+
* @returns the sum of the count property of all nodes in the tree.
|
|
68
|
+
*/
|
|
69
|
+
getComputedCount() {
|
|
59
70
|
let sum = 0;
|
|
60
71
|
this.dfs(node => (sum += node.count));
|
|
61
72
|
return sum;
|
|
@@ -205,10 +216,10 @@ class AVLTreeMultiMap extends avl_tree_1.AVLTree {
|
|
|
205
216
|
}
|
|
206
217
|
else {
|
|
207
218
|
const { familyPosition: fp } = curr;
|
|
208
|
-
if (fp ===
|
|
219
|
+
if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
|
|
209
220
|
parent.left = curr.right;
|
|
210
221
|
}
|
|
211
|
-
else if (fp ===
|
|
222
|
+
else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {
|
|
212
223
|
parent.right = curr.right;
|
|
213
224
|
}
|
|
214
225
|
needBalanced = parent;
|
|
@@ -271,11 +282,11 @@ class AVLTreeMultiMap extends avl_tree_1.AVLTree {
|
|
|
271
282
|
* @returns a boolean value.
|
|
272
283
|
*/
|
|
273
284
|
perfectlyBalance(iterationType = this.iterationType) {
|
|
274
|
-
const sorted = this.dfs(node => node, '
|
|
285
|
+
const sorted = this.dfs(node => node, 'IN'), n = sorted.length;
|
|
275
286
|
if (sorted.length < 1)
|
|
276
287
|
return false;
|
|
277
288
|
this.clear();
|
|
278
|
-
if (iterationType ===
|
|
289
|
+
if (iterationType === 'RECURSIVE') {
|
|
279
290
|
const buildBalanceBST = (l, r) => {
|
|
280
291
|
if (l > r)
|
|
281
292
|
return;
|
|
@@ -135,7 +135,7 @@ 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
|
*/
|
|
@@ -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,15 +1110,15 @@ 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 = '
|
|
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
|
-
case '
|
|
1121
|
+
case 'IN':
|
|
1123
1122
|
if (includeNull) {
|
|
1124
1123
|
if (this.isRealNode(node) && this.isNodeOrNull(node.left))
|
|
1125
1124
|
_traverse(node.left);
|
|
@@ -1135,7 +1134,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1135
1134
|
_traverse(node.right);
|
|
1136
1135
|
}
|
|
1137
1136
|
break;
|
|
1138
|
-
case '
|
|
1137
|
+
case 'PRE':
|
|
1139
1138
|
if (includeNull) {
|
|
1140
1139
|
this.isNodeOrNull(node) && ans.push(callback(node));
|
|
1141
1140
|
if (this.isRealNode(node) && this.isNodeOrNull(node.left))
|
|
@@ -1151,7 +1150,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1151
1150
|
_traverse(node.right);
|
|
1152
1151
|
}
|
|
1153
1152
|
break;
|
|
1154
|
-
case '
|
|
1153
|
+
case 'POST':
|
|
1155
1154
|
if (includeNull) {
|
|
1156
1155
|
if (this.isRealNode(node) && this.isNodeOrNull(node.left))
|
|
1157
1156
|
_traverse(node.left);
|
|
@@ -1191,17 +1190,17 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1191
1190
|
}
|
|
1192
1191
|
else {
|
|
1193
1192
|
switch (pattern) {
|
|
1194
|
-
case '
|
|
1193
|
+
case 'IN':
|
|
1195
1194
|
cur.node && stack.push({ opt: 0, node: cur.node.right });
|
|
1196
1195
|
stack.push({ opt: 1, node: cur.node });
|
|
1197
1196
|
cur.node && stack.push({ opt: 0, node: cur.node.left });
|
|
1198
1197
|
break;
|
|
1199
|
-
case '
|
|
1198
|
+
case 'PRE':
|
|
1200
1199
|
cur.node && stack.push({ opt: 0, node: cur.node.right });
|
|
1201
1200
|
cur.node && stack.push({ opt: 0, node: cur.node.left });
|
|
1202
1201
|
stack.push({ opt: 1, node: cur.node });
|
|
1203
1202
|
break;
|
|
1204
|
-
case '
|
|
1203
|
+
case 'POST':
|
|
1205
1204
|
stack.push({ opt: 1, node: cur.node });
|
|
1206
1205
|
cur.node && stack.push({ opt: 0, node: cur.node.right });
|
|
1207
1206
|
cur.node && stack.push({ opt: 0, node: cur.node.left });
|
|
@@ -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] = [];
|
|
@@ -1391,7 +1390,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1391
1390
|
* `callback` function on each node in the binary tree. The type of the array nodes is determined
|
|
1392
1391
|
* by the return type of the `callback` function.
|
|
1393
1392
|
*/
|
|
1394
|
-
morris(callback = this._defaultOneParamCallback, pattern = '
|
|
1393
|
+
morris(callback = this._defaultOneParamCallback, pattern = 'IN', beginRoot = this.root) {
|
|
1395
1394
|
beginRoot = this.ensureNode(beginRoot);
|
|
1396
1395
|
if (beginRoot === null)
|
|
1397
1396
|
return [];
|
|
@@ -1418,7 +1417,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1418
1417
|
_reverseEdge(tail);
|
|
1419
1418
|
};
|
|
1420
1419
|
switch (pattern) {
|
|
1421
|
-
case '
|
|
1420
|
+
case 'IN':
|
|
1422
1421
|
while (cur) {
|
|
1423
1422
|
if (cur.left) {
|
|
1424
1423
|
const predecessor = this.getPredecessor(cur);
|
|
@@ -1435,7 +1434,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1435
1434
|
cur = cur.right;
|
|
1436
1435
|
}
|
|
1437
1436
|
break;
|
|
1438
|
-
case '
|
|
1437
|
+
case 'PRE':
|
|
1439
1438
|
while (cur) {
|
|
1440
1439
|
if (cur.left) {
|
|
1441
1440
|
const predecessor = this.getPredecessor(cur);
|
|
@@ -1455,7 +1454,7 @@ class BinaryTree extends base_1.IterableEntryBase {
|
|
|
1455
1454
|
cur = cur.right;
|
|
1456
1455
|
}
|
|
1457
1456
|
break;
|
|
1458
|
-
case '
|
|
1457
|
+
case 'POST':
|
|
1459
1458
|
while (cur) {
|
|
1460
1459
|
if (cur.left) {
|
|
1461
1460
|
const predecessor = this.getPredecessor(cur);
|
|
@@ -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,7 +109,7 @@ 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
115
|
ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>, iterationType?: IterationType): NODE | undefined;
|
|
@@ -372,8 +372,27 @@ 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
|
+
/**
|
|
380
|
+
* The function `_lt` compares two values `a` and `b` using an extractor function and returns true if
|
|
381
|
+
* `a` is less than `b` based on the specified variant.
|
|
382
|
+
* @param {K} a - The parameter "a" is of type "K", which means it can be any type. It represents the
|
|
383
|
+
* first value to be compared in the function.
|
|
384
|
+
* @param {K} b - The parameter `b` is of type `K`, which means it can be any type. It is used as one
|
|
385
|
+
* of the arguments for the comparison in the `_lt` function.
|
|
386
|
+
* @returns a boolean value.
|
|
387
|
+
*/
|
|
388
|
+
protected _lt(a: K, b: K): boolean;
|
|
389
|
+
/**
|
|
390
|
+
* The function compares two values using a custom extractor function and returns true if the first
|
|
391
|
+
* value is greater than the second value.
|
|
392
|
+
* @param {K} a - The parameter "a" is of type K, which means it can be any type.
|
|
393
|
+
* @param {K} b - The parameter "b" is of type K, which means it can be any type. It is used as one
|
|
394
|
+
* of the arguments for the comparison in the function.
|
|
395
|
+
* @returns a boolean value.
|
|
396
|
+
*/
|
|
397
|
+
protected _gt(a: K, b: K): boolean;
|
|
379
398
|
}
|
|
@@ -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,19 @@ 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') {
|
|
364
|
+
// return this.getNodes(key, this._defaultOneParamCallback, true, this.root, iterationType)[0];
|
|
365
365
|
if (!this.isRealNode(this.root))
|
|
366
366
|
return undefined;
|
|
367
|
-
if (iterationType ===
|
|
367
|
+
if (iterationType === 'RECURSIVE') {
|
|
368
368
|
const _dfs = (cur) => {
|
|
369
369
|
if (cur.key === key)
|
|
370
370
|
return cur;
|
|
371
371
|
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right))
|
|
372
372
|
return;
|
|
373
|
-
if (this._compare(cur.key, key) ===
|
|
373
|
+
if (this._compare(cur.key, key) === 'GT' && this.isRealNode(cur.left))
|
|
374
374
|
return _dfs(cur.left);
|
|
375
|
-
if (this._compare(cur.key, key) ===
|
|
375
|
+
if (this._compare(cur.key, key) === 'LT' && this.isRealNode(cur.right))
|
|
376
376
|
return _dfs(cur.right);
|
|
377
377
|
};
|
|
378
378
|
return _dfs(this.root);
|
|
@@ -382,11 +382,11 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
382
382
|
while (queue.size > 0) {
|
|
383
383
|
const cur = queue.shift();
|
|
384
384
|
if (this.isRealNode(cur)) {
|
|
385
|
-
if (this._compare(cur.key, key) ===
|
|
385
|
+
if (this._compare(cur.key, key) === 'EQ')
|
|
386
386
|
return cur;
|
|
387
|
-
if (this._compare(cur.key, key) ===
|
|
387
|
+
if (this._compare(cur.key, key) === 'GT')
|
|
388
388
|
this.isRealNode(cur.left) && queue.push(cur.left);
|
|
389
|
-
if (this._compare(cur.key, key) ===
|
|
389
|
+
if (this._compare(cur.key, key) === 'LT')
|
|
390
390
|
this.isRealNode(cur.right) && queue.push(cur.right);
|
|
391
391
|
}
|
|
392
392
|
}
|
|
@@ -425,7 +425,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
425
425
|
if (!beginRoot)
|
|
426
426
|
return [];
|
|
427
427
|
const ans = [];
|
|
428
|
-
if (iterationType ===
|
|
428
|
+
if (iterationType === 'RECURSIVE') {
|
|
429
429
|
const _traverse = (cur) => {
|
|
430
430
|
const callbackResult = callback(cur);
|
|
431
431
|
if (callbackResult === identifier) {
|
|
@@ -437,10 +437,10 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
437
437
|
return;
|
|
438
438
|
// TODO potential bug
|
|
439
439
|
if (callback === this._defaultOneParamCallback) {
|
|
440
|
-
if (this._compare(cur.key, identifier) ===
|
|
441
|
-
|
|
442
|
-
if (this._compare(cur.key, identifier) ===
|
|
443
|
-
|
|
440
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier) === 'GT')
|
|
441
|
+
_traverse(cur.left);
|
|
442
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier) === 'LT')
|
|
443
|
+
_traverse(cur.right);
|
|
444
444
|
}
|
|
445
445
|
else {
|
|
446
446
|
this.isRealNode(cur.left) && _traverse(cur.left);
|
|
@@ -450,9 +450,9 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
450
450
|
_traverse(beginRoot);
|
|
451
451
|
}
|
|
452
452
|
else {
|
|
453
|
-
const
|
|
454
|
-
while (
|
|
455
|
-
const cur =
|
|
453
|
+
const stack = [beginRoot];
|
|
454
|
+
while (stack.length > 0) {
|
|
455
|
+
const cur = stack.pop();
|
|
456
456
|
if (this.isRealNode(cur)) {
|
|
457
457
|
const callbackResult = callback(cur);
|
|
458
458
|
if (callbackResult === identifier) {
|
|
@@ -462,14 +462,20 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
462
462
|
}
|
|
463
463
|
// TODO potential bug
|
|
464
464
|
if (callback === this._defaultOneParamCallback) {
|
|
465
|
-
if (this._compare(cur.key, identifier) ===
|
|
466
|
-
|
|
467
|
-
if (this._compare(cur.key, identifier) ===
|
|
468
|
-
|
|
465
|
+
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier) === 'LT')
|
|
466
|
+
stack.push(cur.right);
|
|
467
|
+
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier) === 'GT')
|
|
468
|
+
stack.push(cur.left);
|
|
469
|
+
// if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
|
|
470
|
+
// if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
|
|
471
|
+
// // @ts-ignore
|
|
472
|
+
// if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right);
|
|
473
|
+
// // @ts-ignore
|
|
474
|
+
// if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left);
|
|
469
475
|
}
|
|
470
476
|
else {
|
|
471
|
-
this.isRealNode(cur.
|
|
472
|
-
this.isRealNode(cur.
|
|
477
|
+
this.isRealNode(cur.right) && stack.push(cur.right);
|
|
478
|
+
this.isRealNode(cur.left) && stack.push(cur.left);
|
|
473
479
|
}
|
|
474
480
|
}
|
|
475
481
|
}
|
|
@@ -499,7 +505,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
499
505
|
* following values:
|
|
500
506
|
* @returns The method is returning an array of the return type of the callback function.
|
|
501
507
|
*/
|
|
502
|
-
dfs(callback = this._defaultOneParamCallback, pattern = '
|
|
508
|
+
dfs(callback = this._defaultOneParamCallback, pattern = 'IN', beginRoot = this.root, iterationType = 'ITERATIVE') {
|
|
503
509
|
return super.dfs(callback, pattern, beginRoot, iterationType, false);
|
|
504
510
|
}
|
|
505
511
|
/**
|
|
@@ -572,7 +578,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
572
578
|
let current = this.ensureNode(beginRoot);
|
|
573
579
|
if (!current)
|
|
574
580
|
return undefined;
|
|
575
|
-
if (this._variant ===
|
|
581
|
+
if (this._variant === 'STANDARD') {
|
|
576
582
|
// For BSTVariant.MIN, find the rightmost node
|
|
577
583
|
while (current.right !== undefined) {
|
|
578
584
|
current = current.right;
|
|
@@ -611,7 +617,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
611
617
|
* @returns The function `lesserOrGreaterTraverse` returns an array of values of type
|
|
612
618
|
* `ReturnType<C>`, which is the return type of the callback function passed as an argument.
|
|
613
619
|
*/
|
|
614
|
-
lesserOrGreaterTraverse(callback = this._defaultOneParamCallback, lesserOrGreater =
|
|
620
|
+
lesserOrGreaterTraverse(callback = this._defaultOneParamCallback, lesserOrGreater = 'LT', targetNode = this.root, iterationType = this.iterationType) {
|
|
615
621
|
targetNode = this.ensureNode(targetNode);
|
|
616
622
|
const ans = [];
|
|
617
623
|
if (!targetNode)
|
|
@@ -619,7 +625,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
619
625
|
if (!this.root)
|
|
620
626
|
return ans;
|
|
621
627
|
const targetKey = targetNode.key;
|
|
622
|
-
if (iterationType ===
|
|
628
|
+
if (iterationType === 'RECURSIVE') {
|
|
623
629
|
const _traverse = (cur) => {
|
|
624
630
|
const compared = this._compare(cur.key, targetKey);
|
|
625
631
|
if (compared === lesserOrGreater)
|
|
@@ -665,11 +671,11 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
665
671
|
* @returns The function `perfectlyBalance` returns a boolean value.
|
|
666
672
|
*/
|
|
667
673
|
perfectlyBalance(iterationType = this.iterationType) {
|
|
668
|
-
const sorted = this.dfs(node => node, '
|
|
674
|
+
const sorted = this.dfs(node => node, 'IN'), n = sorted.length;
|
|
669
675
|
this.clear();
|
|
670
676
|
if (sorted.length < 1)
|
|
671
677
|
return false;
|
|
672
|
-
if (iterationType ===
|
|
678
|
+
if (iterationType === 'RECURSIVE') {
|
|
673
679
|
const buildBalanceBST = (l, r) => {
|
|
674
680
|
if (l > r)
|
|
675
681
|
return;
|
|
@@ -727,7 +733,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
727
733
|
if (!this.root)
|
|
728
734
|
return true;
|
|
729
735
|
let balanced = true;
|
|
730
|
-
if (iterationType ===
|
|
736
|
+
if (iterationType === 'RECURSIVE') {
|
|
731
737
|
const _height = (cur) => {
|
|
732
738
|
if (!cur)
|
|
733
739
|
return 0;
|
|
@@ -784,14 +790,47 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
784
790
|
* is greater than, less than, or equal to the second value.
|
|
785
791
|
* @param {K} a - The parameter "a" is of type K.
|
|
786
792
|
* @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),
|
|
793
|
+
* @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater
|
|
794
|
+
* than), 'LT' (less than), or 'EQ' (equal).
|
|
789
795
|
*/
|
|
790
796
|
_compare(a, b) {
|
|
791
797
|
const extractedA = this.extractor(a);
|
|
792
798
|
const extractedB = this.extractor(b);
|
|
793
|
-
const compared = this.variant ===
|
|
794
|
-
return compared > 0 ?
|
|
799
|
+
const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA;
|
|
800
|
+
return compared > 0 ? 'GT' : compared < 0 ? 'LT' : 'EQ';
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* The function `_lt` compares two values `a` and `b` using an extractor function and returns true if
|
|
804
|
+
* `a` is less than `b` based on the specified variant.
|
|
805
|
+
* @param {K} a - The parameter "a" is of type "K", which means it can be any type. It represents the
|
|
806
|
+
* first value to be compared in the function.
|
|
807
|
+
* @param {K} b - The parameter `b` is of type `K`, which means it can be any type. It is used as one
|
|
808
|
+
* of the arguments for the comparison in the `_lt` function.
|
|
809
|
+
* @returns a boolean value.
|
|
810
|
+
*/
|
|
811
|
+
_lt(a, b) {
|
|
812
|
+
const extractedA = this.extractor(a);
|
|
813
|
+
const extractedB = this.extractor(b);
|
|
814
|
+
// return this.variant === BSTVariant.STANDARD ? extractedA < extractedB : extractedA > extractedB;
|
|
815
|
+
return this.variant === 'STANDARD' ? extractedA < extractedB : extractedA > extractedB;
|
|
816
|
+
// return extractedA < extractedB;
|
|
817
|
+
// return a < b;
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* The function compares two values using a custom extractor function and returns true if the first
|
|
821
|
+
* value is greater than the second value.
|
|
822
|
+
* @param {K} a - The parameter "a" is of type K, which means it can be any type.
|
|
823
|
+
* @param {K} b - The parameter "b" is of type K, which means it can be any type. It is used as one
|
|
824
|
+
* of the arguments for the comparison in the function.
|
|
825
|
+
* @returns a boolean value.
|
|
826
|
+
*/
|
|
827
|
+
_gt(a, b) {
|
|
828
|
+
const extractedA = this.extractor(a);
|
|
829
|
+
const extractedB = this.extractor(b);
|
|
830
|
+
// return this.variant === BSTVariant.STANDARD ? extractedA > extractedB : extractedA < extractedB;
|
|
831
|
+
return this.variant === 'STANDARD' ? extractedA > extractedB : extractedA < extractedB;
|
|
832
|
+
// return extractedA > extractedB;
|
|
833
|
+
// return a > b;
|
|
795
834
|
}
|
|
796
835
|
}
|
|
797
836
|
exports.BST = BST;
|