diff --git a/CHANGELOG.md b/CHANGELOG.md
index 15df49a..bb0a83a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
- [`auto-changelog`](https://github.com/CookPete/auto-changelog)
-## [v1.50.9](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
+## [v1.51.0](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
### Changes
diff --git a/README.md b/README.md
index 1edd0c8..a379ff5 100644
--- a/README.md
+++ b/README.md
@@ -104,7 +104,7 @@ Performance surpasses that of native JS/TS
### Conciseness and uniformity
In [java.utils](), you need to memorize a table for all sequential data structures(Queue, Deque, LinkedList),
-
+
Java ArrayList |
@@ -687,43 +687,43 @@ Version 11.7.9
[//]: # (No deletion!!! Start of Replace Section)
heap
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 6.58 | 152.07 | 3.13e-4 |
100,000 add & poll | 35.67 | 28.03 | 0.01 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 6.36 | 157.24 | 1.88e-4 |
100,000 add & poll | 32.56 | 30.72 | 0.01 |
rb-tree
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 55.91 | 17.89 | 0.01 |
100,000 get | 125.11 | 7.99 | 0.01 |
100,000 iterator | 27.97 | 35.76 | 0.01 |
100,000 add & delete orderly | 125.06 | 8.00 | 0.00 |
100,000 add & delete randomly | 242.78 | 4.12 | 0.01 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 55.46 | 18.03 | 0.00 |
100,000 get | 114.63 | 8.72 | 0.00 |
100,000 iterator | 26.52 | 37.71 | 0.01 |
100,000 add & delete orderly | 128.13 | 7.80 | 0.02 |
100,000 add & delete randomly | 228.89 | 4.37 | 0.00 |
queue
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 44.81 | 22.32 | 0.01 |
100,000 push & shift | 4.99 | 200.39 | 7.40e-4 |
Native JS Array 100,000 push & shift | 2234.97 | 0.45 | 0.19 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 43.53 | 22.97 | 0.01 |
100,000 push & shift | 4.80 | 208.14 | 5.81e-4 |
Native JS Array 100,000 push & shift | 2201.64 | 0.45 | 0.11 |
deque
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 24.34 | 41.08 | 0.01 |
1,000,000 push & pop | 31.41 | 31.83 | 0.00 |
1,000,000 push & shift | 31.12 | 32.13 | 0.00 |
100,000 push & shift | 3.27 | 306.17 | 2.62e-4 |
Native JS Array 100,000 push & shift | 2362.95 | 0.42 | 0.12 |
100,000 unshift & shift | 2.89 | 345.46 | 3.23e-4 |
Native JS Array 100,000 unshift & shift | 4313.81 | 0.23 | 0.13 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 25.91 | 38.59 | 0.01 |
1,000,000 push & pop | 30.71 | 32.57 | 0.00 |
1,000,000 push & shift | 30.59 | 32.69 | 0.00 |
100,000 push & shift | 3.23 | 309.94 | 2.61e-4 |
Native JS Array 100,000 push & shift | 2525.12 | 0.40 | 0.39 |
100,000 unshift & shift | 2.87 | 347.92 | 2.86e-4 |
Native JS Array 100,000 unshift & shift | 4400.38 | 0.23 | 0.14 |
hash-map
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 set | 118.81 | 8.42 | 0.02 |
Native JS Map 1,000,000 set | 218.24 | 4.58 | 0.02 |
Native JS Set 1,000,000 add | 180.64 | 5.54 | 0.03 |
1,000,000 set & get | 121.23 | 8.25 | 0.01 |
Native JS Map 1,000,000 set & get | 273.71 | 3.65 | 0.01 |
Native JS Set 1,000,000 add & has | 173.69 | 5.76 | 0.01 |
1,000,000 ObjKey set & get | 331.89 | 3.01 | 0.04 |
Native JS Map 1,000,000 ObjKey set & get | 331.49 | 3.02 | 0.05 |
Native JS Set 1,000,000 ObjKey add & has | 308.15 | 3.25 | 0.04 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 set | 113.02 | 8.85 | 0.02 |
Native JS Map 1,000,000 set | 201.23 | 4.97 | 0.00 |
Native JS Set 1,000,000 add | 168.53 | 5.93 | 0.01 |
1,000,000 set & get | 118.49 | 8.44 | 0.02 |
Native JS Map 1,000,000 set & get | 263.49 | 3.80 | 0.01 |
Native JS Set 1,000,000 add & has | 168.28 | 5.94 | 0.01 |
1,000,000 ObjKey set & get | 309.88 | 3.23 | 0.01 |
Native JS Map 1,000,000 ObjKey set & get | 282.50 | 3.54 | 0.04 |
Native JS Set 1,000,000 ObjKey add & has | 268.42 | 3.73 | 0.03 |
trie
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 push | 58.78 | 17.01 | 0.02 |
100,000 getWords | 95.99 | 10.42 | 0.01 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 push | 44.85 | 22.30 | 0.01 |
100,000 getWords | 84.84 | 11.79 | 0.01 |
avl-tree
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 add randomly | 50.17 | 19.93 | 0.01 |
10,000 get | 20.86 | 47.94 | 0.00 |
10,000 add & delete randomly | 79.18 | 12.63 | 0.00 |
10,000 addMany | 52.92 | 18.90 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 381.63 | 2.62 | 0.00 |
100,000 get | 354.69 | 2.82 | 0.00 |
100,000 iterator | 29.87 | 33.48 | 0.01 |
100,000 add & delete orderly | 652.77 | 1.53 | 0.00 |
100,000 add & delete randomly | 929.07 | 1.08 | 0.00 |
binary-tree-overall
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 RBTree add | 5.69 | 175.82 | 5.70e-4 |
10,000 RBTree add & delete randomly | 19.94 | 50.16 | 0.00 |
10,000 RBTree get | 0.65 | 1543.77 | 1.81e-5 |
10,000 AVLTree add | 44.46 | 22.49 | 0.00 |
10,000 AVLTree get | 20.07 | 49.84 | 0.00 |
10,000 AVLTree add & delete randomly | 77.29 | 12.94 | 0.01 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
10,000 RBTree add | 5.55 | 180.05 | 7.09e-5 |
10,000 RBTree add & delete randomly | 19.06 | 52.46 | 1.94e-4 |
10,000 RBTree get | 0.61 | 1647.37 | 6.11e-6 |
10,000 AVLTree add | 32.03 | 31.22 | 7.32e-4 |
10,000 AVLTree get | 19.65 | 50.89 | 3.12e-4 |
10,000 AVLTree add & delete randomly | 62.07 | 16.11 | 4.26e-4 |
directed-graph
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 addVertex | 0.10 | 9883.75 | 9.48e-7 |
1,000 addEdge | 6.05 | 165.15 | 1.08e-4 |
1,000 getVertex | 0.05 | 2.15e+4 | 5.74e-7 |
1,000 getEdge | 23.58 | 42.41 | 0.00 |
tarjan | 208.84 | 4.79 | 0.01 |
topologicalSort | 180.27 | 5.55 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000 addVertex | 0.10 | 9939.30 | 9.29e-7 |
1,000 addEdge | 6.15 | 162.54 | 8.71e-4 |
1,000 getVertex | 0.05 | 2.18e+4 | 2.83e-7 |
1,000 getEdge | 23.93 | 41.78 | 0.00 |
tarjan | 207.83 | 4.81 | 0.01 |
topologicalSort | 181.91 | 5.50 | 0.00 |
doubly-linked-list
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 208.91 | 4.79 | 0.07 |
1,000,000 unshift | 202.73 | 4.93 | 0.03 |
1,000,000 unshift & shift | 182.70 | 5.47 | 0.06 |
1,000,000 addBefore | 314.16 | 3.18 | 0.06 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 210.21 | 4.76 | 0.03 |
1,000,000 unshift | 218.63 | 4.57 | 0.05 |
1,000,000 unshift & shift | 162.14 | 6.17 | 0.01 |
1,000,000 addBefore | 319.75 | 3.13 | 0.06 |
singly-linked-list
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push & shift | 207.94 | 4.81 | 0.05 |
10,000 push & pop | 216.07 | 4.63 | 0.01 |
10,000 addBefore | 246.19 | 4.06 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push & shift | 191.55 | 5.22 | 0.03 |
10,000 push & pop | 215.95 | 4.63 | 0.01 |
10,000 addBefore | 249.82 | 4.00 | 0.01 |
priority-queue
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 27.00 | 37.04 | 2.43e-4 |
100,000 add & poll | 77.16 | 12.96 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
100,000 add | 27.54 | 36.31 | 2.55e-4 |
100,000 add & poll | 75.88 | 13.18 | 4.27e-4 |
stack
-
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 39.29 | 25.45 | 0.00 |
1,000,000 push & pop | 48.05 | 20.81 | 0.00 |
+
test name | time taken (ms) | executions per sec | sample deviation |
---|
1,000,000 push | 39.78 | 25.14 | 0.01 |
1,000,000 push & pop | 46.90 | 21.32 | 0.01 |
[//]: # (No deletion!!! End of Replace Section)
diff --git a/package-lock.json b/package-lock.json
index a83a61c..8fae293 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "data-structure-typed",
- "version": "1.50.9",
+ "version": "1.51.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "data-structure-typed",
- "version": "1.50.9",
+ "version": "1.51.0",
"license": "MIT",
"devDependencies": {
"@swc/core": "^1.3.96",
diff --git a/package.json b/package.json
index a15f1eb..b6ae07a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "data-structure-typed",
- "version": "1.50.9",
+ "version": "1.51.0",
"description": "Javascript Data Structure. Heap, Binary Tree, Red Black Tree, Linked List, Deque, Trie, HashMap, Directed Graph, Undirected Graph, Binary Search Tree(BST), AVL Tree, Priority Queue, Graph, Queue, Tree Multiset, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue, Stack. Benchmark compared with C++ STL. API aligned with ES6 and Java.util. Usability is comparable to Python",
"main": "dist/cjs/index.js",
"module": "dist/mjs/index.js",
diff --git a/src/data-structures/binary-tree/avl-tree-multi-map.ts b/src/data-structures/binary-tree/avl-tree-multi-map.ts
index b095a92..281eb41 100644
--- a/src/data-structures/binary-tree/avl-tree-multi-map.ts
+++ b/src/data-structures/binary-tree/avl-tree-multi-map.ts
@@ -240,7 +240,7 @@ export class AVLTreeMultiMap<
*/
override delete>(
identifier: ReturnType,
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
ignoreCount = false
): BinaryTreeDeleteResult[] {
const deletedResult: BinaryTreeDeleteResult[] = [];
diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts
index b8e5074..8ec899e 100644
--- a/src/data-structures/binary-tree/avl-tree.ts
+++ b/src/data-structures/binary-tree/avl-tree.ts
@@ -164,13 +164,13 @@ export class AVLTree<
* `callback` function.
* @param {C} callback - The `callback` parameter is a function that will be called for each node
* that is deleted from the binary tree. It is an optional parameter and if not provided, it will
- * default to the `_defaultOneParamCallback` function. The `callback` function should have a single
+ * default to the `_DEFAULT_CALLBACK` function. The `callback` function should have a single
* parameter of type `NODE
* @returns The method is returning an array of `BinaryTreeDeleteResult`.
*/
override delete>(
identifier: ReturnType,
- callback: C = this._defaultOneParamCallback as C
+ callback: C = this._DEFAULT_CALLBACK as C
): BinaryTreeDeleteResult[] {
if ((identifier as any) instanceof AVLTreeNode) callback = (node => node) as C;
const deletedResults = super.delete(identifier, callback);
diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts
index 6467200..a111f74 100644
--- a/src/data-structures/binary-tree/binary-tree.ts
+++ b/src/data-structures/binary-tree/binary-tree.ts
@@ -268,17 +268,17 @@ export class BinaryTree<
keyOrNodeOrEntry: KeyOrNodeOrEntry,
iterationType: IterationType = 'ITERATIVE'
): NODE | null | undefined {
- let res: NODE | null | undefined;
if (this.isRealNode(keyOrNodeOrEntry)) {
- res = keyOrNodeOrEntry;
+ return keyOrNodeOrEntry;
} else if (this.isEntry(keyOrNodeOrEntry)) {
- if (keyOrNodeOrEntry[0] === null) res = null;
- else if (keyOrNodeOrEntry[0] !== undefined) res = this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
+ if (keyOrNodeOrEntry[0] === null) return null;
+ if (keyOrNodeOrEntry[0] === undefined) return;
+ return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
} else {
- if (keyOrNodeOrEntry === null) res = null;
- else if (keyOrNodeOrEntry !== undefined) res = this.getNodeByKey(keyOrNodeOrEntry, iterationType);
+ if (keyOrNodeOrEntry === null) return null;
+ if (keyOrNodeOrEntry === undefined) return;
+ return this.getNodeByKey(keyOrNodeOrEntry, iterationType);
}
- return res;
}
/**
@@ -486,16 +486,16 @@ export class BinaryTree<
* specific node based on its value or object.
* @param {C} callback - The `callback` parameter is a function that is used to determine the
* identifier of the node to be deleted. It is optional and has a default value of
- * `this._defaultOneParamCallback`. The `callback` function should return the identifier of the node.
+ * `this._DEFAULT_CALLBACK`. The `callback` function should return the identifier of the node.
* @returns an array of `BinaryTreeDeleteResult`.
*/
delete>(
identifier: ReturnType | null | undefined,
- callback: C = this._defaultOneParamCallback as C
+ callback: C = this._DEFAULT_CALLBACK as C
): BinaryTreeDeleteResult[] {
const deletedResult: BinaryTreeDeleteResult[] = [];
if (!this.root) return deletedResult;
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
const curr = this.getNode(identifier, callback);
@@ -579,7 +579,7 @@ export class BinaryTree<
* specific value.
* @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as
* input and returns a value of type `C`. It is used to determine if a node matches the given
- * identifier. If no callback is provided, the `_defaultOneParamCallback` function is used as the
+ * identifier. If no callback is provided, the `_DEFAULT_CALLBACK` function is used as the
* default
* @param [onlyOne=false] - A boolean value indicating whether to only return the first node that
* matches the identifier. If set to true, the function will stop iterating once it finds a matching
@@ -594,12 +594,12 @@ export class BinaryTree<
*/
getNodes>(
identifier: ReturnType | null | undefined,
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
onlyOne = false,
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType
): NODE[] {
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
beginRoot = this.ensureNode(beginRoot);
if (!beginRoot) return [];
@@ -607,28 +607,28 @@ export class BinaryTree<
const ans: NODE[] = [];
if (iterationType === 'RECURSIVE') {
- const _traverse = (cur: NODE) => {
+ const dfs = (cur: NODE) => {
if (callback(cur) === identifier) {
ans.push(cur);
if (onlyOne) return;
}
if (!cur.left && !cur.right) return;
- cur.left && _traverse(cur.left);
- cur.right && _traverse(cur.right);
+ cur.left && dfs(cur.left);
+ cur.right && dfs(cur.right);
};
- _traverse(beginRoot);
+ dfs(beginRoot);
} else {
- const queue = new Queue([beginRoot]);
- while (queue.size > 0) {
- const cur = queue.shift();
+ const stack = [beginRoot];
+ while (stack.length > 0) {
+ const cur = stack.pop();
if (cur) {
if (callback(cur) === identifier) {
ans.push(cur);
if (onlyOne) return ans;
}
- cur.left && queue.push(cur.left);
- cur.right && queue.push(cur.right);
+ cur.left && stack.push(cur.left);
+ cur.right && stack.push(cur.right);
}
}
}
@@ -685,11 +685,11 @@ export class BinaryTree<
*/
getNode>(
identifier: ReturnType | null | undefined,
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType
): NODE | null | undefined {
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
@@ -717,23 +717,23 @@ export class BinaryTree<
getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
if (!this.root) return undefined;
if (iterationType === 'RECURSIVE') {
- const _dfs = (cur: NODE): NODE | undefined => {
+ const dfs = (cur: NODE): NODE | undefined => {
if (cur.key === key) return cur;
if (!cur.left && !cur.right) return;
- if (cur.left) return _dfs(cur.left);
- if (cur.right) return _dfs(cur.right);
+ if (cur.left) return dfs(cur.left);
+ if (cur.right) return dfs(cur.right);
};
- return _dfs(this.root);
+ return dfs(this.root);
} else {
- const queue = new Queue([this.root]);
- while (queue.size > 0) {
- const cur = queue.shift();
+ const stack = [this.root];
+ while (stack.length > 0) {
+ const cur = stack.pop();
if (cur) {
if (cur.key === key) return cur;
- cur.left && queue.push(cur.left);
- cur.right && queue.push(cur.right);
+ cur.left && stack.push(cur.left);
+ cur.right && stack.push(cur.right);
}
}
}
@@ -789,11 +789,11 @@ export class BinaryTree<
*/
override get>(
identifier: ReturnType | null | undefined,
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType
): V | undefined {
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
@@ -848,11 +848,11 @@ export class BinaryTree<
*/
override has>(
identifier: ReturnType | null | undefined,
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType
): boolean {
- if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
+ if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
@@ -1184,20 +1184,20 @@ export class BinaryTree<
if (!this.isRealNode(beginRoot)) return beginRoot;
if (iterationType === 'RECURSIVE') {
- const _traverse = (cur: NODE): NODE => {
+ const dfs = (cur: NODE): NODE => {
if (!this.isRealNode(cur.left)) return cur;
- return _traverse(cur.left);
+ return dfs(cur.left);
};
- return _traverse(beginRoot);
+ return dfs(beginRoot);
} else {
// Indirect implementation of iteration using tail recursion optimization
- const _traverse = trampoline((cur: NODE) => {
+ const dfs = trampoline((cur: NODE) => {
if (!this.isRealNode(cur.left)) return cur;
- return _traverse.cont(cur.left);
+ return dfs.cont(cur.left);
});
- return _traverse(beginRoot);
+ return dfs(beginRoot);
}
}
@@ -1231,20 +1231,20 @@ export class BinaryTree<
if (!beginRoot) return beginRoot;
if (iterationType === 'RECURSIVE') {
- const _traverse = (cur: NODE): NODE => {
+ const dfs = (cur: NODE): NODE => {
if (!this.isRealNode(cur.right)) return cur;
- return _traverse(cur.right);
+ return dfs(cur.right);
};
- return _traverse(beginRoot);
+ return dfs(beginRoot);
} else {
// Indirect implementation of iteration using tail recursion optimization
- const _traverse = trampoline((cur: NODE) => {
+ const dfs = trampoline((cur: NODE) => {
if (!this.isRealNode(cur.right)) return cur;
- return _traverse.cont(cur.right);
+ return dfs.cont(cur.right);
});
- return _traverse(beginRoot);
+ return dfs(beginRoot);
}
}
@@ -1351,7 +1351,7 @@ export class BinaryTree<
* @returns an array of values that are the return values of the callback function.
*/
dfs>(
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
pattern: DFSOrderPattern = 'IN',
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = 'ITERATIVE',
@@ -1361,38 +1361,38 @@ export class BinaryTree<
if (!beginRoot) return [];
const ans: ReturnType[] = [];
if (iterationType === 'RECURSIVE') {
- const _traverse = (node: NODE | null | undefined) => {
+ const dfs = (node: NODE | null | undefined) => {
switch (pattern) {
case 'IN':
if (includeNull) {
- if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
+ if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
this.isNodeOrNull(node) && ans.push(callback(node));
- if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
+ if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
} else {
- if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
+ if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
this.isRealNode(node) && ans.push(callback(node));
- if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
+ if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
}
break;
case 'PRE':
if (includeNull) {
this.isNodeOrNull(node) && ans.push(callback(node));
- if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
- if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
+ if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
+ if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
} else {
this.isRealNode(node) && ans.push(callback(node));
- if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
- if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
+ if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
+ if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
}
break;
case 'POST':
if (includeNull) {
- if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
- if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
+ if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
+ if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
this.isNodeOrNull(node) && ans.push(callback(node));
} else {
- if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
- if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
+ if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
+ if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
this.isRealNode(node) && ans.push(callback(node));
}
@@ -1400,7 +1400,7 @@ export class BinaryTree<
}
};
- _traverse(beginRoot);
+ dfs(beginRoot);
} else {
// 0: visit, 1: print
const stack: { opt: 0 | 1; node: NODE | null | undefined }[] = [{ opt: 0, node: beginRoot }];
@@ -1486,7 +1486,7 @@ export class BinaryTree<
* the breadth-first traversal of a binary tree.
*/
bfs>(
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType,
includeNull = false
@@ -1499,7 +1499,7 @@ export class BinaryTree<
if (iterationType === 'RECURSIVE') {
const queue: Queue = new Queue([beginRoot]);
- const traverse = (level: number) => {
+ const dfs = (level: number) => {
if (queue.size === 0) return;
const current = queue.shift()!;
@@ -1513,10 +1513,10 @@ export class BinaryTree<
if (this.isRealNode(current.right)) queue.push(current.right);
}
- traverse(level + 1);
+ dfs(level + 1);
};
- traverse(0);
+ dfs(0);
} else {
const queue = new Queue([beginRoot]);
while (queue.size > 0) {
@@ -1580,7 +1580,7 @@ export class BinaryTree<
* @returns The function `listLevels` returns a two-dimensional array of type `ReturnType[][]`.
*/
listLevels>(
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType,
includeNull = false
@@ -1651,7 +1651,7 @@ export class BinaryTree<
* by the return type of the `callback` function.
*/
morris>(
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
pattern: DFSOrderPattern = 'IN',
beginRoot: KeyOrNodeOrEntry = this.root
): ReturnType[] {
@@ -1995,7 +1995,7 @@ export class BinaryTree<
}
}
- protected _defaultOneParamCallback = (node: NODE | null | undefined) => (node ? node.key : undefined);
+ protected _DEFAULT_CALLBACK = (node: NODE | null | undefined) => (node ? node.key : undefined);
/**
* Swap the data of two nodes in the binary tree.
diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts
index 8199ea1..cee0877 100644
--- a/src/data-structures/binary-tree/bst.ts
+++ b/src/data-structures/binary-tree/bst.ts
@@ -214,15 +214,15 @@ export class BST<
keyOrNodeOrEntry: KeyOrNodeOrEntry,
iterationType: IterationType = 'ITERATIVE'
): NODE | undefined {
- let res: NODE | undefined;
if (this.isRealNode(keyOrNodeOrEntry)) {
- res = keyOrNodeOrEntry;
+ return keyOrNodeOrEntry;
} else if (this.isEntry(keyOrNodeOrEntry)) {
- if (keyOrNodeOrEntry[0]) res = this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
+ if (keyOrNodeOrEntry[0] === null || keyOrNodeOrEntry[0] === undefined) return;
+ return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
} else {
- if (keyOrNodeOrEntry) res = this.getNodeByKey(keyOrNodeOrEntry, iterationType);
+ if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) return;
+ return this.getNodeByKey(keyOrNodeOrEntry, iterationType);
}
- return res;
}
/**
@@ -426,26 +426,26 @@ export class BST<
* found in the binary tree. If no node is found, it returns `undefined`.
*/
override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
- // return this.getNodes(key, this._defaultOneParamCallback, true, this.root, iterationType)[0];
- if (!this.isRealNode(this.root)) return undefined;
+ // return this.getNodes(key, this._DEFAULT_CALLBACK, true, this.root, iterationType)[0];
+ if (!this.isRealNode(this.root)) return;
if (iterationType === 'RECURSIVE') {
- const _dfs = (cur: NODE): NODE | undefined => {
+ const dfs = (cur: NODE): NODE | undefined => {
if (cur.key === key) return cur;
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
- if (this._compare(cur.key, key) === 'GT' && this.isRealNode(cur.left)) return _dfs(cur.left);
- if (this._compare(cur.key, key) === 'LT' && this.isRealNode(cur.right)) return _dfs(cur.right);
+ if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') return dfs(cur.left);
+ if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') return dfs(cur.right);
};
- return _dfs(this.root);
+ return dfs(this.root);
} else {
- const queue = new Queue([this.root]);
- while (queue.size > 0) {
- const cur = queue.shift();
+ const stack = [this.root];
+ while (stack.length > 0) {
+ const cur = stack.pop();
if (this.isRealNode(cur)) {
if (this._compare(cur.key, key) === 'EQ') return cur;
- if (this._compare(cur.key, key) === 'GT') this.isRealNode(cur.left) && queue.push(cur.left);
- if (this._compare(cur.key, key) === 'LT') this.isRealNode(cur.right) && queue.push(cur.right);
+ if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') stack.push(cur.left);
+ if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') stack.push(cur.right);
}
}
}
@@ -481,7 +481,7 @@ export class BST<
*/
override getNodes>(
identifier: ReturnType | undefined,
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
onlyOne = false,
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType
@@ -491,7 +491,7 @@ export class BST<
const ans: NODE[] = [];
if (iterationType === 'RECURSIVE') {
- const _traverse = (cur: NODE) => {
+ const dfs = (cur: NODE) => {
const callbackResult = callback(cur);
if (callbackResult === identifier) {
ans.push(cur);
@@ -500,16 +500,16 @@ export class BST<
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
// TODO potential bug
- if (callback === this._defaultOneParamCallback) {
- if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') _traverse(cur.left);
- if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') _traverse(cur.right);
+ if (callback === this._DEFAULT_CALLBACK) {
+ if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') dfs(cur.left);
+ if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') dfs(cur.right);
} else {
- this.isRealNode(cur.left) && _traverse(cur.left);
- this.isRealNode(cur.right) && _traverse(cur.right);
+ this.isRealNode(cur.left) && dfs(cur.left);
+ this.isRealNode(cur.right) && dfs(cur.right);
}
};
- _traverse(beginRoot);
+ dfs(beginRoot);
} else {
const stack = [beginRoot];
while (stack.length > 0) {
@@ -521,7 +521,7 @@ export class BST<
if (onlyOne) return ans;
}
// TODO potential bug
- if (callback === this._defaultOneParamCallback) {
+ if (callback === this._DEFAULT_CALLBACK) {
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') stack.push(cur.right);
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') stack.push(cur.left);
@@ -568,7 +568,7 @@ export class BST<
* @returns The method is returning an array of the return type of the callback function.
*/
override dfs>(
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
pattern: DFSOrderPattern = 'IN',
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = 'ITERATIVE'
@@ -599,7 +599,7 @@ export class BST<
* @returns The method is returning an array of the return type of the callback function.
*/
override bfs>(
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType
): ReturnType[] {
@@ -630,7 +630,7 @@ export class BST<
* function.
*/
override listLevels>(
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType
): ReturnType[][] {
@@ -700,7 +700,7 @@ export class BST<
* `ReturnType`, which is the return type of the callback function passed as an argument.
*/
lesserOrGreaterTraverse>(
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
lesserOrGreater: CP = 'LT',
targetNode: KeyOrNodeOrEntry = this.root,
iterationType: IterationType = this.iterationType
@@ -713,15 +713,15 @@ export class BST<
const targetKey = targetNode.key;
if (iterationType === 'RECURSIVE') {
- const _traverse = (cur: NODE) => {
+ const dfs = (cur: NODE) => {
const compared = this._compare(cur.key, targetKey);
if (compared === lesserOrGreater) ans.push(callback(cur));
- if (this.isRealNode(cur.left)) _traverse(cur.left);
- if (this.isRealNode(cur.right)) _traverse(cur.right);
+ if (this.isRealNode(cur.left)) dfs(cur.left);
+ if (this.isRealNode(cur.right)) dfs(cur.right);
};
- _traverse(this.root);
+ dfs(this.root);
return ans;
} else {
const queue = new Queue([this.root]);
diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts
index 16066cf..1e48309 100644
--- a/src/data-structures/binary-tree/rb-tree.ts
+++ b/src/data-structures/binary-tree/rb-tree.ts
@@ -231,7 +231,7 @@ export class RedBlackTree<
*/
override getNode>(
identifier: ReturnType | undefined,
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: BSTNKeyOrNode = this.root,
iterationType: IterationType = this.iterationType
): NODE | null | undefined {
@@ -308,13 +308,13 @@ export class RedBlackTree<
* deleted is not found.
* @param {C} callback - The `callback` parameter is a function that is used to retrieve a node from
* the binary tree based on its identifier. It is an optional parameter and if not provided, the
- * `_defaultOneParamCallback` function is used as the default callback. The callback function should
+ * `_DEFAULT_CALLBACK` function is used as the default callback. The callback function should
* return the identifier of the node to
* @returns an array of BinaryTreeDeleteResult objects.
*/
override delete>(
identifier: ReturnType | null | undefined,
- callback: C = this._defaultOneParamCallback as C
+ callback: C = this._DEFAULT_CALLBACK as C
): BinaryTreeDeleteResult[] {
if (identifier === null) return [];
const results: BinaryTreeDeleteResult[] = [];
diff --git a/src/data-structures/binary-tree/tree-multi-map.ts b/src/data-structures/binary-tree/tree-multi-map.ts
index 9b0e3aa..025520b 100644
--- a/src/data-structures/binary-tree/tree-multi-map.ts
+++ b/src/data-structures/binary-tree/tree-multi-map.ts
@@ -242,7 +242,7 @@ export class TreeMultiMap<
* function. It can also be null or undefined if no node needs to be deleted.
* @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as
* input and returns a value of type `ReturnType`. It is used to determine if a node matches the
- * identifier for deletion. If no callback is provided, the `_defaultOneParamCallback` function is
+ * identifier for deletion. If no callback is provided, the `_DEFAULT_CALLBACK` function is
* used
* @param [ignoreCount=false] - A boolean value indicating whether to ignore the count of the target
* node when performing deletion. If set to true, the count of the target node will not be considered
@@ -252,7 +252,7 @@ export class TreeMultiMap<
*/
override delete>(
identifier: ReturnType | null | undefined,
- callback: C = this._defaultOneParamCallback as C,
+ callback: C = this._DEFAULT_CALLBACK as C,
ignoreCount = false
): BinaryTreeDeleteResult[] {
if (identifier === null) return [];
diff --git a/test/integration/avl-tree.test.ts b/test/integration/avl-tree.test.ts
index 4a6d967..09af032 100644
--- a/test/integration/avl-tree.test.ts
+++ b/test/integration/avl-tree.test.ts
@@ -1,4 +1,4 @@
-import { AVLTree, CP } from 'avl-tree-typed';
+import { AVLTree } from 'avl-tree-typed';
describe('AVL Tree Test', () => {
it('should perform various operations on a AVL Tree', () => {
diff --git a/test/integration/bst.test.ts b/test/integration/bst.test.ts
index ad3440b..61c915a 100644
--- a/test/integration/bst.test.ts
+++ b/test/integration/bst.test.ts
@@ -1,4 +1,4 @@
-import { BST, BSTNode, CP } from 'bst-typed';
+import { BST, BSTNode } from 'bst-typed';
describe('Individual package BST operations test', () => {
it('should perform various operations on a Binary Search Tree with numeric values', () => {
diff --git a/test/integration/index.html b/test/integration/index.html
index 50e80bd..41866b4 100644
--- a/test/integration/index.html
+++ b/test/integration/index.html
@@ -28,14 +28,14 @@
const n = 1000000;
const startEn = performance.now();
for (let i = 0; i < n; i++) {
- queue.enqueue(i);
+ queue.push(i);
}
console.log((performance.now() - startEn).toFixed(2), `Queue ${n.toLocaleString()} enqueue `);
let last = 0;
const startTime = performance.now();
for (let i = 0; i < n; i++) {
- last = queue.dequeue();
+ last = queue.shift();
}
console.log((performance.now() - startTime).toFixed(2), `Queue ${n.toLocaleString()} dequeue `);
diff --git a/test/unit/data-structures/binary-tree/tree-multi-map.test.ts b/test/unit/data-structures/binary-tree/tree-multi-map.test.ts
index d6ff398..a3bf093 100644
--- a/test/unit/data-structures/binary-tree/tree-multi-map.test.ts
+++ b/test/unit/data-structures/binary-tree/tree-multi-map.test.ts
@@ -45,6 +45,7 @@ describe('TreeMultiMap operations test1', () => {
expect(tmm.getMinHeight()).toBe(-1);
tmm.addMany([1, 6, 7, 2, 3, 4, 9, 11, 8, 5, 10, 12, 16, 14, 13, 15]);
+ // tmm.print()
expect(tmm.getHeight()).toBe(5);
expect(tmm.getMinHeight()).toBe(2);
});
diff --git a/test/utils/big-o.ts b/test/utils/big-o.ts
index b639463..1c9175f 100644
--- a/test/utils/big-o.ts
+++ b/test/utils/big-o.ts
@@ -205,3 +205,15 @@ export function logBigOMetrics(target: any, propertyKey: string, descriptor: Pro
return descriptor;
}
+
+export const logPerf = function (fn: (...args: any[]) => any, args: any[], thisArg?: any) {
+ const start = performance.now();
+ if (thisArg) {
+ if (args && args.length > 0) fn.apply(thisArg, args);
+ else fn.apply(thisArg);
+ } else {
+ if (args && args.length > 0) fn(...args);
+ else fn();
+ }
+ console.log(`function running cost : ${(performance.now() - start).toFixed(2)} ms`);
+};