diff --git a/README.md b/README.md
index 200131f..307615f 100644
--- a/README.md
+++ b/README.md
@@ -626,52 +626,52 @@ Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.key) // ['A', 'B', '
[//]: # (No deletion!!! Start of Replace Section)
avl-tree
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add randomly | 31.32 | 31.93 | 3.67e-4 |
10,000 add & delete randomly | 70.90 | 14.10 | 0.00 |
10,000 addMany | 40.58 | 24.64 | 4.87e-4 |
10,000 get | 27.31 | 36.62 | 2.00e-4 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add randomly | 33.09 | 30.22 | 4.32e-4 |
10,000 add & delete randomly | 74.12 | 13.49 | 0.00 |
10,000 addMany | 41.71 | 23.97 | 0.00 |
10,000 get | 28.37 | 35.25 | 2.37e-4 |
binary-tree
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 add randomly | 12.35 | 80.99 | 7.17e-5 |
1,000 add & delete randomly | 15.98 | 62.58 | 7.98e-4 |
1,000 addMany | 10.96 | 91.27 | 0.00 |
1,000 get | 18.61 | 53.73 | 0.00 |
1,000 dfs | 164.20 | 6.09 | 0.04 |
1,000 bfs | 58.84 | 17.00 | 0.01 |
1,000 morris | 256.66 | 3.90 | 7.70e-4 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 add randomly | 14.50 | 68.96 | 1.33e-4 |
1,000 add & delete randomly | 16.20 | 61.72 | 2.03e-4 |
1,000 addMany | 10.51 | 95.12 | 8.76e-5 |
1,000 get | 18.28 | 54.69 | 1.82e-4 |
1,000 dfs | 157.23 | 6.36 | 7.06e-4 |
1,000 bfs | 58.06 | 17.22 | 0.01 |
1,000 morris | 256.36 | 3.90 | 0.00 |
bst
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add randomly | 31.59 | 31.66 | 2.74e-4 |
10,000 add & delete randomly | 74.56 | 13.41 | 8.32e-4 |
10,000 addMany | 29.16 | 34.30 | 0.00 |
10,000 get | 29.24 | 34.21 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add randomly | 30.48 | 32.81 | 4.13e-4 |
10,000 add & delete randomly | 71.84 | 13.92 | 0.00 |
10,000 addMany | 29.54 | 33.85 | 5.25e-4 |
10,000 get | 30.53 | 32.75 | 0.01 |
rb-tree
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 85.85 | 11.65 | 0.00 |
100,000 add & delete randomly | 211.54 | 4.73 | 0.00 |
100,000 getNode | 37.92 | 26.37 | 1.65e-4 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 90.89 | 11.00 | 0.00 |
100,000 CPT add | 50.65 | 19.74 | 0.00 |
100,000 add & delete randomly | 230.08 | 4.35 | 0.02 |
100,000 getNode | 38.97 | 25.66 | 5.82e-4 |
100,000 add & iterator | 118.32 | 8.45 | 0.01 |
comparison
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
SRC PQ 10,000 add | 0.57 | 1748.73 | 4.96e-6 |
CJS PQ 10,000 add | 0.57 | 1746.69 | 4.91e-6 |
MJS PQ 10,000 add | 0.57 | 1749.68 | 4.43e-6 |
SRC PQ 10,000 add & pop | 3.47 | 288.14 | 6.38e-4 |
CJS PQ 10,000 add & pop | 3.39 | 295.36 | 3.90e-5 |
MJS PQ 10,000 add & pop | 3.37 | 297.17 | 3.03e-5 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
SRC PQ 10,000 add | 0.14 | 6939.33 | 1.74e-6 |
CJS PQ 10,000 add | 0.15 | 6881.64 | 1.91e-6 |
MJS PQ 10,000 add | 0.57 | 1745.92 | 1.60e-5 |
CPT PQ 10,000 add | 0.57 | 1744.71 | 1.01e-5 |
SRC PQ 10,000 add & pop | 3.51 | 284.93 | 6.79e-4 |
CJS PQ 10,000 add & pop | 3.42 | 292.55 | 4.04e-5 |
MJS PQ 10,000 add & pop | 3.41 | 293.38 | 5.11e-5 |
CPT PQ 10,000 add & pop | 2.09 | 478.76 | 2.28e-5 |
CPT OM 100,000 add | 43.22 | 23.14 | 0.00 |
CPT HM 10,000 set | 0.58 | 1721.25 | 1.85e-5 |
CPT HM 10,000 set & get | 0.68 | 1477.31 | 1.26e-5 |
CPT LL 1,000,000 unshift | 81.38 | 12.29 | 0.02 |
CPT PQ 10,000 add & pop | 2.10 | 476.50 | 1.60e-4 |
CPT DQ 1,000,000 push | 22.51 | 44.42 | 0.00 |
CPT Q 1,000,000 push | 47.85 | 20.90 | 0.01 |
CPT ST 1,000,000 push | 42.54 | 23.51 | 0.01 |
CPT ST 1,000,000 push & pop | 50.08 | 19.97 | 0.00 |
directed-graph
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 addVertex | 0.10 | 9534.93 | 8.72e-7 |
1,000 addEdge | 6.30 | 158.67 | 0.00 |
1,000 getVertex | 0.05 | 2.16e+4 | 3.03e-7 |
1,000 getEdge | 22.31 | 44.82 | 0.00 |
tarjan | 210.90 | 4.74 | 0.01 |
tarjan all | 214.72 | 4.66 | 0.01 |
topologicalSort | 172.52 | 5.80 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 addVertex | 0.11 | 9501.34 | 6.10e-6 |
1,000 addEdge | 6.35 | 157.55 | 6.69e-4 |
1,000 getVertex | 0.05 | 2.14e+4 | 2.50e-6 |
1,000 getEdge | 25.00 | 39.99 | 0.01 |
tarjan | 219.46 | 4.56 | 0.01 |
tarjan all | 218.15 | 4.58 | 0.00 |
topologicalSort | 176.83 | 5.66 | 0.00 |
hash-map
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 set | 275.88 | 3.62 | 0.12 |
1,000,000 Map set | 211.66 | 4.72 | 0.01 |
1,000,000 Set add | 177.72 | 5.63 | 0.02 |
1,000,000 set & get | 317.60 | 3.15 | 0.02 |
1,000,000 Map set & get | 274.99 | 3.64 | 0.03 |
1,000,000 Set add & has | 172.23 | 5.81 | 0.02 |
1,000,000 ObjKey set & get | 929.40 | 1.08 | 0.07 |
1,000,000 Map ObjKey set & get | 310.02 | 3.23 | 0.05 |
1,000,000 Set ObjKey add & has | 283.28 | 3.53 | 0.04 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 set | 254.46 | 3.93 | 0.04 |
1,000,000 CPT set | 251.21 | 3.98 | 0.03 |
1,000,000 Map set | 211.27 | 4.73 | 0.01 |
1,000,000 Set add | 175.15 | 5.71 | 0.02 |
1,000,000 set & get | 370.54 | 2.70 | 0.11 |
1,000,000 CPT set & get | 283.34 | 3.53 | 0.07 |
1,000,000 Map set & get | 287.09 | 3.48 | 0.04 |
1,000,000 Set add & has | 190.50 | 5.25 | 0.01 |
1,000,000 ObjKey set & get | 880.47 | 1.14 | 0.10 |
1,000,000 Map ObjKey set & get | 334.47 | 2.99 | 0.05 |
1,000,000 Set ObjKey add & has | 310.12 | 3.22 | 0.06 |
heap
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add & pop | 5.80 | 172.35 | 8.78e-5 |
10,000 fib add & pop | 357.92 | 2.79 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add & pop | 80.13 | 12.48 | 0.00 |
100,000 add & dfs | 35.08 | 28.50 | 0.00 |
10,000 fib add & pop | 367.84 | 2.72 | 0.01 |
doubly-linked-list
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 221.57 | 4.51 | 0.03 |
1,000,000 unshift | 229.02 | 4.37 | 0.07 |
1,000,000 unshift & shift | 169.21 | 5.91 | 0.02 |
1,000,000 insertBefore | 314.48 | 3.18 | 0.07 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 237.28 | 4.21 | 0.07 |
1,000,000 CPT push | 75.66 | 13.22 | 0.03 |
1,000,000 unshift | 226.38 | 4.42 | 0.05 |
1,000,000 CPT unshift | 93.34 | 10.71 | 0.07 |
1,000,000 unshift & shift | 188.34 | 5.31 | 0.05 |
1,000,000 insertBefore | 329.60 | 3.03 | 0.05 |
singly-linked-list
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 push & pop | 212.98 | 4.70 | 0.01 |
10,000 insertBefore | 250.68 | 3.99 | 0.01 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 push & pop | 221.32 | 4.52 | 0.01 |
10,000 insertBefore | 255.52 | 3.91 | 0.01 |
max-priority-queue
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 refill & poll | 8.91 | 112.29 | 2.26e-4 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 refill & poll | 9.07 | 110.24 | 2.71e-4 |
priority-queue
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add & pop | 103.59 | 9.65 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add & pop | 101.93 | 9.81 | 7.95e-4 |
100,000 CPT add & pop | 28.54 | 35.04 | 0.00 |
deque
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 14.55 | 68.72 | 6.91e-4 |
1,000,000 push & pop | 23.40 | 42.73 | 5.94e-4 |
1,000,000 push & shift | 24.41 | 40.97 | 1.45e-4 |
1,000,000 unshift & shift | 22.56 | 44.32 | 1.30e-4 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 14.43 | 69.29 | 2.36e-4 |
1,000,000 CPT push | 25.08 | 39.87 | 0.01 |
1,000,000 push & pop | 22.87 | 43.72 | 6.05e-4 |
1,000,000 push & shift | 25.28 | 39.55 | 0.01 |
1,000,000 unshift & shift | 21.88 | 45.71 | 2.05e-4 |
queue
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 39.90 | 25.07 | 0.01 |
1,000,000 push & shift | 81.79 | 12.23 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 38.49 | 25.98 | 9.08e-4 |
1,000,000 CPT push | 43.93 | 22.76 | 0.01 |
1,000,000 push & shift | 82.85 | 12.07 | 0.00 |
stack
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 37.60 | 26.60 | 0.00 |
1,000,000 push & pop | 47.01 | 21.27 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 40.19 | 24.88 | 0.01 |
1,000,000 CPT push | 39.87 | 25.08 | 0.00 |
1,000,000 push & pop | 41.67 | 24.00 | 0.01 |
1,000,000 CPT push & pop | 46.65 | 21.44 | 0.00 |
trie
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 push | 45.97 | 21.76 | 0.00 |
100,000 getWords | 66.20 | 15.11 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 push | 43.42 | 23.03 | 7.57e-4 |
100,000 getWords | 93.41 | 10.71 | 0.00 |
[//]: # (No deletion!!! End of Replace Section)
diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts
index ed4e9b0..d26ea3f 100644
--- a/src/data-structures/binary-tree/avl-tree.ts
+++ b/src/data-structures/binary-tree/avl-tree.ts
@@ -11,10 +11,9 @@ import type {
AVLTreeNodeNested,
AVLTreeOptions,
BiTreeDeleteResult,
- BSTNKeyOrNode,
- BTNExemplar,
- BTNKey,
- BTNKeyOrNode
+ BSTNodeKeyOrNode,
+ BTNodeExemplar,
+ BTNKey
} from '../../types';
import { BTNCallback } from '../../types';
import { IBinaryTree } from '../../interfaces';
@@ -38,9 +37,9 @@ export class AVLTree = AVLTreeNode>, options?: Partial) {
+ constructor(elements?: Iterable>, options?: Partial) {
super([], options);
- if (elements) this.init(elements);
+ if (elements) this.addMany(elements);
}
/**
@@ -75,9 +74,9 @@ export class AVLTree = AVLTreeNode, value?: V): N | undefined {
- if (keyOrNode === null) return undefined;
- const inserted = super.add(keyOrNode, value);
+ override add(keyOrNodeOrEntry: BTNodeExemplar): N | undefined {
+ if (keyOrNodeOrEntry === null) return undefined;
+ const inserted = super.add(keyOrNodeOrEntry);
if (inserted) this._balancePath(inserted);
return inserted;
}
@@ -116,23 +115,6 @@ export class AVLTree = AVLTreeNode>): void {
- if (elements) {
- for (const entryOrKey of elements) {
- if (Array.isArray(entryOrKey)) {
- const [key, value] = entryOrKey;
- this.add(key, value);
- } else {
- this.add(entryOrKey);
- }
- }
- }
- }
/**
* The `_swap` function swaps the key, value, and height properties between two nodes in a binary
@@ -144,7 +126,7 @@ export class AVLTree = AVLTreeNode, destNode: BSTNKeyOrNode): N | undefined {
+ protected override _swap(srcNode: BSTNodeKeyOrNode, destNode: BSTNodeKeyOrNode): N | undefined {
srcNode = this.ensureNotKey(srcNode);
destNode = this.ensureNotKey(destNode);
diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts
index dc0b9ff..403b050 100644
--- a/src/data-structures/binary-tree/binary-tree.ts
+++ b/src/data-structures/binary-tree/binary-tree.ts
@@ -10,9 +10,10 @@ import type {
BinaryTreeNodeNested,
BinaryTreeOptions,
BTNCallback,
- BTNExemplar,
+ BTNodeEntry,
+ BTNodeExemplar,
BTNKey,
- BTNKeyOrNode
+ BTNodeKeyOrNode
} from '../../types';
import {
BinaryTreeNested,
@@ -131,7 +132,7 @@ export class BinaryTree = BinaryTreeNode
* Creates a new instance of BinaryTree.
* @param {BinaryTreeOptions} [options] - The options for the binary tree.
*/
- constructor(elements?: Iterable>, options?: Partial) {
+ constructor(elements?: Iterable>, options?: Partial) {
if (options) {
const { iterationType } = options;
@@ -142,7 +143,7 @@ export class BinaryTree = BinaryTreeNode
this._size = 0;
- if (elements) this.init(elements);
+ if (elements) this.addMany(elements);
}
protected _root?: N | null;
@@ -177,6 +178,10 @@ export class BinaryTree = BinaryTreeNode
return new BinaryTree([], { iterationType: this.iterationType, ...options }) as TREE;
}
+ isEntry(kne: BTNodeExemplar): kne is BTNodeEntry {
+ return Array.isArray(kne) && kne.length === 2;
+ }
+
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
@@ -190,7 +195,7 @@ export class BinaryTree = BinaryTreeNode
* @returns The function `add` returns a node (`N`) if it was successfully inserted into the binary
* tree, or `null` or `undefined` if the insertion was not successful.
*/
- add(keyOrNode: BTNKeyOrNode, value?: V): N | null | undefined {
+ add(keyOrNodeOrEntry: BTNodeExemplar): N | null | undefined {
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
const queue = new Queue([root]);
while (queue.size > 0) {
@@ -208,12 +213,21 @@ export class BinaryTree = BinaryTreeNode
let inserted: N | null | undefined, needInsert: N | null | undefined;
- if (keyOrNode === null) {
+ if (keyOrNodeOrEntry === null) {
needInsert = null;
- } else if (this.isNodeKey(keyOrNode)) {
- needInsert = this.createNode(keyOrNode, value);
- } else if (keyOrNode instanceof BinaryTreeNode) {
- needInsert = keyOrNode;
+ } else if (this.isNodeKey(keyOrNodeOrEntry)) {
+ needInsert = this.createNode(keyOrNodeOrEntry);
+ } else if (keyOrNodeOrEntry instanceof BinaryTreeNode) {
+ needInsert = keyOrNodeOrEntry;
+ } else if (this.isEntry(keyOrNodeOrEntry)) {
+ const [key, value] = keyOrNodeOrEntry;
+ if (key === undefined) {
+ return;
+ } else if (key === null) {
+ needInsert = null;
+ } else {
+ needInsert = this.createNode(key, value);
+ }
} else {
return;
}
@@ -252,19 +266,19 @@ export class BinaryTree = BinaryTreeNode
* keys or nodes during the add operation.
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
- addMany(keysOrNodes: (BTNKeyOrNode)[], values?: (V | undefined)[]): (N | null | undefined)[] {
+ addMany(nodes: Iterable>): (N | null | undefined)[] {
// TODO not sure addMany not be run multi times
+ const keysOrNodes = [...nodes];
return keysOrNodes.map((keyOrNode, i) => {
if (keyOrNode instanceof BinaryTreeNode) {
- return this.add(keyOrNode.key, keyOrNode.value);
+ return this.add(keyOrNode);
}
if (keyOrNode === null) {
return this.add(null);
}
- const value = values?.[i];
- return this.add(keyOrNode, value);
+ return this.add(keyOrNode);
});
}
@@ -285,9 +299,9 @@ export class BinaryTree = BinaryTreeNode
* array. Each value in the `data` array will be assigned to the
* @returns The method is returning a boolean value.
*/
- refill(keysOrNodes: (BTNKeyOrNode)[], values?: (V | undefined)[]): boolean {
+ refill(nodesOrKeysOrEntries: Iterable>): void {
this.clear();
- return keysOrNodes.length === this.addMany(keysOrNodes, values).length;
+ this.addMany(nodesOrKeysOrEntries);
}
/**
@@ -384,7 +398,7 @@ export class BinaryTree = BinaryTreeNode
* `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot
* @returns the depth of the `distNode` relative to the `beginRoot`.
*/
- getDepth(distNode: BTNKeyOrNode, beginRoot: BTNKeyOrNode = this.root): number {
+ getDepth(distNode: BTNodeKeyOrNode, beginRoot: BTNodeKeyOrNode = this.root): number {
distNode = this.ensureNotKey(distNode);
beginRoot = this.ensureNotKey(beginRoot);
let depth = 0;
@@ -417,7 +431,7 @@ export class BinaryTree = BinaryTreeNode
* values:
* @returns the height of the binary tree.
*/
- getHeight(beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType): number {
+ getHeight(beginRoot: BTNodeKeyOrNode = this.root, iterationType = this.iterationType): number {
beginRoot = this.ensureNotKey(beginRoot);
if (!beginRoot) return -1;
@@ -466,7 +480,7 @@ export class BinaryTree = BinaryTreeNode
* to calculate the minimum height of a binary tree. It can have two possible values:
* @returns The function `getMinHeight` returns the minimum height of a binary tree.
*/
- getMinHeight(beginRoot: BTNKeyOrNode = this.root, iterationType = this.iterationType): number {
+ getMinHeight(beginRoot: BTNodeKeyOrNode = this.root, iterationType = this.iterationType): number {
beginRoot = this.ensureNotKey(beginRoot);
if (!beginRoot) return -1;
@@ -526,7 +540,7 @@ export class BinaryTree = BinaryTreeNode
* value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If
* @returns a boolean value.
*/
- isPerfectlyBalanced(beginRoot: BTNKeyOrNode = this.root): boolean {
+ isPerfectlyBalanced(beginRoot: BTNodeKeyOrNode = this.root): boolean {
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
}
@@ -539,7 +553,7 @@ export class BinaryTree = BinaryTreeNode
identifier: BTNKey,
callback?: C,
onlyOne?: boolean,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): N[];
@@ -547,7 +561,7 @@ export class BinaryTree = BinaryTreeNode
identifier: N | null | undefined,
callback?: C,
onlyOne?: boolean,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): N[];
@@ -555,7 +569,7 @@ export class BinaryTree = BinaryTreeNode
identifier: ReturnType,
callback: C,
onlyOne?: boolean,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): N[];
@@ -588,7 +602,7 @@ export class BinaryTree = BinaryTreeNode
identifier: ReturnType | null | undefined,
callback: C = this._defaultOneParamCallback as C,
onlyOne = false,
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType = this.iterationType
): N[] {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -636,21 +650,21 @@ export class BinaryTree = BinaryTreeNode
has>(
identifier: BTNKey,
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): boolean;
has>(
identifier: N | null | undefined,
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): boolean;
has>(
identifier: ReturnType | null | undefined,
callback: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): boolean;
@@ -677,7 +691,7 @@ export class BinaryTree = BinaryTreeNode
has>(
identifier: ReturnType | null | undefined,
callback: C = this._defaultOneParamCallback as C,
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType = this.iterationType
): boolean {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -694,21 +708,21 @@ export class BinaryTree = BinaryTreeNode
getNode>(
identifier: BTNKey,
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): N | null | undefined;
getNode>(
identifier: N | null | undefined,
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): N | null | undefined;
getNode>(
identifier: ReturnType,
callback: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): N | null | undefined;
@@ -736,7 +750,7 @@ export class BinaryTree = BinaryTreeNode
getNode>(
identifier: ReturnType | null | undefined,
callback: C = this._defaultOneParamCallback as C,
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType = this.iterationType
): N | null | undefined {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -805,28 +819,28 @@ export class BinaryTree = BinaryTreeNode
* @returns either the node corresponding to the given key if it is a valid node key, or the key
* itself if it is not a valid node key.
*/
- ensureNotKey(key: BTNKeyOrNode, iterationType = IterationType.ITERATIVE): N | null | undefined {
+ ensureNotKey(key: BTNodeKeyOrNode, iterationType = IterationType.ITERATIVE): N | null | undefined {
return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
}
get>(
identifier: BTNKey,
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): V | undefined;
get>(
identifier: N | null | undefined,
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): V | undefined;
get>(
identifier: ReturnType,
callback: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType
): V | undefined;
@@ -855,7 +869,7 @@ export class BinaryTree = BinaryTreeNode
get>(
identifier: ReturnType | null | undefined,
callback: C = this._defaultOneParamCallback as C,
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType = this.iterationType
): V | undefined {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@@ -899,7 +913,7 @@ export class BinaryTree = BinaryTreeNode
* reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is
* @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
*/
- getPathToRoot(beginRoot: BTNKeyOrNode, isReverse = true): N[] {
+ getPathToRoot(beginRoot: BTNodeKeyOrNode, isReverse = true): N[] {
// TODO to support get path through passing key
const result: N[] = [];
beginRoot = this.ensureNotKey(beginRoot);
@@ -936,7 +950,7 @@ export class BinaryTree = BinaryTreeNode
* is no leftmost node, it returns `null` or `undefined` depending on the input.
*/
getLeftMost(
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType = this.iterationType
): N | null | undefined {
beginRoot = this.ensureNotKey(beginRoot);
@@ -982,7 +996,7 @@ export class BinaryTree = BinaryTreeNode
* is no rightmost node, it returns `null` or `undefined`, depending on the input.
*/
getRightMost(
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType = this.iterationType
): N | null | undefined {
// TODO support get right most by passing key in
@@ -1024,7 +1038,7 @@ export class BinaryTree = BinaryTreeNode
* possible values:
* @returns a boolean value.
*/
- isSubtreeBST(beginRoot: BTNKeyOrNode, iterationType = this.iterationType): boolean {
+ isSubtreeBST(beginRoot: BTNodeKeyOrNode, iterationType = this.iterationType): boolean {
// TODO there is a bug
beginRoot = this.ensureNotKey(beginRoot);
if (!beginRoot) return true;
@@ -1083,21 +1097,21 @@ export class BinaryTree = BinaryTreeNode
subTreeTraverse>(
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: false
): ReturnType[];
subTreeTraverse>(
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: undefined
): ReturnType[];
subTreeTraverse>(
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: true
): ReturnType[];
@@ -1126,7 +1140,7 @@ export class BinaryTree = BinaryTreeNode
*/
subTreeTraverse>(
callback: C = this._defaultOneParamCallback as C,
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType = this.iterationType,
includeNull = false
): ReturnType[] {
@@ -1216,7 +1230,7 @@ export class BinaryTree = BinaryTreeNode
dfs>(
callback?: C,
pattern?: DFSOrderPattern,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: false
): ReturnType[];
@@ -1224,7 +1238,7 @@ export class BinaryTree = BinaryTreeNode
dfs>(
callback?: C,
pattern?: DFSOrderPattern,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: undefined
): ReturnType[];
@@ -1232,7 +1246,7 @@ export class BinaryTree = BinaryTreeNode
dfs>(
callback?: C,
pattern?: DFSOrderPattern,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: true
): ReturnType[];
@@ -1263,7 +1277,7 @@ export class BinaryTree = BinaryTreeNode
dfs>(
callback: C = this._defaultOneParamCallback as C,
pattern: DFSOrderPattern = 'in',
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType: IterationType = IterationType.ITERATIVE,
includeNull = false
): ReturnType[] {
@@ -1362,21 +1376,21 @@ export class BinaryTree = BinaryTreeNode
bfs>(
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: false
): ReturnType[];
bfs>(
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: undefined
): ReturnType[];
bfs>(
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: true
): ReturnType[];
@@ -1404,7 +1418,7 @@ export class BinaryTree = BinaryTreeNode
*/
bfs>(
callback: C = this._defaultOneParamCallback as C,
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType = this.iterationType,
includeNull = false
): ReturnType[] {
@@ -1463,21 +1477,21 @@ export class BinaryTree = BinaryTreeNode
listLevels>(
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: false
): ReturnType[][];
listLevels>(
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: undefined
): ReturnType[][];
listLevels>(
callback?: C,
- beginRoot?: BTNKeyOrNode,
+ beginRoot?: BTNodeKeyOrNode,
iterationType?: IterationType,
includeNull?: true
): ReturnType[][];
@@ -1505,7 +1519,7 @@ export class BinaryTree = BinaryTreeNode
*/
listLevels>(
callback: C = this._defaultOneParamCallback as C,
- beginRoot: BTNKeyOrNode = this.root,
+ beginRoot: BTNodeKeyOrNode = this.root,
iterationType = this.iterationType,
includeNull = false
): ReturnType[][] {
@@ -1563,7 +1577,7 @@ export class BinaryTree = BinaryTreeNode
* `null`, or `undefined`.
* @returns The function `getPredecessor` returns a value of type `N | undefined`.
*/
- getPredecessor(node: BTNKeyOrNode): N | undefined {
+ getPredecessor(node: BTNodeKeyOrNode): N | undefined {
node = this.ensureNotKey(node);
if (!this.isRealNode(node)) return undefined;
@@ -1623,7 +1637,7 @@ export class BinaryTree = BinaryTreeNode
morris>(
callback: C = this._defaultOneParamCallback as C,
pattern: DFSOrderPattern = 'in',
- beginRoot: BTNKeyOrNode = this.root
+ beginRoot: BTNodeKeyOrNode = this.root
): ReturnType[] {
beginRoot = this.ensureNotKey(beginRoot);
if (beginRoot === null) return [];
@@ -1735,7 +1749,7 @@ export class BinaryTree = BinaryTreeNode
const newTree = this.createTree();
for (const [key, value] of this) {
if (predicate([key, value], this)) {
- newTree.add(key, value);
+ newTree.add([key, value]);
}
}
return newTree;
@@ -1750,7 +1764,7 @@ export class BinaryTree = BinaryTreeNode
map(callback: (entry: [BTNKey, V | undefined], tree: this) => V) {
const newTree = this.createTree();
for (const [key, value] of this) {
- newTree.add(key, callback([key, value], this));
+ newTree.add([key, callback([key, value], this)]);
}
return newTree;
}
@@ -1831,7 +1845,7 @@ export class BinaryTree = BinaryTreeNode
* following types:
* @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.
*/
- print(beginRoot: BTNKeyOrNode = this.root, options?: BinaryTreePrintOptions): void {
+ print(beginRoot: BTNodeKeyOrNode = this.root, options?: BinaryTreePrintOptions): void {
const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };
beginRoot = this.ensureNotKey(beginRoot);
if (!beginRoot) return;
@@ -1853,19 +1867,6 @@ export class BinaryTree = BinaryTreeNode
display(beginRoot);
}
- init(elements: Iterable>): void {
- if (elements) {
- for (const entryOrKey of elements) {
- if (Array.isArray(entryOrKey)) {
- const [key, value] = entryOrKey;
- this.add(key, value);
- } else {
- this.add(entryOrKey);
- }
- }
- }
- }
-
protected _displayAux(node: N | null | undefined, options: BinaryTreePrintOptions): NodeDisplayLayout {
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
const emptyDisplayLayout = [['─'], 1, 0, 0];
@@ -1924,7 +1925,7 @@ export class BinaryTree = BinaryTreeNode
* @param {N} destNode - The destination node to swap.
* @returns {N} - The destination node after the swap.
*/
- protected _swap(srcNode: BTNKeyOrNode, destNode: BTNKeyOrNode): N | undefined {
+ protected _swap(srcNode: BTNodeKeyOrNode, destNode: BTNodeKeyOrNode): N | undefined {
srcNode = this.ensureNotKey(srcNode);
destNode = this.ensureNotKey(destNode);
@@ -1956,7 +1957,7 @@ export class BinaryTree = BinaryTreeNode
* the binary tree. If neither the left nor right child is available, the function returns undefined.
* If the parent node is null, the function also returns undefined.
*/
- protected _addTo(newNode: N | null | undefined, parent: BTNKeyOrNode): N | null | undefined {
+ protected _addTo(newNode: N | null | undefined, parent: BTNodeKeyOrNode): N | null | undefined {
if (this.isNodeKey(parent)) parent = this.getNode(parent);
if (parent) {
diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts
index 64f9aa1..d805937 100644
--- a/src/data-structures/binary-tree/bst.ts
+++ b/src/data-structures/binary-tree/bst.ts
@@ -7,14 +7,14 @@
*/
import type {
BSTNested,
- BSTNKeyOrNode,
+ BSTNodeKeyOrNode,
BSTNodeNested,
BSTOptions,
BTNCallback,
- BTNExemplar,
+ BTNodeExemplar,
BTNKey,
- BTNKeyOrNode,
- Comparator
+ Comparator,
+ BTNodePureExemplar
} from '../../types';
import { CP, IterationType } from '../../types';
import { BinaryTree, BinaryTreeNode } from './binary-tree';
@@ -76,12 +76,8 @@ export class BST = BSTNode>
extends BinaryTree
implements IBinaryTree {
- /**
- * The constructor function initializes a binary search tree with an optional comparator function.
- * @param {BSTOptions} [options] - An optional object that contains additional configuration options
- * for the binary search tree.
- */
- constructor(elements?: Iterable>, options?: Partial) {
+
+ constructor(elements?: Iterable>, options?: Partial) {
super([], options);
if (options) {
@@ -92,7 +88,8 @@ export class BST = BSTNode>
}
this._root = undefined;
- if (elements) this.init(elements);
+
+ if (elements) this.addMany(elements);
}
protected override _root?: N;
@@ -137,15 +134,23 @@ export class BST = BSTNode>
* @returns The method `add` returns a node (`N`) that was inserted into the binary search tree. If
* no node was inserted, it returns `undefined`.
*/
- override add(keyOrNode: BTNKeyOrNode, value?: V): N | undefined {
- if (keyOrNode === null) return undefined;
+ override add(keyOrNodeOrEntry: BTNodeExemplar): N | undefined {
+ if (keyOrNodeOrEntry === null) return undefined;
// TODO support node as a parameter
let inserted: N | undefined;
let newNode: N | undefined;
- if (keyOrNode instanceof BSTNode) {
- newNode = keyOrNode;
- } else if (this.isNodeKey(keyOrNode)) {
- newNode = this.createNode(keyOrNode, value);
+ if (keyOrNodeOrEntry instanceof BSTNode) {
+ newNode = keyOrNodeOrEntry;
+ } else if (this.isNodeKey(keyOrNodeOrEntry)) {
+ newNode = this.createNode(keyOrNodeOrEntry);
+ } else if (this.isEntry(keyOrNodeOrEntry)) {
+ const [key, value] = keyOrNodeOrEntry;
+ if (key === undefined || key === null) {
+ return;
+ } else {
+ newNode = this.createNode(key, value);
+
+ }
} else {
newNode = undefined;
}
@@ -230,57 +235,55 @@ export class BST = BSTNode>
* @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values.
*/
override addMany(
- keysOrNodes: (BSTNKeyOrNode)[],
- data?: (V | undefined)[],
+ keysOrNodesOrEntries: Iterable>,
isBalanceAdd = true,
iterationType = this.iterationType
): (N | undefined)[] {
+ const inserted: (N | undefined)[] = []
+ if (!isBalanceAdd) {
+ for (const kve of keysOrNodesOrEntries) {
+ const nn = this.add(kve)
+ inserted.push(nn);
+ }
+ return inserted;
+ }
+ const realBTNExemplars: BTNodePureExemplar[] = [];
+
+
+ const isRealBTNExemplar = (kve: BTNodeExemplar): kve is BTNodePureExemplar => {
+ if (kve === undefined || kve === null) return false;
+ return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
+ }
+
+ for (const kve of keysOrNodesOrEntries) {
+ isRealBTNExemplar(kve) && realBTNExemplars.push(kve);
+ }
+
// TODO this addMany function is inefficient, it should be optimized
- function hasNoUndefined(arr: (BSTNKeyOrNode)[]): arr is (BTNKey | N)[] {
- return arr.indexOf(undefined) === -1;
- }
+ let sorted: BTNodePureExemplar[] = [];
- if (!isBalanceAdd || !hasNoUndefined(keysOrNodes)) {
- return super.addMany(keysOrNodes, data).map(n => n ?? undefined);
- }
+ sorted = realBTNExemplars.sort((a, b) => {
+ let aR: number, bR: number;
+ if (this.isEntry(a)) aR = a[0]
+ else if (this.isRealNode(a)) aR = a.key
+ else aR = a;
- const inserted: (N | undefined)[] = [];
- const combinedArr: [BTNKey | N, V][] = keysOrNodes.map(
- (value: BTNKey | N, index) => [value, data?.[index]] as [BTNKey | N, V]
- );
+ if (this.isEntry(b)) bR = b[0]
+ else if (this.isRealNode(b)) bR = b.key
+ else bR = b;
- let sorted = [];
+ return aR - bR;
+ })
- function _isNodeOrUndefinedTuple(arr: [BTNKey | N, V][]): arr is [N, V][] {
- for (const [keyOrNode] of arr) if (keyOrNode instanceof BSTNode) return true;
- return false;
- }
- const _isBinaryTreeKeyOrNullTuple = (arr: [BTNKey | N, V][]): arr is [BTNKey, V][] => {
- for (const [keyOrNode] of arr) if (this.isNodeKey(keyOrNode)) return true;
- return false;
- };
-
- let sortedKeysOrNodes: (number | N | undefined)[] = [],
- sortedData: (V | undefined)[] | undefined = [];
-
- if (_isNodeOrUndefinedTuple(combinedArr)) {
- sorted = combinedArr.sort((a, b) => a[0].key - b[0].key);
- } else if (_isBinaryTreeKeyOrNullTuple(combinedArr)) {
- sorted = combinedArr.sort((a, b) => a[0] - b[0]);
- } else {
- throw new Error('Invalid input keysOrNodes');
- }
- sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode);
- sortedData = sorted.map(([, value]) => value);
- const _dfs = (arr: (BSTNKeyOrNode)[], data?: (V | undefined)[]) => {
+ const _dfs = (arr: BTNodePureExemplar[]) => {
if (arr.length === 0) return;
const mid = Math.floor((arr.length - 1) / 2);
- const newNode = this.add(arr[mid], data?.[mid]);
+ const newNode = this.add(arr[mid]);
inserted.push(newNode);
- _dfs(arr.slice(0, mid), data?.slice(0, mid));
- _dfs(arr.slice(mid + 1), data?.slice(mid + 1));
+ _dfs(arr.slice(0, mid));
+ _dfs(arr.slice(mid + 1));
};
const _iterate = () => {
const n = sorted.length;
@@ -291,7 +294,7 @@ export class BST = BSTNode>
const [l, r] = popped;
if (l <= r) {
const m = l + Math.floor((r - l) / 2);
- const newNode = this.add(sortedKeysOrNodes[m], sortedData?.[m]);
+ const newNode = this.add(realBTNExemplars[m]);
inserted.push(newNode);
stack.push([m + 1, r]);
stack.push([l, m - 1]);
@@ -300,7 +303,7 @@ export class BST = BSTNode>
}
};
if (iterationType === IterationType.RECURSIVE) {
- _dfs(sortedKeysOrNodes, sortedData);
+ _dfs(sorted);
} else {
_iterate();
}
@@ -328,7 +331,7 @@ export class BST