linked-list-typed 1.49.4 → 1.49.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-structures/base/iterable-base.d.ts +1 -1
- package/dist/data-structures/binary-tree/binary-tree.d.ts +1 -13
- package/dist/data-structures/binary-tree/binary-tree.js +19 -49
- package/dist/data-structures/binary-tree/tree-multimap.d.ts +0 -16
- package/dist/data-structures/binary-tree/tree-multimap.js +1 -43
- package/dist/data-structures/graph/abstract-graph.d.ts +1 -1
- package/dist/data-structures/graph/abstract-graph.js +3 -2
- package/dist/data-structures/hash/hash-map.d.ts +1 -1
- package/dist/data-structures/hash/hash-map.js +2 -2
- package/dist/data-structures/heap/heap.js +2 -3
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +2 -2
- package/dist/data-structures/matrix/index.d.ts +0 -2
- package/dist/data-structures/matrix/index.js +0 -2
- package/dist/data-structures/matrix/matrix.d.ts +128 -10
- package/dist/data-structures/matrix/matrix.js +400 -15
- package/dist/data-structures/queue/deque.d.ts +2 -2
- package/dist/data-structures/queue/deque.js +5 -7
- package/dist/data-structures/queue/queue.d.ts +1 -1
- package/dist/types/data-structures/base/base.d.ts +1 -1
- package/dist/types/data-structures/heap/heap.d.ts +1 -1
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +1 -1
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.js +6 -1
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +1 -1
- package/src/data-structures/base/iterable-base.ts +7 -10
- package/src/data-structures/binary-tree/avl-tree.ts +15 -8
- package/src/data-structures/binary-tree/binary-tree.ts +57 -74
- package/src/data-structures/binary-tree/bst.ts +16 -13
- package/src/data-structures/binary-tree/rb-tree.ts +16 -10
- package/src/data-structures/binary-tree/tree-multimap.ts +11 -48
- package/src/data-structures/graph/abstract-graph.ts +13 -11
- package/src/data-structures/graph/directed-graph.ts +1 -3
- package/src/data-structures/graph/map-graph.ts +6 -1
- package/src/data-structures/graph/undirected-graph.ts +3 -6
- package/src/data-structures/hash/hash-map.ts +18 -16
- package/src/data-structures/heap/heap.ts +7 -10
- package/src/data-structures/heap/max-heap.ts +2 -1
- package/src/data-structures/heap/min-heap.ts +2 -1
- package/src/data-structures/linked-list/singly-linked-list.ts +2 -3
- package/src/data-structures/matrix/index.ts +0 -2
- package/src/data-structures/matrix/matrix.ts +442 -13
- package/src/data-structures/priority-queue/min-priority-queue.ts +11 -10
- package/src/data-structures/queue/deque.ts +18 -39
- package/src/data-structures/queue/queue.ts +1 -1
- package/src/interfaces/binary-tree.ts +7 -2
- package/src/types/common.ts +4 -4
- package/src/types/data-structures/base/base.ts +14 -3
- package/src/types/data-structures/base/index.ts +1 -1
- package/src/types/data-structures/graph/abstract-graph.ts +4 -2
- package/src/types/data-structures/hash/hash-map.ts +3 -3
- package/src/types/data-structures/heap/heap.ts +2 -2
- package/src/types/data-structures/priority-queue/priority-queue.ts +2 -2
- package/src/utils/utils.ts +7 -1
- package/dist/data-structures/matrix/matrix2d.d.ts +0 -107
- package/dist/data-structures/matrix/matrix2d.js +0 -199
- package/dist/data-structures/matrix/vector2d.d.ts +0 -200
- package/dist/data-structures/matrix/vector2d.js +0 -290
- package/src/data-structures/matrix/matrix2d.ts +0 -211
- package/src/data-structures/matrix/vector2d.ts +0 -315
|
@@ -18,7 +18,11 @@ import type {
|
|
|
18
18
|
} from '../../types';
|
|
19
19
|
import { IBinaryTree } from '../../interfaces';
|
|
20
20
|
|
|
21
|
-
export class AVLTreeNode<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNodeNested<K, V>> extends BSTNode<
|
|
21
|
+
export class AVLTreeNode<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNodeNested<K, V>> extends BSTNode<
|
|
22
|
+
K,
|
|
23
|
+
V,
|
|
24
|
+
N
|
|
25
|
+
> {
|
|
22
26
|
height: number;
|
|
23
27
|
|
|
24
28
|
constructor(key: K, value?: V) {
|
|
@@ -36,10 +40,14 @@ export class AVLTreeNode<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLT
|
|
|
36
40
|
* 6. Complex Insertions and Deletions: Due to rebalancing, these operations are more complex than in a regular BST.
|
|
37
41
|
* 7. Path Length: The path length from the root to any leaf is longer compared to an unbalanced BST, but shorter than a linear chain of nodes.
|
|
38
42
|
*/
|
|
39
|
-
export class AVLTree<
|
|
43
|
+
export class AVLTree<
|
|
44
|
+
K = any,
|
|
45
|
+
V = any,
|
|
46
|
+
N extends AVLTreeNode<K, V, N> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>,
|
|
47
|
+
TREE extends AVLTree<K, V, N, TREE> = AVLTree<K, V, N, AVLTreeNested<K, V, N>>
|
|
48
|
+
>
|
|
40
49
|
extends BST<K, V, N, TREE>
|
|
41
50
|
implements IBinaryTree<K, V, N, TREE> {
|
|
42
|
-
|
|
43
51
|
/**
|
|
44
52
|
* The constructor function initializes an AVLTree object with optional elements and options.
|
|
45
53
|
* @param [elements] - The `elements` parameter is an optional iterable of `BTNExemplar<K, V, N>`
|
|
@@ -77,7 +85,8 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
|
|
|
77
85
|
override createTree(options?: AVLTreeOptions<K>): TREE {
|
|
78
86
|
return new AVLTree<K, V, N, TREE>([], {
|
|
79
87
|
iterationType: this.iterationType,
|
|
80
|
-
variant: this.variant,
|
|
88
|
+
variant: this.variant,
|
|
89
|
+
...options
|
|
81
90
|
}) as TREE;
|
|
82
91
|
}
|
|
83
92
|
|
|
@@ -97,7 +106,7 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
|
|
|
97
106
|
* @returns a boolean value indicating whether the potentialKey is of type number or not.
|
|
98
107
|
*/
|
|
99
108
|
override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
|
|
100
|
-
return !(potentialKey instanceof AVLTreeNode)
|
|
109
|
+
return !(potentialKey instanceof AVLTreeNode);
|
|
101
110
|
}
|
|
102
111
|
|
|
103
112
|
/**
|
|
@@ -105,7 +114,6 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
|
|
|
105
114
|
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
|
106
115
|
*/
|
|
107
116
|
|
|
108
|
-
|
|
109
117
|
/**
|
|
110
118
|
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.
|
|
111
119
|
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
|
@@ -159,7 +167,6 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
|
|
|
159
167
|
return deletedResults;
|
|
160
168
|
}
|
|
161
169
|
|
|
162
|
-
|
|
163
170
|
/**
|
|
164
171
|
* The `_swapProperties` function swaps the key, value, and height properties between two nodes in a binary
|
|
165
172
|
* tree.
|
|
@@ -489,6 +496,6 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
|
|
|
489
496
|
protected _replaceNode(oldNode: N, newNode: N): N {
|
|
490
497
|
newNode.height = oldNode.height;
|
|
491
498
|
|
|
492
|
-
return super._replaceNode(oldNode, newNode)
|
|
499
|
+
return super._replaceNode(oldNode, newNode);
|
|
493
500
|
}
|
|
494
501
|
}
|
|
@@ -24,14 +24,18 @@ import { FamilyPosition, IterationType } from '../../types';
|
|
|
24
24
|
import { IBinaryTree } from '../../interfaces';
|
|
25
25
|
import { trampoline } from '../../utils';
|
|
26
26
|
import { Queue } from '../queue';
|
|
27
|
-
import { IterableEntryBase } from
|
|
27
|
+
import { IterableEntryBase } from '../base';
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Represents a node in a binary tree.
|
|
31
31
|
* @template V - The type of data stored in the node.
|
|
32
32
|
* @template N - The type of the family relationship in the binary tree.
|
|
33
33
|
*/
|
|
34
|
-
export class BinaryTreeNode<
|
|
34
|
+
export class BinaryTreeNode<
|
|
35
|
+
K = any,
|
|
36
|
+
V = any,
|
|
37
|
+
N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>
|
|
38
|
+
> {
|
|
35
39
|
key: K;
|
|
36
40
|
|
|
37
41
|
value?: V;
|
|
@@ -97,10 +101,15 @@ export class BinaryTreeNode<K = any, V = any, N extends BinaryTreeNode<K, V, N>
|
|
|
97
101
|
* 5. Leaf Nodes: Nodes without children are leaves.
|
|
98
102
|
*/
|
|
99
103
|
|
|
100
|
-
export class BinaryTree<
|
|
101
|
-
|
|
104
|
+
export class BinaryTree<
|
|
105
|
+
K = any,
|
|
106
|
+
V = any,
|
|
107
|
+
N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>,
|
|
108
|
+
TREE extends BinaryTree<K, V, N, TREE> = BinaryTree<K, V, N, BinaryTreeNested<K, V, N>>
|
|
109
|
+
>
|
|
110
|
+
extends IterableEntryBase<K, V | undefined>
|
|
102
111
|
implements IBinaryTree<K, V, N, TREE> {
|
|
103
|
-
iterationType = IterationType.ITERATIVE
|
|
112
|
+
iterationType = IterationType.ITERATIVE;
|
|
104
113
|
|
|
105
114
|
/**
|
|
106
115
|
* The constructor function initializes a binary tree object with optional elements and options.
|
|
@@ -128,7 +137,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
128
137
|
if (elements) this.addMany(elements);
|
|
129
138
|
}
|
|
130
139
|
|
|
131
|
-
protected _extractor = (key: K) => Number(key)
|
|
140
|
+
protected _extractor = (key: K) => Number(key);
|
|
132
141
|
|
|
133
142
|
get extractor() {
|
|
134
143
|
return this._extractor;
|
|
@@ -287,7 +296,6 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
287
296
|
return undefined; // If the insertion position cannot be found, return undefined
|
|
288
297
|
}
|
|
289
298
|
|
|
290
|
-
|
|
291
299
|
/**
|
|
292
300
|
* Time Complexity: O(k log n) - O(k * n)
|
|
293
301
|
* Space Complexity: O(1)
|
|
@@ -329,7 +337,6 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
329
337
|
return inserted;
|
|
330
338
|
}
|
|
331
339
|
|
|
332
|
-
|
|
333
340
|
/**
|
|
334
341
|
* Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
|
|
335
342
|
* Space Complexity: O(1)
|
|
@@ -985,10 +992,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
985
992
|
* @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
|
|
986
993
|
* is no leftmost node, it returns `null` or `undefined` depending on the input.
|
|
987
994
|
*/
|
|
988
|
-
getLeftMost(
|
|
989
|
-
beginRoot: BTNKeyOrNode<K, N> = this.root,
|
|
990
|
-
iterationType = this.iterationType
|
|
991
|
-
): N | null | undefined {
|
|
995
|
+
getLeftMost(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): N | null | undefined {
|
|
992
996
|
beginRoot = this.ensureNode(beginRoot);
|
|
993
997
|
|
|
994
998
|
if (!beginRoot) return beginRoot;
|
|
@@ -1031,10 +1035,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
1031
1035
|
* @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
|
|
1032
1036
|
* is no rightmost node, it returns `null` or `undefined`, depending on the input.
|
|
1033
1037
|
*/
|
|
1034
|
-
getRightMost(
|
|
1035
|
-
beginRoot: BTNKeyOrNode<K, N> = this.root,
|
|
1036
|
-
iterationType = this.iterationType
|
|
1037
|
-
): N | null | undefined {
|
|
1038
|
+
getRightMost(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): N | null | undefined {
|
|
1038
1039
|
// TODO support get right most by passing key in
|
|
1039
1040
|
beginRoot = this.ensureNode(beginRoot);
|
|
1040
1041
|
if (!beginRoot) return beginRoot;
|
|
@@ -1262,7 +1263,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
1262
1263
|
* @returns a boolean value indicating whether the potentialKey is of type number or not.
|
|
1263
1264
|
*/
|
|
1264
1265
|
isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
|
|
1265
|
-
return !(potentialKey instanceof BinaryTreeNode)
|
|
1266
|
+
return !(potentialKey instanceof BinaryTreeNode);
|
|
1266
1267
|
}
|
|
1267
1268
|
|
|
1268
1269
|
dfs<C extends BTNCallback<N>>(
|
|
@@ -1637,7 +1638,6 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
1637
1638
|
* after the given node in the inorder traversal of the binary tree.
|
|
1638
1639
|
*/
|
|
1639
1640
|
getSuccessor(x?: K | N | null): N | null | undefined {
|
|
1640
|
-
|
|
1641
1641
|
x = this.ensureNode(x);
|
|
1642
1642
|
if (!this.isRealNode(x)) return undefined;
|
|
1643
1643
|
|
|
@@ -1858,11 +1858,14 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
1858
1858
|
beginRoot = this.ensureNode(beginRoot);
|
|
1859
1859
|
if (!beginRoot) return;
|
|
1860
1860
|
|
|
1861
|
-
if (opts.isShowUndefined)
|
|
1861
|
+
if (opts.isShowUndefined)
|
|
1862
|
+
console.log(`U for undefined
|
|
1862
1863
|
`);
|
|
1863
|
-
if (opts.isShowNull)
|
|
1864
|
+
if (opts.isShowNull)
|
|
1865
|
+
console.log(`N for null
|
|
1864
1866
|
`);
|
|
1865
|
-
if (opts.isShowRedBlackNIL)
|
|
1867
|
+
if (opts.isShowRedBlackNIL)
|
|
1868
|
+
console.log(`S for Sentinel Node
|
|
1866
1869
|
`);
|
|
1867
1870
|
|
|
1868
1871
|
const display = (root: N | null | undefined): void => {
|
|
@@ -1920,30 +1923,42 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
1920
1923
|
} else if (node !== null && node !== undefined) {
|
|
1921
1924
|
// Display logic of normal nodes
|
|
1922
1925
|
|
|
1923
|
-
const key = node.key,
|
|
1926
|
+
const key = node.key,
|
|
1927
|
+
line = isNaN(this.extractor(key)) ? 'S' : this.extractor(key).toString(),
|
|
1924
1928
|
width = line.length;
|
|
1925
1929
|
|
|
1926
|
-
return _buildNodeDisplay(
|
|
1927
|
-
|
|
1930
|
+
return _buildNodeDisplay(
|
|
1931
|
+
line,
|
|
1932
|
+
width,
|
|
1933
|
+
this._displayAux(node.left, options),
|
|
1934
|
+
this._displayAux(node.right, options)
|
|
1935
|
+
);
|
|
1928
1936
|
} else {
|
|
1929
1937
|
// For cases where none of the conditions are met, null, undefined, and NaN nodes are not displayed
|
|
1930
|
-
const line = node === undefined ? 'U' : 'N',
|
|
1938
|
+
const line = node === undefined ? 'U' : 'N',
|
|
1939
|
+
width = line.length;
|
|
1931
1940
|
|
|
1932
|
-
return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0])
|
|
1941
|
+
return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0]);
|
|
1933
1942
|
}
|
|
1934
1943
|
|
|
1935
1944
|
function _buildNodeDisplay(line: string, width: number, left: NodeDisplayLayout, right: NodeDisplayLayout) {
|
|
1936
1945
|
const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
|
|
1937
1946
|
const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
|
|
1938
|
-
const firstLine =
|
|
1939
|
-
|
|
1940
|
-
+
|
|
1941
|
-
+
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
+
const firstLine =
|
|
1948
|
+
' '.repeat(Math.max(0, leftMiddle + 1)) +
|
|
1949
|
+
'_'.repeat(Math.max(0, leftWidth - leftMiddle - 1)) +
|
|
1950
|
+
line +
|
|
1951
|
+
'_'.repeat(Math.max(0, rightMiddle)) +
|
|
1952
|
+
' '.repeat(Math.max(0, rightWidth - rightMiddle));
|
|
1953
|
+
|
|
1954
|
+
const secondLine =
|
|
1955
|
+
(leftHeight > 0
|
|
1956
|
+
? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1)
|
|
1957
|
+
: ' '.repeat(leftWidth)) +
|
|
1958
|
+
' '.repeat(width) +
|
|
1959
|
+
(rightHeight > 0
|
|
1960
|
+
? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1)
|
|
1961
|
+
: ' '.repeat(rightWidth));
|
|
1947
1962
|
|
|
1948
1963
|
const mergedLines = [firstLine, secondLine];
|
|
1949
1964
|
|
|
@@ -1953,11 +1968,16 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
1953
1968
|
mergedLines.push(leftLine + ' '.repeat(width) + rightLine);
|
|
1954
1969
|
}
|
|
1955
1970
|
|
|
1956
|
-
return <NodeDisplayLayout>[
|
|
1971
|
+
return <NodeDisplayLayout>[
|
|
1972
|
+
mergedLines,
|
|
1973
|
+
leftWidth + width + rightWidth,
|
|
1974
|
+
Math.max(leftHeight, rightHeight) + 2,
|
|
1975
|
+
leftWidth + Math.floor(width / 2)
|
|
1976
|
+
];
|
|
1957
1977
|
}
|
|
1958
1978
|
}
|
|
1959
1979
|
|
|
1960
|
-
protected _defaultOneParamCallback = (node: N | null | undefined) => node ? node.key : undefined;
|
|
1980
|
+
protected _defaultOneParamCallback = (node: N | null | undefined) => (node ? node.key : undefined);
|
|
1961
1981
|
|
|
1962
1982
|
/**
|
|
1963
1983
|
* Swap the data of two nodes in the binary tree.
|
|
@@ -2012,43 +2032,6 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
|
|
|
2012
2032
|
return newNode;
|
|
2013
2033
|
}
|
|
2014
2034
|
|
|
2015
|
-
/**
|
|
2016
|
-
* The function `_addTo` adds a new node to a binary tree if there is an available position.
|
|
2017
|
-
* @param {N | null | undefined} newNode - The `newNode` parameter represents the node that you want to add to
|
|
2018
|
-
* the binary tree. It can be either a node object or `null`.
|
|
2019
|
-
* @param {N} parent - The `parent` parameter represents the parent node to which the new node will
|
|
2020
|
-
* be added as a child.
|
|
2021
|
-
* @returns either the left or right child node of the parent node, depending on which child is
|
|
2022
|
-
* available for adding the new node. If a new node is added, the function also updates the size of
|
|
2023
|
-
* the binary tree. If neither the left nor right child is available, the function returns undefined.
|
|
2024
|
-
* If the parent node is null, the function also returns undefined.
|
|
2025
|
-
*/
|
|
2026
|
-
protected _addTo(newNode: N | null | undefined, parent: BTNKeyOrNode<K, N>): N | null | undefined {
|
|
2027
|
-
if (this.isNotNodeInstance(parent)) parent = this.getNode(parent);
|
|
2028
|
-
|
|
2029
|
-
if (parent) {
|
|
2030
|
-
// When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.
|
|
2031
|
-
// In this scenario, null nodes serve as "sentinel nodes," "virtual nodes," or "placeholder nodes."
|
|
2032
|
-
if (parent.left === undefined) {
|
|
2033
|
-
parent.left = newNode;
|
|
2034
|
-
if (newNode) {
|
|
2035
|
-
this._size = this.size + 1;
|
|
2036
|
-
}
|
|
2037
|
-
return parent.left;
|
|
2038
|
-
} else if (parent.right === undefined) {
|
|
2039
|
-
parent.right = newNode;
|
|
2040
|
-
if (newNode) {
|
|
2041
|
-
this._size = this.size + 1;
|
|
2042
|
-
}
|
|
2043
|
-
return parent.right;
|
|
2044
|
-
} else {
|
|
2045
|
-
return;
|
|
2046
|
-
}
|
|
2047
|
-
} else {
|
|
2048
|
-
return;
|
|
2049
|
-
}
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
2035
|
/**
|
|
2053
2036
|
* The function sets the root property of an object to a given value, and if the value is not null,
|
|
2054
2037
|
* it also sets the parent property of the value to undefined.
|
|
@@ -20,7 +20,11 @@ import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
|
20
20
|
import { IBinaryTree } from '../../interfaces';
|
|
21
21
|
import { Queue } from '../queue';
|
|
22
22
|
|
|
23
|
-
export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<
|
|
23
|
+
export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<
|
|
24
|
+
K,
|
|
25
|
+
V,
|
|
26
|
+
N
|
|
27
|
+
> {
|
|
24
28
|
override parent?: N;
|
|
25
29
|
|
|
26
30
|
constructor(key: K, value?: V) {
|
|
@@ -80,11 +84,14 @@ export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNeste
|
|
|
80
84
|
* 6. Balance Variability: Can become unbalanced; special types maintain balance.
|
|
81
85
|
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
|
|
82
86
|
*/
|
|
83
|
-
export class BST<
|
|
87
|
+
export class BST<
|
|
88
|
+
K = any,
|
|
89
|
+
V = any,
|
|
90
|
+
N extends BSTNode<K, V, N> = BSTNode<K, V, BSTNodeNested<K, V>>,
|
|
91
|
+
TREE extends BST<K, V, N, TREE> = BST<K, V, N, BSTNested<K, V, N>>
|
|
92
|
+
>
|
|
84
93
|
extends BinaryTree<K, V, N, TREE>
|
|
85
94
|
implements IBinaryTree<K, V, N, TREE> {
|
|
86
|
-
|
|
87
|
-
|
|
88
95
|
/**
|
|
89
96
|
* This is the constructor function for a binary search tree class in TypeScript, which initializes
|
|
90
97
|
* the tree with optional elements and options.
|
|
@@ -114,7 +121,7 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|
|
114
121
|
return this._root;
|
|
115
122
|
}
|
|
116
123
|
|
|
117
|
-
protected _variant = BSTVariant.MIN
|
|
124
|
+
protected _variant = BSTVariant.MIN;
|
|
118
125
|
|
|
119
126
|
get variant() {
|
|
120
127
|
return this._variant;
|
|
@@ -142,7 +149,8 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|
|
142
149
|
override createTree(options?: Partial<BSTOptions<K>>): TREE {
|
|
143
150
|
return new BST<K, V, N, TREE>([], {
|
|
144
151
|
iterationType: this.iterationType,
|
|
145
|
-
variant: this.variant,
|
|
152
|
+
variant: this.variant,
|
|
153
|
+
...options
|
|
146
154
|
}) as TREE;
|
|
147
155
|
}
|
|
148
156
|
|
|
@@ -155,7 +163,6 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|
|
155
163
|
return exemplar instanceof BSTNode;
|
|
156
164
|
}
|
|
157
165
|
|
|
158
|
-
|
|
159
166
|
/**
|
|
160
167
|
* The function `exemplarToNode` takes an exemplar and returns a node if the exemplar is valid,
|
|
161
168
|
* otherwise it returns undefined.
|
|
@@ -301,7 +308,7 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|
|
301
308
|
const isRealBTNExemplar = (kve: BTNExemplar<K, V, N>): kve is BTNodePureExemplar<K, V, N> => {
|
|
302
309
|
if (kve === undefined || kve === null) return false;
|
|
303
310
|
return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
|
|
304
|
-
}
|
|
311
|
+
};
|
|
305
312
|
|
|
306
313
|
for (const kve of keysOrNodesOrEntries) {
|
|
307
314
|
isRealBTNExemplar(kve) && realBTNExemplars.push(kve);
|
|
@@ -359,7 +366,6 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|
|
359
366
|
return inserted;
|
|
360
367
|
}
|
|
361
368
|
|
|
362
|
-
|
|
363
369
|
/**
|
|
364
370
|
* Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
|
|
365
371
|
* Space Complexity: O(n) - Additional space is required for the sorted array.
|
|
@@ -398,7 +404,6 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|
|
398
404
|
return current.key;
|
|
399
405
|
}
|
|
400
406
|
|
|
401
|
-
|
|
402
407
|
/**
|
|
403
408
|
* Time Complexity: O(log n) - Average case for a balanced tree.
|
|
404
409
|
* Space Complexity: O(1) - Constant space is used.
|
|
@@ -450,7 +455,7 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|
|
450
455
|
* @returns a boolean value indicating whether the potentialKey is of type number or not.
|
|
451
456
|
*/
|
|
452
457
|
override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
|
|
453
|
-
return !(potentialKey instanceof BSTNode)
|
|
458
|
+
return !(potentialKey instanceof BSTNode);
|
|
454
459
|
}
|
|
455
460
|
|
|
456
461
|
/**
|
|
@@ -738,7 +743,6 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|
|
738
743
|
return balanced;
|
|
739
744
|
}
|
|
740
745
|
|
|
741
|
-
|
|
742
746
|
protected _setRoot(v: N | undefined) {
|
|
743
747
|
if (v) {
|
|
744
748
|
v.parent = undefined;
|
|
@@ -761,5 +765,4 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|
|
761
765
|
|
|
762
766
|
return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq;
|
|
763
767
|
}
|
|
764
|
-
|
|
765
768
|
}
|
|
@@ -21,10 +21,11 @@ import {
|
|
|
21
21
|
import { BST, BSTNode } from './bst';
|
|
22
22
|
import { IBinaryTree } from '../../interfaces';
|
|
23
23
|
|
|
24
|
-
export class RedBlackTreeNode<
|
|
25
|
-
K
|
|
26
|
-
|
|
27
|
-
>
|
|
24
|
+
export class RedBlackTreeNode<
|
|
25
|
+
K = any,
|
|
26
|
+
V = any,
|
|
27
|
+
N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNodeNested<K, V>
|
|
28
|
+
> extends BSTNode<K, V, N> {
|
|
28
29
|
color: RBTNColor;
|
|
29
30
|
|
|
30
31
|
constructor(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK) {
|
|
@@ -40,7 +41,12 @@ export class RedBlackTreeNode<K = any, V = any, N extends RedBlackTreeNode<K, V,
|
|
|
40
41
|
* 4. Red nodes must have black children.
|
|
41
42
|
* 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
|
|
42
43
|
*/
|
|
43
|
-
export class RedBlackTree<
|
|
44
|
+
export class RedBlackTree<
|
|
45
|
+
K = any,
|
|
46
|
+
V = any,
|
|
47
|
+
N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>,
|
|
48
|
+
TREE extends RedBlackTree<K, V, N, TREE> = RedBlackTree<K, V, N, RedBlackTreeNested<K, V, N>>
|
|
49
|
+
>
|
|
44
50
|
extends BST<K, V, N, TREE>
|
|
45
51
|
implements IBinaryTree<K, V, N, TREE> {
|
|
46
52
|
Sentinel: N = new RedBlackTreeNode<K, V>(NaN as K) as unknown as N;
|
|
@@ -101,7 +107,8 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
|
|
|
101
107
|
override createTree(options?: RBTreeOptions<K>): TREE {
|
|
102
108
|
return new RedBlackTree<K, V, N, TREE>([], {
|
|
103
109
|
iterationType: this.iterationType,
|
|
104
|
-
variant: this.variant,
|
|
110
|
+
variant: this.variant,
|
|
111
|
+
...options
|
|
105
112
|
}) as TREE;
|
|
106
113
|
}
|
|
107
114
|
|
|
@@ -122,7 +129,7 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
|
|
|
122
129
|
* @returns a boolean value indicating whether the potentialKey is of type number or not.
|
|
123
130
|
*/
|
|
124
131
|
override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
|
|
125
|
-
return !(potentialKey instanceof RedBlackTreeNode)
|
|
132
|
+
return !(potentialKey instanceof RedBlackTreeNode);
|
|
126
133
|
}
|
|
127
134
|
|
|
128
135
|
/**
|
|
@@ -191,12 +198,11 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
|
|
|
191
198
|
x = x?.right;
|
|
192
199
|
} else {
|
|
193
200
|
if (newNode !== x) {
|
|
194
|
-
this._replaceNode(x, newNode)
|
|
201
|
+
this._replaceNode(x, newNode);
|
|
195
202
|
}
|
|
196
203
|
return;
|
|
197
204
|
}
|
|
198
205
|
}
|
|
199
|
-
|
|
200
206
|
}
|
|
201
207
|
|
|
202
208
|
newNode.parent = y;
|
|
@@ -649,6 +655,6 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
|
|
|
649
655
|
protected _replaceNode(oldNode: N, newNode: N): N {
|
|
650
656
|
newNode.color = oldNode.color;
|
|
651
657
|
|
|
652
|
-
return super._replaceNode(oldNode, newNode)
|
|
658
|
+
return super._replaceNode(oldNode, newNode);
|
|
653
659
|
}
|
|
654
660
|
}
|
|
@@ -45,11 +45,14 @@ export class TreeMultimapNode<
|
|
|
45
45
|
/**
|
|
46
46
|
* The only distinction between a TreeMultimap and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.
|
|
47
47
|
*/
|
|
48
|
-
export class TreeMultimap<
|
|
49
|
-
|
|
48
|
+
export class TreeMultimap<
|
|
49
|
+
K = any,
|
|
50
|
+
V = any,
|
|
51
|
+
N extends TreeMultimapNode<K, V, N> = TreeMultimapNode<K, V, TreeMultimapNodeNested<K, V>>,
|
|
52
|
+
TREE extends TreeMultimap<K, V, N, TREE> = TreeMultimap<K, V, N, TreeMultimapNested<K, V, N>>
|
|
53
|
+
>
|
|
50
54
|
extends AVLTree<K, V, N, TREE>
|
|
51
55
|
implements IBinaryTree<K, V, N, TREE> {
|
|
52
|
-
|
|
53
56
|
constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<TreeMultimapOptions<K>>) {
|
|
54
57
|
super([], options);
|
|
55
58
|
if (elements) this.addMany(elements);
|
|
@@ -60,7 +63,7 @@ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N>
|
|
|
60
63
|
// TODO the _count is not accurate after nodes count modified
|
|
61
64
|
get count(): number {
|
|
62
65
|
let sum = 0;
|
|
63
|
-
this.subTreeTraverse(node => sum += node.count);
|
|
66
|
+
this.subTreeTraverse(node => (sum += node.count));
|
|
64
67
|
return sum;
|
|
65
68
|
}
|
|
66
69
|
|
|
@@ -80,7 +83,8 @@ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N>
|
|
|
80
83
|
override createTree(options?: TreeMultimapOptions<K>): TREE {
|
|
81
84
|
return new TreeMultimap<K, V, N, TREE>([], {
|
|
82
85
|
iterationType: this.iterationType,
|
|
83
|
-
variant: this.variant,
|
|
86
|
+
variant: this.variant,
|
|
87
|
+
...options
|
|
84
88
|
}) as TREE;
|
|
85
89
|
}
|
|
86
90
|
|
|
@@ -101,7 +105,7 @@ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N>
|
|
|
101
105
|
* @returns a boolean value indicating whether the potentialKey is of type number or not.
|
|
102
106
|
*/
|
|
103
107
|
override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
|
|
104
|
-
return !(potentialKey instanceof TreeMultimapNode)
|
|
108
|
+
return !(potentialKey instanceof TreeMultimapNode);
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
/**
|
|
@@ -357,47 +361,6 @@ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N>
|
|
|
357
361
|
return cloned;
|
|
358
362
|
}
|
|
359
363
|
|
|
360
|
-
/**
|
|
361
|
-
* Time Complexity: O(1) - constant time, as it performs basic pointer assignments.
|
|
362
|
-
* Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.
|
|
363
|
-
*
|
|
364
|
-
* The function adds a new node to a binary tree, either as the left child or the right child of a
|
|
365
|
-
* given parent node.
|
|
366
|
-
* @param {N | undefined} newNode - The `newNode` parameter represents the node that needs to be
|
|
367
|
-
* added to the binary tree. It can be of type `N` (which represents a node in the binary tree) or
|
|
368
|
-
* `undefined` if there is no node to add.
|
|
369
|
-
* @param {K | N | undefined} parent - The `parent` parameter represents the parent node to
|
|
370
|
-
* which the new node will be added as a child. It can be either a node object (`N`) or a key value
|
|
371
|
-
* (`K`).
|
|
372
|
-
* @returns The method `_addTo` returns either the `parent.left` or `parent.right` node that was
|
|
373
|
-
* added, or `undefined` if no node was added.
|
|
374
|
-
*/
|
|
375
|
-
protected override _addTo(newNode: N | undefined, parent: BSTNKeyOrNode<K, N>): N | undefined {
|
|
376
|
-
parent = this.ensureNode(parent);
|
|
377
|
-
if (parent) {
|
|
378
|
-
if (parent.left === undefined) {
|
|
379
|
-
parent.left = newNode;
|
|
380
|
-
if (newNode !== undefined) {
|
|
381
|
-
this._size = this.size + 1;
|
|
382
|
-
this._count += newNode.count;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
return parent.left;
|
|
386
|
-
} else if (parent.right === undefined) {
|
|
387
|
-
parent.right = newNode;
|
|
388
|
-
if (newNode !== undefined) {
|
|
389
|
-
this._size = this.size + 1;
|
|
390
|
-
this._count += newNode.count;
|
|
391
|
-
}
|
|
392
|
-
return parent.right;
|
|
393
|
-
} else {
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
} else {
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
364
|
/**
|
|
402
365
|
* The `_swapProperties` function swaps the key, value, count, and height properties between two nodes.
|
|
403
366
|
* @param {K | N | undefined} srcNode - The `srcNode` parameter represents the source node from
|
|
@@ -433,7 +396,7 @@ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N>
|
|
|
433
396
|
}
|
|
434
397
|
|
|
435
398
|
protected _replaceNode(oldNode: N, newNode: N): N {
|
|
436
|
-
newNode.count = oldNode.count + newNode.count
|
|
399
|
+
newNode.count = oldNode.count + newNode.count;
|
|
437
400
|
return super._replaceNode(oldNode, newNode);
|
|
438
401
|
}
|
|
439
402
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { DijkstraResult, EntryCallback, VertexKey } from '../../types';
|
|
9
9
|
import { uuidV4 } from '../../utils';
|
|
10
|
-
import { IterableEntryBase } from
|
|
10
|
+
import { IterableEntryBase } from '../base';
|
|
11
11
|
import { IGraph } from '../../interfaces';
|
|
12
12
|
import { Heap } from '../heap';
|
|
13
13
|
import { Queue } from '../queue';
|
|
@@ -65,7 +65,9 @@ export abstract class AbstractGraph<
|
|
|
65
65
|
E = any,
|
|
66
66
|
VO extends AbstractVertex<V> = AbstractVertex<V>,
|
|
67
67
|
EO extends AbstractEdge<E> = AbstractEdge<E>
|
|
68
|
-
>
|
|
68
|
+
>
|
|
69
|
+
extends IterableEntryBase<VertexKey, V | undefined>
|
|
70
|
+
implements IGraph<V, E, VO, EO> {
|
|
69
71
|
constructor() {
|
|
70
72
|
super();
|
|
71
73
|
}
|
|
@@ -165,7 +167,7 @@ export abstract class AbstractGraph<
|
|
|
165
167
|
|
|
166
168
|
isVertexKey(potentialKey: any): potentialKey is VertexKey {
|
|
167
169
|
const potentialKeyType = typeof potentialKey;
|
|
168
|
-
return potentialKeyType ===
|
|
170
|
+
return potentialKeyType === 'string' || potentialKeyType === 'number';
|
|
169
171
|
}
|
|
170
172
|
|
|
171
173
|
/**
|
|
@@ -662,7 +664,6 @@ export abstract class AbstractGraph<
|
|
|
662
664
|
getMinDist: boolean = false,
|
|
663
665
|
genPaths: boolean = false
|
|
664
666
|
): DijkstraResult<VO> {
|
|
665
|
-
|
|
666
667
|
let minDist = Infinity;
|
|
667
668
|
let minDest: VO | undefined = undefined;
|
|
668
669
|
let minPath: VO[] = [];
|
|
@@ -1170,7 +1171,10 @@ export abstract class AbstractGraph<
|
|
|
1170
1171
|
|
|
1171
1172
|
const dfs = (vertex: VO, currentPath: VertexKey[], visited: Set<VO>) => {
|
|
1172
1173
|
if (visited.has(vertex)) {
|
|
1173
|
-
if (
|
|
1174
|
+
if (
|
|
1175
|
+
((!isInclude2Cycle && currentPath.length > 2) || (isInclude2Cycle && currentPath.length >= 2)) &&
|
|
1176
|
+
currentPath[0] === vertex.key
|
|
1177
|
+
) {
|
|
1174
1178
|
cycles.push([...currentPath]);
|
|
1175
1179
|
}
|
|
1176
1180
|
return;
|
|
@@ -1195,18 +1199,16 @@ export abstract class AbstractGraph<
|
|
|
1195
1199
|
const uniqueCycles = new Map<string, VertexKey[]>();
|
|
1196
1200
|
|
|
1197
1201
|
for (const cycle of cycles) {
|
|
1198
|
-
const sorted = [...cycle].sort().toString()
|
|
1202
|
+
const sorted = [...cycle].sort().toString();
|
|
1199
1203
|
|
|
1200
|
-
if (uniqueCycles.has(sorted)) continue
|
|
1204
|
+
if (uniqueCycles.has(sorted)) continue;
|
|
1201
1205
|
else {
|
|
1202
|
-
uniqueCycles.set(sorted, cycle)
|
|
1206
|
+
uniqueCycles.set(sorted, cycle);
|
|
1203
1207
|
}
|
|
1204
1208
|
}
|
|
1205
1209
|
|
|
1206
1210
|
// Convert the unique cycles back to an array
|
|
1207
|
-
return [...uniqueCycles].map(cycleString =>
|
|
1208
|
-
cycleString[1]
|
|
1209
|
-
);
|
|
1211
|
+
return [...uniqueCycles].map(cycleString => cycleString[1]);
|
|
1210
1212
|
}
|
|
1211
1213
|
|
|
1212
1214
|
/**
|