From 3fa7155c979b8e97acd0deccb76a18dc2ff945bd Mon Sep 17 00:00:00 2001 From: Revone Date: Fri, 19 Jan 2024 17:13:25 +0800 Subject: [PATCH] fix: #82. refactor: Minor performance optimization, rewrite the _compare method within the Red-Black Tree. test: Change the test sequence in binary-tree-overall.test. --- CHANGELOG.md | 4 +- README.md | 34 ++--- package-lock.json | 52 +++---- package.json | 10 +- .../binary-tree/binary-tree.ts | 45 ++---- src/data-structures/binary-tree/bst.ts | 135 ++++++++---------- src/data-structures/binary-tree/rb-tree.ts | 19 ++- .../binary-tree/binary-tree-overall.test.ts | 14 +- 8 files changed, 146 insertions(+), 167 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89c9026..bbf3270 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,9 @@ 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.51.5](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) +## [v1.51.6](https://github.com/zrwusa/data-structure-typed/compare/v1.51.5...main) (upcoming) + +## [v1.51.5](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...v1.51.5) (18 January 2024) ### Changes diff --git a/README.md b/README.md index 0fc65bc..760a9fc 100644 --- a/README.md +++ b/README.md @@ -736,43 +736,45 @@ Version 11.7.9 [//]: # (No deletion!!! Start of Replace Section)
heap
-
test nametime taken (ms)executions per secsample deviation
100,000 add6.44155.391.89e-4
100,000 add & poll31.5431.717.91e-4
+
test nametime taken (ms)executions per secsample deviation
100,000 add6.31158.421.69e-4
100,000 add & poll32.2131.050.00
rb-tree
-
test nametime taken (ms)executions per secsample deviation
100,000 add55.6417.973.93e-4
100,000 add randomly70.3514.210.00
100,000 get115.518.660.00
100,000 iterator27.6436.180.01
100,000 add & delete orderly120.738.280.00
100,000 add & delete randomly223.374.480.00
+
test nametime taken (ms)executions per secsample deviation
100,000 add59.7016.757.70e-4
100,000 add randomly72.5513.780.00
100,000 get104.489.570.00
100,000 iterator27.7036.100.01
100,000 add & delete orderly126.077.930.00
100,000 add & delete randomly212.964.700.00
queue
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push42.8723.330.01
100,000 push & shift4.87205.176.94e-4
Native JS Array 100,000 push & shift2196.840.460.19
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push44.4922.480.01
100,000 push & shift4.82207.405.25e-4
Native JS Array 100,000 push & shift2201.760.450.10
deque
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push23.6842.220.00
1,000,000 push & pop30.6832.600.00
1,000,000 push & shift30.4932.800.00
100,000 push & shift3.21311.512.41e-4
Native JS Array 100,000 push & shift2510.080.400.34
100,000 unshift & shift2.89346.572.98e-4
Native JS Array 100,000 unshift & shift4581.650.220.40
-
-
hash-map
-
test nametime taken (ms)executions per secsample deviation
1,000,000 set120.668.290.03
Native JS Map 1,000,000 set202.574.940.01
Native JS Set 1,000,000 add167.465.970.01
1,000,000 set & get115.608.650.01
Native JS Map 1,000,000 set & get265.343.770.01
Native JS Set 1,000,000 add & has167.855.960.01
1,000,000 ObjKey set & get308.733.240.03
Native JS Map 1,000,000 ObjKey set & get300.603.330.03
Native JS Set 1,000,000 ObjKey add & has270.493.700.04
-
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push12.3481.061.27e-4
1,000,000 push & pop21.3546.841.44e-4
1,000,000 push & shift21.5446.420.00
100,000 push & shift2.09478.801.60e-4
Native JS Array 100,000 push & shift2233.460.450.12
100,000 unshift & shift1.99502.421.55e-4
Native JS Array 100,000 unshift & shift4153.080.240.34
+
+
hash-map
+
test nametime taken (ms)executions per secsample deviation
1,000,000 set129.847.700.04
Native JS Map 1,000,000 set238.664.190.03
Native JS Set 1,000,000 add194.685.140.01
1,000,000 set & get134.957.410.03
Native JS Map 1,000,000 set & get320.943.120.04
Native JS Set 1,000,000 add & has261.563.820.07
1,000,000 ObjKey set & get363.112.750.06
Native JS Map 1,000,000 ObjKey set & get344.032.910.05
Native JS Set 1,000,000 ObjKey add & has351.352.850.10
+
+ +
trie
-
test nametime taken (ms)executions per secsample deviation
100,000 push45.7921.847.32e-4
100,000 getWords87.8511.380.00
+
test nametime taken (ms)executions per secsample deviation
100,000 push44.7522.356.31e-4
100,000 getWords83.9611.910.00
avl-tree
-
test nametime taken (ms)executions per secsample deviation
100,000 add260.783.830.00
100,000 add randomly306.613.260.00
100,000 get140.277.130.00
100,000 iterator29.9033.450.01
100,000 add & delete orderly428.762.330.00
100,000 add & delete randomly580.741.720.00
+
test nametime taken (ms)executions per secsample deviation
100,000 add262.233.810.00
100,000 add randomly323.183.090.00
100,000 get130.857.640.00
100,000 iterator31.7931.460.01
100,000 add & delete orderly423.802.360.00
100,000 add & delete randomly585.791.710.00
binary-tree-overall
-
test nametime taken (ms)executions per secsample deviation
10,000 RBTree add5.74174.109.29e-5
10,000 RBTree add & delete randomly18.8353.101.49e-4
10,000 RBTree get0.771290.557.33e-6
10,000 AVLTree add22.6044.252.14e-4
10,000 AVLTree get10.6394.081.02e-4
10,000 AVLTree add & delete randomly44.1722.643.52e-4
+
test nametime taken (ms)executions per secsample deviation
10,000 RBTree add randomly5.84171.138.92e-5
10,000 RBTree get randomly9.48105.495.40e-4
10,000 RBTree add & delete randomly18.1954.981.42e-4
10,000 AVLTree add randomly26.4537.802.66e-4
10,000 AVLTree get randomly10.6394.091.36e-4
10,000 AVLTree add & delete randomly49.0720.383.49e-4
directed-graph
-
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.119501.691.02e-6
1,000 addEdge6.18161.814.27e-4
1,000 getVertex0.052.16e+43.23e-7
1,000 getEdge23.3142.900.00
tarjan206.064.850.01
topologicalSort181.655.510.01
+
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.101.01e+41.05e-6
1,000 addEdge6.18161.887.72e-4
1,000 getVertex0.052.17e+43.58e-7
1,000 getEdge23.0343.430.00
tarjan203.184.920.02
topologicalSort174.785.720.00
doubly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push207.884.810.04
1,000,000 unshift214.334.670.06
1,000,000 unshift & shift185.545.390.04
1,000,000 addBefore308.663.240.08
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push227.394.400.03
1,000,000 unshift211.704.720.02
1,000,000 unshift & shift171.845.820.02
1,000,000 addBefore318.693.140.06
singly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift202.614.940.04
10,000 push & pop219.694.550.02
10,000 addBefore247.134.050.01
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift201.654.960.04
10,000 push & pop216.764.610.01
10,000 addBefore248.824.020.01
priority-queue
-
test nametime taken (ms)executions per secsample deviation
100,000 add27.3636.559.92e-4
100,000 add & poll146.726.826.84e-4
+
test nametime taken (ms)executions per secsample deviation
100,000 add27.3536.560.00
100,000 add & poll78.7612.700.02
stack
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push39.3625.410.01
1,000,000 push & pop47.8620.890.01
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push38.7925.780.00
1,000,000 push & pop47.0121.270.01
[//]: # (No deletion!!! End of Replace Section) diff --git a/package-lock.json b/package-lock.json index c9db3c4..6efadea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "data-structure-typed", - "version": "1.51.5", + "version": "1.51.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-structure-typed", - "version": "1.51.5", + "version": "1.51.6", "license": "MIT", "devDependencies": { "@swc/core": "^1.3.96", @@ -16,11 +16,11 @@ "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "auto-changelog": "^2.4.0", - "avl-tree-typed": "^1.51.4", + "avl-tree-typed": "^1.51.5", "benchmark": "^2.1.4", - "binary-tree-typed": "^1.51.4", - "bst-typed": "^1.51.4", - "data-structure-typed": "^1.51.4", + "binary-tree-typed": "^1.51.5", + "bst-typed": "^1.51.5", + "data-structure-typed": "^1.51.5", "dependency-cruiser": "^14.1.0", "doctoc": "^2.2.1", "eslint": "^8.50.0", @@ -29,7 +29,7 @@ "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.28.1", "fast-glob": "^3.3.1", - "heap-typed": "^1.51.4", + "heap-typed": "^1.51.5", "istanbul-badges-readme": "^1.8.5", "jest": "^29.7.0", "js-sdsl": "^4.4.2", @@ -3097,12 +3097,12 @@ } }, "node_modules/avl-tree-typed": { - "version": "1.51.4", - "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.51.4.tgz", - "integrity": "sha512-9kK90VK8FHzawVDf4p55AWEnC2iprGWD9UVBGUg333K2vf75oGkzfVKL0lMV/BsSprTYf98Sreo4KQ03VNZL4Q==", + "version": "1.51.5", + "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.51.5.tgz", + "integrity": "sha512-cw/xCqnyRDh3lh11YkMcZDFV1rQoozfhKOGkkeO+xT7aHu8a1jtK9zJrrqCqIfOYKTieTsirwvngBloQb6PH/g==", "dev": true, "dependencies": { - "data-structure-typed": "^1.51.4" + "data-structure-typed": "^1.51.5" } }, "node_modules/babel-jest": { @@ -3306,12 +3306,12 @@ } }, "node_modules/binary-tree-typed": { - "version": "1.51.4", - "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.51.4.tgz", - "integrity": "sha512-iAYoTj36MUNMjHPT4mGjQ4ggh+3YOY4f25EM45yYz1SLehXxeYGrGnoLu4L0r3UgNp3KkvbMp7BvmML2hTSDgA==", + "version": "1.51.5", + "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.51.5.tgz", + "integrity": "sha512-a34NqnG4KNUNwcRHQC7vjYpqQYkKy9QaWZx7uHiRcbHQjU/8EA9ICl4U3s3X8V3Ur+CclOsBYNPUdeAd38SH9A==", "dev": true, "dependencies": { - "data-structure-typed": "^1.51.4" + "data-structure-typed": "^1.51.5" } }, "node_modules/brace-expansion": { @@ -3390,12 +3390,12 @@ } }, "node_modules/bst-typed": { - "version": "1.51.4", - "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.51.4.tgz", - "integrity": "sha512-HDt+d7fMrnLa7FYBZH7FCWZQF+t5VA77L0QUgHI/m6lr/opGUmNSxqsEk4VsYwc4JskNi70F1HxApl26MLxAhQ==", + "version": "1.51.5", + "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.51.5.tgz", + "integrity": "sha512-HmpA3D4WmPBcWIbJMSTJ2wLPwwfl9ulNXJyuSIYGFLZoTa9+g1oA4HRL43IUnBCLgVWSXsq7Bhc/Jp1jvN/84w==", "dev": true, "dependencies": { - "data-structure-typed": "^1.51.4" + "data-structure-typed": "^1.51.5" } }, "node_modules/buffer-from": { @@ -3838,9 +3838,9 @@ } }, "node_modules/data-structure-typed": { - "version": "1.51.4", - "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.51.4.tgz", - "integrity": "sha512-nVMJaCwf9m+2MqtGmPfc3LNda8Jhek2gDQ2D1tam/rous+k++geROPRDfWhYzBYXU24ndLeYP/NepB5Po6qsMQ==", + "version": "1.51.5", + "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.51.5.tgz", + "integrity": "sha512-uVONyHrk2UHXDHkRDm7EnXO9TNybAU1Rmd/9r1Ld5vaFPa/oIXy9yzFk6deTDgsnbiHASnogA3IWiqhCag1RZQ==", "dev": true }, "node_modules/debug": { @@ -5363,12 +5363,12 @@ } }, "node_modules/heap-typed": { - "version": "1.51.4", - "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.51.4.tgz", - "integrity": "sha512-82U5jW7U87VefYCZ/Wmq6jfN6fPKT5IdThJ5VSBMNyMNGSP60UiK0DSftoGif2kQWsI/2ay7fmm7sFIjkQy4rQ==", + "version": "1.51.5", + "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.51.5.tgz", + "integrity": "sha512-mCD9etfviFYdbDEkXJWTyKVX7f2LPRCQHHLjo+VOsE+IBJRTScuNIJKSD+HKZOntNBCWW0VWdc+ZzkXEKU2mhw==", "dev": true, "dependencies": { - "data-structure-typed": "^1.51.4" + "data-structure-typed": "^1.51.5" } }, "node_modules/html-escaper": { diff --git a/package.json b/package.json index c2a0a2f..9fa29ec 100644 --- a/package.json +++ b/package.json @@ -66,11 +66,11 @@ "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "auto-changelog": "^2.4.0", - "avl-tree-typed": "^1.51.4", + "avl-tree-typed": "^1.51.5", "benchmark": "^2.1.4", - "binary-tree-typed": "^1.51.4", - "bst-typed": "^1.51.4", - "data-structure-typed": "^1.51.4", + "binary-tree-typed": "^1.51.5", + "bst-typed": "^1.51.5", + "data-structure-typed": "^1.51.5", "dependency-cruiser": "^14.1.0", "doctoc": "^2.2.1", "eslint": "^8.50.0", @@ -79,7 +79,7 @@ "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.28.1", "fast-glob": "^3.3.1", - "heap-typed": "^1.51.4", + "heap-typed": "^1.51.5", "istanbul-badges-readme": "^1.8.5", "jest": "^29.7.0", "js-sdsl": "^4.4.2", diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index 4b07d8a..c96509c 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -278,17 +278,19 @@ export class BinaryTree< keyOrNodeOrEntry: KeyOrNodeOrEntry, iterationType: IterationType = 'ITERATIVE' ): NODE | null | undefined { + if (keyOrNodeOrEntry === this.NIL) return; if (this.isRealNode(keyOrNodeOrEntry)) { return keyOrNodeOrEntry; - } else if (this.isEntry(keyOrNodeOrEntry)) { - if (keyOrNodeOrEntry[0] === null) return null; - if (keyOrNodeOrEntry[0] === undefined) return; - return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType); - } else { - if (keyOrNodeOrEntry === null) return null; - if (keyOrNodeOrEntry === undefined) return; - return this.getNodeByKey(keyOrNodeOrEntry, iterationType); } + if (this.isEntry(keyOrNodeOrEntry)) { + const key = keyOrNodeOrEntry[0]; + if (key === null) return null; + if (key === undefined) return; + return this.getNodeByKey(key, iterationType); + } + if (keyOrNodeOrEntry === null) return null; + if (keyOrNodeOrEntry === undefined) return; + return this.getNodeByKey(keyOrNodeOrEntry, iterationType); } /** @@ -722,29 +724,8 @@ export class BinaryTree< * @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is * found in the binary tree. If no node is found, it returns `undefined`. */ - getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined { - if (!this.root) return undefined; - if (iterationType === 'RECURSIVE') { - 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); - }; - - return dfs(this.root); - } else { - const stack = [this.root]; - while (stack.length > 0) { - const cur = stack.pop(); - if (cur) { - if (cur.key === key) return cur; - cur.left && stack.push(cur.left); - cur.right && stack.push(cur.right); - } - } - } + getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | null | undefined { + return this.getNode(key, this._DEFAULT_CALLBACK, this.root, iterationType); } override get>( @@ -801,7 +782,7 @@ export class BinaryTree< beginRoot: KeyOrNodeOrEntry = this.root, iterationType: IterationType = this.iterationType ): V | undefined { - return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined; + return this.getNode(identifier, callback, beginRoot, iterationType)?.value; } override has>( diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index ea72934..021b88f 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -214,15 +214,20 @@ export class BST< keyOrNodeOrEntry: KeyOrNodeOrEntry, iterationType: IterationType = 'ITERATIVE' ): NODE | undefined { + if (keyOrNodeOrEntry === this.NIL) return; if (this.isRealNode(keyOrNodeOrEntry)) { return keyOrNodeOrEntry; - } else if (this.isEntry(keyOrNodeOrEntry)) { - if (keyOrNodeOrEntry[0] === null || keyOrNodeOrEntry[0] === undefined) return; - return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType); - } else { - if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) return; - return this.getNodeByKey(keyOrNodeOrEntry, iterationType); } + + if (this.isEntry(keyOrNodeOrEntry)) { + const key = keyOrNodeOrEntry[0]; + if (key === null || key === undefined) return; + return this.getNodeByKey(key, iterationType); + } + + const key = keyOrNodeOrEntry; + if (key === null || key === undefined) return; + return this.getNodeByKey(key, iterationType); } /** @@ -406,51 +411,6 @@ export class BST< return inserted; } - /** - * Time Complexity: O(log n) - * Space Complexity: O(1) - */ - - /** - * Time Complexity: O(log n) - * Space Complexity: O(1) - * - * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using - * either recursive or iterative methods. - * @param {K} key - The `key` parameter is the key value that we are searching for in the tree. - * It is used to identify the node that we want to retrieve. - * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the - * type of iteration to use when searching for a node in the binary tree. It can have two possible - * values: - * @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is - * 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._DEFAULT_CALLBACK, true, this.root, iterationType)[0]; - if (!this.isRealNode(this.root)) return; - if (iterationType === 'RECURSIVE') { - const dfs = (cur: NODE): NODE | undefined => { - if (cur.key === key) return cur; - if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return; - - 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); - } else { - 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.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); - } - } - } - } - /** * Time Complexity: O(log n) * Space Complexity: O(k + log n) @@ -513,29 +473,27 @@ export class BST< } else { const stack = [beginRoot]; while (stack.length > 0) { - const cur = stack.pop(); - if (this.isRealNode(cur)) { - const callbackResult = callback(cur); - if (callbackResult === identifier) { - ans.push(cur); - if (onlyOne) return ans; - } - // TODO potential bug - 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); + const cur = stack.pop()!; + const callbackResult = callback(cur); + if (callbackResult === identifier) { + ans.push(cur); + if (onlyOne) return ans; + } + // TODO potential bug + 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); - // if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right); - // if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left); + // if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right); + // if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left); - // // @ts-ignore - // if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right); - // // @ts-ignore - // if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left); - } else { - this.isRealNode(cur.right) && stack.push(cur.right); - this.isRealNode(cur.left) && stack.push(cur.left); - } + // // @ts-ignore + // if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right); + // // @ts-ignore + // if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left); + } else { + this.isRealNode(cur.right) && stack.push(cur.right); + this.isRealNode(cur.left) && stack.push(cur.left); } } } @@ -578,6 +536,29 @@ export class BST< return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined; } + /** + * Time Complexity: O(log n) + * Space Complexity: O(1) + */ + + /** + * Time Complexity: O(log n) + * Space Complexity: O(1) + * + * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using + * either recursive or iterative methods. + * @param {K} key - The `key` parameter is the key value that we are searching for in the tree. + * It is used to identify the node that we want to retrieve. + * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the + * type of iteration to use when searching for a node in the binary tree. It can have two possible + * values: + * @returns The function `getNodeByKey` returns a node (`NODE`) if a node with the specified key is + * found in the binary tree. If no node is found, it returns `undefined`. + */ + override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined { + return this.getNode(key, this._DEFAULT_CALLBACK, this.root, iterationType); + } + /** * Time complexity: O(n) * Space complexity: O(n) @@ -920,7 +901,9 @@ export class BST< const extractedB = this.extractor(b); const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA; - return compared > 0 ? 'GT' : compared < 0 ? 'LT' : 'EQ'; + if (compared > 0) return 'GT'; + if (compared < 0) return 'LT'; + return 'EQ'; } /** @@ -935,10 +918,7 @@ export class BST< protected _lt(a: K, b: K): boolean { const extractedA = this.extractor(a); const extractedB = this.extractor(b); - // return this.variant === BSTVariant.STANDARD ? extractedA < extractedB : extractedA > extractedB; return this.variant === 'STANDARD' ? extractedA < extractedB : extractedA > extractedB; - // return extractedA < extractedB; - // return a < b; } /** @@ -952,9 +932,6 @@ export class BST< protected _gt(a: K, b: K): boolean { const extractedA = this.extractor(a); const extractedB = this.extractor(b); - // return this.variant === BSTVariant.STANDARD ? extractedA > extractedB : extractedA < extractedB; return this.variant === 'STANDARD' ? extractedA > extractedB : extractedA < extractedB; - // return extractedA > extractedB; - // return a > b; } } diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts index b30777b..4fe09bf 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -6,7 +6,7 @@ import type { RedBlackTreeNested, RedBlackTreeNodeNested } from '../../types'; -import { CRUD, RBTNColor } from '../../types'; +import { CP, CRUD, RBTNColor } from '../../types'; import { BST, BSTNode } from './bst'; import { IBinaryTree } from '../../interfaces'; @@ -656,4 +656,21 @@ export class RedBlackTree< x.right = y; y.parent = x; } + + /** + * The function compares two values using a comparator function and returns whether the first value + * is greater than, less than, or equal to the second value. + * @param {K} a - The parameter "a" is of type K. + * @param {K} b - The parameter "b" in the above code represents a K. + * @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater + * than), 'LT' (less than), or 'EQ' (equal). + */ + protected override _compare(a: K, b: K): CP { + const extractedA = this.extractor(a); + const extractedB = this.extractor(b); + const compared = extractedA - extractedB; + if (compared > 0) return 'GT'; + if (compared < 0) return 'LT'; + return 'EQ'; + } } diff --git a/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts b/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts index 97550f4..2bc584d 100644 --- a/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts +++ b/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts @@ -6,26 +6,26 @@ const suite = new Benchmark.Suite(); const rbTree = new RedBlackTree(); const avlTree = new AVLTree(); const { TEN_THOUSAND } = magnitude; -const arr = getRandomIntArray(TEN_THOUSAND, 0, TEN_THOUSAND, true); +const arr = getRandomIntArray(TEN_THOUSAND, 0, TEN_THOUSAND - 1, true); suite - .add(`${TEN_THOUSAND.toLocaleString()} RBTree add`, () => { + .add(`${TEN_THOUSAND.toLocaleString()} RBTree add randomly`, () => { rbTree.clear(); for (let i = 0; i < arr.length; i++) rbTree.add(arr[i]); }) + .add(`${TEN_THOUSAND.toLocaleString()} RBTree get randomly`, () => { + for (let i = 0; i < arr.length; i++) rbTree.get(arr[i]); + }) .add(`${TEN_THOUSAND.toLocaleString()} RBTree add & delete randomly`, () => { rbTree.clear(); for (let i = 0; i < arr.length; i++) rbTree.add(arr[i]); for (let i = 0; i < arr.length; i++) rbTree.delete(arr[i]); }) - .add(`${TEN_THOUSAND.toLocaleString()} RBTree get`, () => { - for (let i = 0; i < arr.length; i++) rbTree.get(arr[i]); - }) - .add(`${TEN_THOUSAND.toLocaleString()} AVLTree add`, () => { + .add(`${TEN_THOUSAND.toLocaleString()} AVLTree add randomly`, () => { avlTree.clear(); for (let i = 0; i < arr.length; i++) avlTree.add(arr[i]); }) - .add(`${TEN_THOUSAND.toLocaleString()} AVLTree get`, () => { + .add(`${TEN_THOUSAND.toLocaleString()} AVLTree get randomly`, () => { for (let i = 0; i < arr.length; i++) avlTree.get(arr[i]); }) .add(`${TEN_THOUSAND.toLocaleString()} AVLTree add & delete randomly`, () => {