From a11c104dff025d0f6fcae172acb0bcecee211ac7 Mon Sep 17 00:00:00 2001 From: Revone Date: Sun, 14 Jan 2024 03:04:07 +0800 Subject: [PATCH] refactor: Replace all enumerations with union types for significant performance improvements in BST, AVLTree, and RedBlackTree. --- README.md | 32 +-- package-lock.json | 52 ++--- package.json | 10 +- .../binary-tree/avl-tree-multi-map.ts | 7 +- .../binary-tree/binary-tree.ts | 49 +++-- src/data-structures/binary-tree/bst.ts | 95 +++++---- src/data-structures/binary-tree/rb-tree.ts | 12 +- .../binary-tree/tree-multi-map.ts | 4 +- src/types/common.ts | 34 +--- test/integration/all-in-one.test.ts | 4 +- test/integration/avl-tree.test.ts | 2 +- test/integration/bst.test.ts | 4 +- .../binary-tree/rb-tree.test.ts | 34 ++-- .../binary-tree/avl-tree-multi-map.test.ts | 24 +-- .../binary-tree/avl-tree.test.ts | 8 +- .../binary-tree/binary-tree.test.ts | 183 +++++++++++------- .../data-structures/binary-tree/bst.test.ts | 24 +-- .../binary-tree/overall.test.ts | 14 +- .../binary-tree/rb-tree.test.ts | 15 +- .../binary-tree/tree-multi-map.test.ts | 22 +-- 20 files changed, 334 insertions(+), 295 deletions(-) diff --git a/README.md b/README.md index 3c3b004..6a1c762 100644 --- a/README.md +++ b/README.md @@ -996,43 +996,45 @@ Intel UHD Graphics 630 1536 MB [//]: # (No deletion!!! Start of Replace Section)
heap
-
test nametime taken (ms)executions per secsample deviation
100,000 add6.34157.681.57e-4
100,000 add & poll31.5431.709.20e-4
-
+
test nametime taken (ms)executions per secsample deviation
100,000 add6.46154.913.36e-4
100,000 add & poll31.6231.628.04e-4
+
rb-tree
-
test nametime taken (ms)executions per secsample deviation
100,000 add orderly57.9017.270.00
100,000 delete orderly10.6593.909.11e-5
100,000 add randomly114.658.720.00
100,000 delete randomly10.2497.625.53e-5
100,000 add orderly58.5117.090.00
100,000 delete randomly10.2597.566.25e-5
100,000 getNode randomly9.53104.986.20e-5
100,000 add & iterator146.466.830.02
-
+
test nametime taken (ms)executions per secsample deviation
100,000 add orderly92.7810.780.00
100,000 add & delete orderly164.956.060.00
100,000 add randomly96.1410.400.00
100,000 add & delete randomly268.323.730.02
100,000 add & get randomly221.234.520.00
100,000 add & iterator130.017.690.01
+
+ +
queue
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push41.5924.050.01
100,000 push & shift4.54220.291.10e-4
Native JS Array 100,000 push & shift2243.540.450.10
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push44.0722.690.01
100,000 push & shift4.89204.655.60e-4
Native JS Array 100,000 push & shift2305.440.430.31
deque
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push23.2043.100.00
1,000,000 push & pop30.1433.180.00
1,000,000 push & shift29.9433.400.00
100,000 push & shift3.18314.703.27e-4
Native JS Array 100,000 push & shift2238.520.450.09
100,000 unshift & shift2.85350.272.85e-4
Native JS Array 100,000 unshift & shift4149.340.240.10
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push24.6940.500.00
1,000,000 push & pop31.5931.660.00
1,000,000 push & shift31.1732.090.00
100,000 push & shift3.27305.752.76e-4
Native JS Array 100,000 push & shift2511.340.400.37
100,000 unshift & shift2.97336.262.53e-4
Native JS Array 100,000 unshift & shift4097.310.240.34
hash-map
-
test nametime taken (ms)executions per secsample deviation
1,000,000 set113.248.830.03
Native JS Map 1,000,000 set205.144.870.00
Native JS Set 1,000,000 add174.385.730.01
1,000,000 set & get114.968.700.03
Native JS Map 1,000,000 set & get267.573.740.00
Native JS Set 1,000,000 add & has172.945.780.01
1,000,000 ObjKey set & get327.383.050.03
Native JS Map 1,000,000 ObjKey set & get297.643.360.03
Native JS Set 1,000,000 ObjKey add & has263.303.800.04
+
test nametime taken (ms)executions per secsample deviation
1,000,000 set114.378.740.02
Native JS Map 1,000,000 set202.674.930.00
Native JS Set 1,000,000 add168.245.940.00
1,000,000 set & get124.108.060.03
Native JS Map 1,000,000 set & get266.463.750.01
Native JS Set 1,000,000 add & has175.145.710.02
1,000,000 ObjKey set & get341.262.930.05
Native JS Map 1,000,000 ObjKey set & get311.603.210.04
Native JS Set 1,000,000 ObjKey add & has274.813.640.03
trie
-
test nametime taken (ms)executions per secsample deviation
100,000 push43.6522.910.00
100,000 getWords82.6412.100.00
+
test nametime taken (ms)executions per secsample deviation
100,000 push59.0816.930.00
100,000 getWords82.9212.060.00
avl-tree
-
test nametime taken (ms)executions per secsample deviation
10,000 add randomly133.027.520.00
10,000 get61.4216.285.07e-4
10,000 add & delete randomly204.194.900.00
10,000 addMany142.697.010.00
+
test nametime taken (ms)executions per secsample deviation
10,000 add randomly48.6620.550.01
10,000 get19.3651.642.95e-4
10,000 add & delete randomly77.6812.870.00
10,000 addMany52.0419.220.01
binary-tree-overall
-
test nametime taken (ms)executions per secsample deviation
10,000 RBTree add9.28107.791.15e-4
10,000 RBTree add & delete randomly60.5616.516.63e-4
10,000 RBTree get1.11902.488.41e-6
10,000 AVLTree add134.177.450.01
10,000 AVLTree get60.9716.404.05e-4
10,000 AVLTree add & delete randomly201.724.960.00
+
test nametime taken (ms)executions per secsample deviation
10,000 RBTree add8.07123.878.53e-5
10,000 RBTree add & delete randomly22.3844.685.81e-4
10,000 RBTree get0.621602.157.37e-6
10,000 AVLTree add46.2721.618.12e-4
10,000 AVLTree get20.0249.954.21e-4
10,000 AVLTree add & delete randomly75.9613.160.00
directed-graph
-
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.101.00e+47.24e-7
1,000 addEdge6.20161.258.47e-4
1,000 getVertex0.052.17e+43.59e-7
1,000 getEdge22.6044.240.00
tarjan207.154.830.02
topologicalSort175.865.690.00
+
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.109647.199.43e-7
1,000 addEdge6.06164.981.09e-4
1,000 getVertex0.052.17e+42.85e-7
1,000 getEdge23.4742.600.00
tarjan208.864.790.01
topologicalSort186.705.360.02
doubly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push235.164.250.06
1,000,000 unshift225.374.440.04
1,000,000 unshift & shift170.755.860.03
1,000,000 addBefore324.453.080.07
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push209.574.770.06
1,000,000 unshift203.854.910.03
1,000,000 unshift & shift172.645.790.02
1,000,000 addBefore315.263.170.08
singly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift215.084.650.07
10,000 push & pop212.544.710.01
10,000 addBefore250.104.000.01
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift218.014.590.06
10,000 push & pop216.064.630.01
10,000 addBefore248.624.020.01
priority-queue
-
test nametime taken (ms)executions per secsample deviation
100,000 add26.7137.442.40e-4
100,000 add & poll74.7813.375.52e-4
+
test nametime taken (ms)executions per secsample deviation
100,000 add27.5236.340.00
100,000 add & poll75.4913.255.41e-4
stack
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push37.1926.890.00
1,000,000 push & pop46.1121.690.00
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push41.2424.250.01
1,000,000 push & pop49.6720.130.01
[//]: # (No deletion!!! End of Replace Section) diff --git a/package-lock.json b/package-lock.json index 774c0b6..8b18a0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "data-structure-typed", - "version": "1.49.4", + "version": "1.50.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-structure-typed", - "version": "1.49.4", + "version": "1.50.7", "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.44.0", + "avl-tree-typed": "^1.50.7", "benchmark": "^2.1.4", - "binary-tree-typed": "^1.44.0", - "bst-typed": "^1.44.0", - "data-structure-typed": "^1.44.0", + "binary-tree-typed": "^1.50.7", + "bst-typed": "^1.50.7", + "data-structure-typed": "^1.50.7", "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.44.0", + "heap-typed": "^1.50.7", "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.49.4", - "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.49.4.tgz", - "integrity": "sha512-koGMepnQ6vmZND5plmUMojmvUSJrbmcFev8uO9XxuJKVKYzcjfWIG3m3Hylantwzi6XAUURFHobmjNgLvsUmaw==", + "version": "1.50.7", + "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.50.7.tgz", + "integrity": "sha512-zYo8Oa4IrM5i3evHGO0FhELFHpDITUOpa2d8cGd06LHR74I9JL0OX7X0J+yuy6RBSuiIiNieJ99EKmhuggGbTg==", "dev": true, "dependencies": { - "data-structure-typed": "^1.49.4" + "data-structure-typed": "^1.50.7" } }, "node_modules/babel-jest": { @@ -3306,12 +3306,12 @@ } }, "node_modules/binary-tree-typed": { - "version": "1.49.4", - "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.49.4.tgz", - "integrity": "sha512-6f0J37Ab6zb3W1YYlQZ7PIeQp/Nabpc03U93ZGAIZo+mSyIzzXgWZkK0XTvarY5vpv8Pd4u1eDeQjV+n6EHHvQ==", + "version": "1.50.7", + "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.50.7.tgz", + "integrity": "sha512-L1kVL9q+1jsXyTNuZ/PJrBD1HUK4MyWFOwQmH4coy7WmOlTg2z2+ZuXCgmT8X/ADYFoKc9hq94niS/Yvy6RpOg==", "dev": true, "dependencies": { - "data-structure-typed": "^1.49.4" + "data-structure-typed": "^1.50.7" } }, "node_modules/brace-expansion": { @@ -3390,12 +3390,12 @@ } }, "node_modules/bst-typed": { - "version": "1.49.4", - "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.49.4.tgz", - "integrity": "sha512-qWuWrC5eGm7Czxc5PPXyGP4kRkkz7FOJ4MlwPwo8JQapJwXrxFLj/ix79pqBvQVUZ4AKXPg8vBsqm/hE4M1mkA==", + "version": "1.50.7", + "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.50.7.tgz", + "integrity": "sha512-grhnOajT8DBZYivgT5Q+qVQKpBbUPIyMJ2KVOx2EBH68l1pFA78zlf/BJWhEL+UcLwDqIJ6DpbvqcyTAjcfE9A==", "dev": true, "dependencies": { - "data-structure-typed": "^1.49.4" + "data-structure-typed": "^1.50.7" } }, "node_modules/buffer-from": { @@ -3838,9 +3838,9 @@ } }, "node_modules/data-structure-typed": { - "version": "1.49.4", - "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.49.4.tgz", - "integrity": "sha512-Xsb/cHHSFc7x7Rr2ppehqZ+fOI5xykqCZ65rt7tS4n3v0AcNZn1nz9elSwiP7mTHGXCLbOeNQdwLtsmcC32wIw==", + "version": "1.50.7", + "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.50.7.tgz", + "integrity": "sha512-TPLHMD4yxQFp4YbigA7i4zAVsQwZEarmYah2KXMmhczzasDXt+bbYLg7/BlRkq58N55Qr8UZuI5MAlH2YKaibQ==", "dev": true }, "node_modules/debug": { @@ -5363,12 +5363,12 @@ } }, "node_modules/heap-typed": { - "version": "1.49.4", - "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.49.4.tgz", - "integrity": "sha512-ykm0Bs7iYFF16uZ21tnCt+WPBYkLFxWh2HLObZiQmxEgozczcfJpc6IxWfRyvECJkIYrnh2Im9ej4ERWca7+aQ==", + "version": "1.50.7", + "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.50.7.tgz", + "integrity": "sha512-124SW17qSl+7aVp0d4gdFVTusW/Lq+x8S89yvyTUfSj6YadqUjP0EKblDx4oShiYC91g3YRPKqKV5juN2SDx5w==", "dev": true, "dependencies": { - "data-structure-typed": "^1.49.4" + "data-structure-typed": "^1.50.7" } }, "node_modules/html-escaper": { diff --git a/package.json b/package.json index e213b12..64d674b 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.44.0", + "avl-tree-typed": "^1.50.7", "benchmark": "^2.1.4", - "binary-tree-typed": "^1.44.0", - "bst-typed": "^1.44.0", - "data-structure-typed": "^1.44.0", + "binary-tree-typed": "^1.50.7", + "bst-typed": "^1.50.7", + "data-structure-typed": "^1.50.7", "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.44.0", + "heap-typed": "^1.50.7", "istanbul-badges-readme": "^1.8.5", "jest": "^29.7.0", "js-sdsl": "^4.4.2", 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 ce63d90..5ac45d5 100644 --- a/src/data-structures/binary-tree/avl-tree-multi-map.ts +++ b/src/data-structures/binary-tree/avl-tree-multi-map.ts @@ -14,7 +14,6 @@ import type { BTNCallback, KeyOrNodeOrEntry } from '../../types'; -import { FamilyPosition, IterationType } from '../../types'; import { IBinaryTree } from '../../interfaces'; import { AVLTree, AVLTreeNode } from './avl-tree'; @@ -249,9 +248,9 @@ export class AVLTreeMultiMap< if (curr.right !== undefined) this._setRoot(curr.right); } else { const { familyPosition: fp } = curr; - if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) { + if (fp === 'LEFT' || fp === 'ROOT_LEFT') { parent.left = curr.right; - } else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) { + } else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') { parent.right = curr.right; } needBalanced = parent; @@ -324,7 +323,7 @@ export class AVLTreeMultiMap< this.clear(); - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const buildBalanceBST = (l: number, r: number) => { if (l > r) return; const m = l + Math.floor((r - l) / 2); diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index 986127b..0a2a39c 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -107,16 +107,16 @@ export class BinaryTreeNode< get familyPosition(): FamilyPosition { const that = this as unknown as NODE; if (!this.parent) { - return this.left || this.right ? FamilyPosition.ROOT : FamilyPosition.ISOLATED; + return this.left || this.right ? 'ROOT' : 'ISOLATED'; } if (this.parent.left === that) { - return this.left || this.right ? FamilyPosition.ROOT_LEFT : FamilyPosition.LEFT; + return this.left || this.right ? 'ROOT_LEFT' : 'LEFT'; } else if (this.parent.right === that) { - return this.left || this.right ? FamilyPosition.ROOT_RIGHT : FamilyPosition.RIGHT; + return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT'; } - return FamilyPosition.MAL_NODE; + return 'MAL_NODE'; } } @@ -136,7 +136,7 @@ export class BinaryTree< > extends IterableEntryBase implements IBinaryTree { - iterationType = IterationType.ITERATIVE; + iterationType: IterationType = 'ITERATIVE'; /** * The constructor function initializes a binary tree object with optional keysOrNodesOrEntries and options. @@ -160,7 +160,7 @@ export class BinaryTree< if (keysOrNodesOrEntries) this.addMany(keysOrNodesOrEntries); } - protected _extractor = (key: K) => Number(key); + protected _extractor = (key: K) => (typeof key === 'number' ? key : Number(key)); /** * The function returns the value of the `_extractor` property. @@ -260,14 +260,11 @@ export class BinaryTree< * `null`, or `undefined`. It represents a key used to identify a node in a binary tree. * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the * type of iteration to be used when searching for a node by key. It has a default value of - * `IterationType.ITERATIVE`. + * `'ITERATIVE'`. * @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. */ - ensureNode( - keyOrNodeOrEntry: KeyOrNodeOrEntry, - iterationType = IterationType.ITERATIVE - ): NODE | null | undefined { + ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry, iterationType = 'ITERATIVE'): NODE | null | undefined { let res: NODE | null | undefined; if (this.isRealNode(keyOrNodeOrEntry)) { res = keyOrNodeOrEntry; @@ -521,9 +518,9 @@ export class BinaryTree< } } else if (parent) { const { familyPosition: fp } = curr; - if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) { + if (fp === 'LEFT' || fp === 'ROOT_LEFT') { parent.left = curr.right; - } else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) { + } else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') { parent.right = curr.right; } needBalanced = parent; @@ -606,7 +603,7 @@ export class BinaryTree< const ans: NODE[] = []; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _traverse = (cur: NODE) => { if (callback(cur) === identifier) { ans.push(cur); @@ -714,9 +711,9 @@ 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 { + getNodeByKey(key: K, iterationType = 'ITERATIVE'): NODE | undefined { if (!this.root) return undefined; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _dfs = (cur: NODE): NODE | undefined => { if (cur.key === key) return cur; @@ -932,7 +929,7 @@ export class BinaryTree< beginRoot = this.ensureNode(beginRoot); if (!beginRoot) return true; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const dfs = (cur: NODE | null | undefined, min: number, max: number): boolean => { if (!this.isRealNode(cur)) return true; const numKey = this.extractor(cur.key); @@ -1023,7 +1020,7 @@ export class BinaryTree< beginRoot = this.ensureNode(beginRoot); if (!this.isRealNode(beginRoot)) return -1; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _getMaxHeight = (cur: NODE | null | undefined): number => { if (!this.isRealNode(cur)) return -1; const leftHeight = _getMaxHeight(cur.left); @@ -1071,7 +1068,7 @@ export class BinaryTree< beginRoot = this.ensureNode(beginRoot); if (!beginRoot) return -1; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _getMinHeight = (cur: NODE | null | undefined): number => { if (!this.isRealNode(cur)) return 0; if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return 0; @@ -1174,7 +1171,7 @@ export class BinaryTree< if (!this.isRealNode(beginRoot)) return beginRoot; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _traverse = (cur: NODE): NODE => { if (!this.isRealNode(cur.left)) return cur; return _traverse(cur.left); @@ -1221,7 +1218,7 @@ export class BinaryTree< beginRoot = this.ensureNode(beginRoot); if (!beginRoot) return beginRoot; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _traverse = (cur: NODE): NODE => { if (!this.isRealNode(cur.right)) return cur; return _traverse(cur.right); @@ -1345,13 +1342,13 @@ export class BinaryTree< callback: C = this._defaultOneParamCallback as C, pattern: DFSOrderPattern = 'in', beginRoot: KeyOrNodeOrEntry = this.root, - iterationType: IterationType = IterationType.ITERATIVE, + iterationType: IterationType = 'ITERATIVE', includeNull = false ): ReturnType[] { beginRoot = this.ensureNode(beginRoot); if (!beginRoot) return []; const ans: ReturnType[] = []; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _traverse = (node: NODE | null | undefined) => { switch (pattern) { case 'in': @@ -1487,7 +1484,7 @@ export class BinaryTree< const ans: ReturnType>[] = []; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const queue: Queue = new Queue([beginRoot]); const traverse = (level: number) => { @@ -1580,7 +1577,7 @@ export class BinaryTree< const levelsNodes: ReturnType[][] = []; if (!beginRoot) return levelsNodes; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _recursive = (node: NODE | null, level: number) => { if (!levelsNodes[level]) levelsNodes[level] = []; levelsNodes[level].push(callback(node)); @@ -1876,7 +1873,7 @@ export class BinaryTree< protected* _getIterator(node = this.root): IterableIterator<[K, V | undefined]> { if (!node) return; - if (this.iterationType === IterationType.ITERATIVE) { + if (this.iterationType === 'ITERATIVE') { const stack: (NODE | null | undefined)[] = []; let current: NODE | null | undefined = node; diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index 1da74b4..d7cee30 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -126,7 +126,7 @@ export class BST< return this._root; } - protected _variant = BSTVariant.STANDARD; + protected _variant: BSTVariant = 'STANDARD'; /** * The function returns the value of the _variant property. @@ -207,13 +207,10 @@ export class BST< * @param {K | NODE | undefined} keyOrNodeOrEntry - The `key` parameter can be of type `K`, `NODE`, or * `undefined`. * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the - * type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`. + * type of iteration to be performed. It has a default value of `'ITERATIVE'`. * @returns either a node object (NODE) or undefined. */ - override ensureNode( - keyOrNodeOrEntry: KeyOrNodeOrEntry, - iterationType = IterationType.ITERATIVE - ): NODE | undefined { + override ensureNode(keyOrNodeOrEntry: KeyOrNodeOrEntry, iterationType = 'ITERATIVE'): NODE | undefined { let res: NODE | undefined; if (this.isRealNode(keyOrNodeOrEntry)) { res = keyOrNodeOrEntry; @@ -263,7 +260,7 @@ export class BST< let current = this.root; while (current !== undefined) { - if (this._compare(current.key, newNode.key) === CP.eq) { + if (this._compare(current.key, newNode.key) === 'EQ') { // if (current !== newNode) { // The key value is the same but the reference is different, update the value of the existing node this._replaceNode(current, newNode); @@ -275,7 +272,7 @@ export class BST< // return; // } - } else if (this._compare(current.key, newNode.key) === CP.gt) { + } else if (this._compare(current.key, newNode.key) === 'GT') { if (current.left === undefined) { current.left = newNode; this._size++; @@ -397,7 +394,7 @@ export class BST< } }; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { _dfs(sorted); } else { _iterate(); @@ -425,15 +422,15 @@ export class BST< * @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 { + override getNodeByKey(key: K, iterationType = 'ITERATIVE'): NODE | undefined { if (!this.isRealNode(this.root)) return undefined; - if (iterationType === IterationType.RECURSIVE) { + 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._compare(cur.key, key) === CP.gt && this.isRealNode(cur.left)) return _dfs(cur.left); - if (this._compare(cur.key, key) === CP.lt && this.isRealNode(cur.right)) return _dfs(cur.right); + 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); }; return _dfs(this.root); @@ -442,9 +439,9 @@ export class BST< while (queue.size > 0) { const cur = queue.shift(); if (this.isRealNode(cur)) { - if (this._compare(cur.key, key) === CP.eq) return cur; - if (this._compare(cur.key, key) === CP.gt) this.isRealNode(cur.left) && queue.push(cur.left); - if (this._compare(cur.key, key) === CP.lt) this.isRealNode(cur.right) && queue.push(cur.right); + 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); } } } @@ -489,7 +486,7 @@ export class BST< if (!beginRoot) return []; const ans: NODE[] = []; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _traverse = (cur: NODE) => { const callbackResult = callback(cur); if (callbackResult === identifier) { @@ -500,8 +497,8 @@ export class BST< if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return; // TODO potential bug if (callback === this._defaultOneParamCallback) { - if (this._compare(cur.key, identifier as K) === CP.gt) this.isRealNode(cur.left) && _traverse(cur.left); - if (this._compare(cur.key, identifier as K) === CP.lt) this.isRealNode(cur.right) && _traverse(cur.right); + 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); } else { this.isRealNode(cur.left) && _traverse(cur.left); this.isRealNode(cur.right) && _traverse(cur.right); @@ -510,9 +507,9 @@ export class BST< _traverse(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 (this.isRealNode(cur)) { const callbackResult = callback(cur); if (callbackResult === identifier) { @@ -521,11 +518,19 @@ export class BST< } // TODO potential bug if (callback === this._defaultOneParamCallback) { - if (this._compare(cur.key, identifier as K) === CP.gt) this.isRealNode(cur.left) && queue.push(cur.left); - if (this._compare(cur.key, identifier as K) === CP.lt) this.isRealNode(cur.right) && queue.push(cur.right); + 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); + + // // @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.left) && queue.push(cur.left); - this.isRealNode(cur.right) && queue.push(cur.right); + this.isRealNode(cur.right) && stack.push(cur.right); + this.isRealNode(cur.left) && stack.push(cur.left); } } } @@ -562,7 +567,7 @@ export class BST< callback: C = this._defaultOneParamCallback as C, pattern: DFSOrderPattern = 'in', beginRoot: KeyOrNodeOrEntry = this.root, - iterationType: IterationType = IterationType.ITERATIVE + iterationType: IterationType = 'ITERATIVE' ): ReturnType[] { return super.dfs(callback, pattern, beginRoot, iterationType, false); } @@ -650,7 +655,7 @@ export class BST< let current = this.ensureNode(beginRoot); if (!current) return undefined; - if (this._variant === BSTVariant.STANDARD) { + if (this._variant === 'STANDARD') { // For BSTVariant.MIN, find the rightmost node while (current.right !== undefined) { current = current.right; @@ -692,7 +697,7 @@ export class BST< */ lesserOrGreaterTraverse>( callback: C = this._defaultOneParamCallback as C, - lesserOrGreater: CP = CP.lt, + lesserOrGreater: CP = 'LT', targetNode: KeyOrNodeOrEntry = this.root, iterationType = this.iterationType ): ReturnType[] { @@ -703,7 +708,7 @@ export class BST< const targetKey = targetNode.key; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _traverse = (cur: NODE) => { const compared = this._compare(cur.key, targetKey); if (compared === lesserOrGreater) ans.push(callback(cur)); @@ -752,7 +757,7 @@ export class BST< this.clear(); if (sorted.length < 1) return false; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const buildBalanceBST = (l: number, r: number) => { if (l > r) return; const m = l + Math.floor((r - l) / 2); @@ -812,7 +817,7 @@ export class BST< let balanced = true; - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const _height = (cur: NODE | undefined): number => { if (!cur) return 0; const leftHeight = _height(cur.left), @@ -868,14 +873,32 @@ export class BST< * 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 CP.gt (greater - * than), CP.lt (less than), or CP.eq (equal). + * @returns a value of type CP (ComparisonResult). The possible return values are 'GT' (greater + * than), 'LT' (less than), or 'EQ' (equal). */ protected _compare(a: K, b: K): CP { const extractedA = this.extractor(a); const extractedB = this.extractor(b); - const compared = this.variant === BSTVariant.STANDARD ? extractedA - extractedB : extractedB - extractedA; + const compared = this.variant === 'STANDARD' ? extractedA - extractedB : extractedB - extractedA; - return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq; + return compared > 0 ? 'GT' : compared < 0 ? 'LT' : 'EQ'; + } + + 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; + } + + 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 50269f3..9120e2e 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -234,8 +234,8 @@ export class RedBlackTree< beginRoot: BSTNKeyOrNode = this.root, iterationType = this.iterationType ): NODE | null | undefined { - if ((identifier as any) instanceof RedBlackTreeNode) callback = (node => node) as C; - return super.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined; + // if ((identifier as any) instanceof RedBlackTreeNode) callback = (node => node) as C; + return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined; } /** @@ -279,7 +279,7 @@ export class RedBlackTree< const insertStatus = this._insert(newNode); - if (insertStatus === CRUD.CREATED) { + if (insertStatus === 'CREATED') { // Ensure the root is black if (this.isRealNode(this._root)) { this._root.color = RBTNColor.BLACK; @@ -288,7 +288,7 @@ export class RedBlackTree< } this._size++; return true; - } else return insertStatus === CRUD.UPDATED; + } else return insertStatus === 'UPDATED'; } /** @@ -435,7 +435,7 @@ export class RedBlackTree< current = current.right ?? this.SENTINEL; } else { this._replaceNode(current, node); - return CRUD.UPDATED; + return 'UPDATED'; } } @@ -454,7 +454,7 @@ export class RedBlackTree< node.color = RBTNColor.RED; this._insertFixup(node); - return CRUD.CREATED; + return 'CREATED'; } /** diff --git a/src/data-structures/binary-tree/tree-multi-map.ts b/src/data-structures/binary-tree/tree-multi-map.ts index 2ac2aba..5f6d86c 100644 --- a/src/data-structures/binary-tree/tree-multi-map.ts +++ b/src/data-structures/binary-tree/tree-multi-map.ts @@ -14,7 +14,7 @@ import type { TreeMultiMapNodeNested, TreeMultiMapOptions } from '../../types'; -import { IterationType, RBTNColor } from '../../types'; +import { RBTNColor } from '../../types'; import { IBinaryTree } from '../../interfaces'; import { RedBlackTree, RedBlackTreeNode } from './rb-tree'; @@ -363,7 +363,7 @@ export class TreeMultiMap< this.clear(); - if (iterationType === IterationType.RECURSIVE) { + if (iterationType === 'RECURSIVE') { const buildBalanceBST = (l: number, r: number) => { if (l > r) return; const m = l + Math.floor((r - l) / 2); diff --git a/src/types/common.ts b/src/types/common.ts index fce4da0..5382da5 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -1,13 +1,5 @@ -export enum BSTVariant { - STANDARD = 'STANDARD', - INVERSE = 'INVERSE' -} - -export enum CP { - lt = 'lt', - eq = 'eq', - gt = 'gt' -} +export type BSTVariant = 'STANDARD' | 'INVERSE'; +export type CP = 'LT' | 'EQ' | 'GT'; /** * Enum representing different loop types. @@ -15,20 +7,9 @@ export enum CP { * - `iterative`: Indicates the iterative loop type (with loops that use iterations). * - `recursive`: Indicates the recursive loop type (with loops that call themselves). */ -export enum IterationType { - ITERATIVE = 'ITERATIVE', - RECURSIVE = 'RECURSIVE' -} +export type IterationType = 'ITERATIVE' | 'RECURSIVE'; -export enum FamilyPosition { - ROOT = 'ROOT', - LEFT = 'LEFT', - RIGHT = 'RIGHT', - ROOT_LEFT = 'ROOT_LEFT', - ROOT_RIGHT = 'ROOT_RIGHT', - ISOLATED = 'ISOLATED', - MAL_NODE = 'MAL_NODE' -} +export type FamilyPosition = 'ROOT' | 'LEFT' | 'RIGHT' | 'ROOT_LEFT' | 'ROOT_RIGHT' | 'ISOLATED' | 'MAL_NODE'; export type Comparator = (a: K, b: K) => number; @@ -64,9 +45,4 @@ export type BSTNKeyOrNode = K | undefined | N; export type BinaryTreeDeleteResult = { deleted: N | null | undefined; needBalanced: N | null | undefined }; -export enum CRUD { - CREATED = 'CREATED', - READ = 'READ', - UPDATED = 'UPDATED', - DELETED = 'DELETED' -} +export type CRUD = 'CREATED' | 'READ' | 'UPDATED' | 'DELETED'; diff --git a/test/integration/all-in-one.test.ts b/test/integration/all-in-one.test.ts index 88a0b5b..534e068 100644 --- a/test/integration/all-in-one.test.ts +++ b/test/integration/all-in-one.test.ts @@ -1,4 +1,4 @@ -import { AVLTree, CP } from 'data-structure-typed'; +import { AVLTree } from 'data-structure-typed'; describe('AVL Tree Test from data-structure-typed', () => { it('should perform various operations on a AVL Tree from data-structure-typed', () => { @@ -27,7 +27,7 @@ describe('AVL Tree Test from data-structure-typed', () => { expect(subTreeSum).toBe(70); let lesserSum = 0; - tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10); + tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); // node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class. diff --git a/test/integration/avl-tree.test.ts b/test/integration/avl-tree.test.ts index 0e0c851..1226eee 100644 --- a/test/integration/avl-tree.test.ts +++ b/test/integration/avl-tree.test.ts @@ -40,7 +40,7 @@ describe('AVL Tree Test', () => { expect(getMinNodeBySpecificNode?.key).toBe(12); let subTreeSum = 0; - node15 && tree.subTreeTraverse(node => (subTreeSum += node.key), 15); + node15 && tree.dfs(node => (subTreeSum += node.key), 'in', 15); expect(subTreeSum).toBe(70); let lesserSum = 0; diff --git a/test/integration/bst.test.ts b/test/integration/bst.test.ts index e954728..8d3b482 100644 --- a/test/integration/bst.test.ts +++ b/test/integration/bst.test.ts @@ -34,7 +34,7 @@ describe('Individual package BST operations test', () => { expect(minNodeBySpecificNode?.key).toBe(12); let subTreeSum = 0; - node15 && bst.subTreeTraverse(node => (subTreeSum += node.key), 15); + node15 && bst.dfs(node => (subTreeSum += node.key), 'in', 15); expect(subTreeSum).toBe(70); let lesserSum = 0; @@ -231,7 +231,7 @@ describe('Individual package BST operations test', () => { expect(minNodeBySpecificNode?.key).toBe(12); let subTreeSum = 0; - node15 && objBST.subTreeTraverse(node => (subTreeSum += node.key), node15); + node15 && objBST.dfs(node => (subTreeSum += node.key), 'in', node15); expect(subTreeSum).toBe(70); let lesserSum = 0; diff --git a/test/performance/data-structures/binary-tree/rb-tree.test.ts b/test/performance/data-structures/binary-tree/rb-tree.test.ts index 102bf4b..dcefa15 100644 --- a/test/performance/data-structures/binary-tree/rb-tree.test.ts +++ b/test/performance/data-structures/binary-tree/rb-tree.test.ts @@ -12,35 +12,29 @@ const cOrderedMap = new OrderedMap(); suite .add(`${HUNDRED_THOUSAND.toLocaleString()} add orderly`, () => { + rbTree.clear(); for (let i = 0; i < randomArray.length; i++) rbTree.add(i); }) - .add(`${HUNDRED_THOUSAND.toLocaleString()} delete orderly`, () => { + .add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete orderly`, () => { + rbTree.clear(); + for (let i = 0; i < randomArray.length; i++) rbTree.add(i); for (let i = 0; i < randomArray.length; i++) rbTree.delete(i); }) .add(`${HUNDRED_THOUSAND.toLocaleString()} add randomly`, () => { rbTree.clear(); for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]); }) - .add(`${HUNDRED_THOUSAND.toLocaleString()} delete randomly`, () => { + .add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete randomly`, () => { + rbTree.clear(); + for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]); for (let i = 0; i < randomArray.length; i++) rbTree.delete(randomArray[i]); }) - .add(`${HUNDRED_THOUSAND.toLocaleString()} add orderly`, () => { - for (let i = 0; i < randomArray.length; i++) rbTree.add(i); - }) - .add(`${HUNDRED_THOUSAND.toLocaleString()} delete randomly`, () => { - for (let i = 0; i < randomArray.length; i++) rbTree.delete(randomArray[i]); + .add(`${HUNDRED_THOUSAND.toLocaleString()} add & get randomly`, () => { + rbTree.clear(); + for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]); + for (let i = 0; i < randomArray.length; i++) rbTree.get(randomArray[i]); }); -if (isCompetitor) { - suite.add(`CPT ${HUNDRED_THOUSAND.toLocaleString()} add`, () => { - for (let i = 0; i < randomArray.length; i++) cOrderedMap.setElement(randomArray[i], randomArray[i]); - }); -} - -suite.add(`${HUNDRED_THOUSAND.toLocaleString()} getNode randomly`, () => { - for (let i = 0; i < randomArray.length; i++) rbTree.getNode(randomArray[i]); -}); - suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & iterator`, () => { rbTree.clear(); for (let i = 0; i < randomArray.length; i++) rbTree.add(randomArray[i]); @@ -48,4 +42,10 @@ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & iterator`, () => { return entries.length === HUNDRED_THOUSAND; }); +if (isCompetitor) { + suite.add(`CPT ${HUNDRED_THOUSAND.toLocaleString()} add`, () => { + for (let i = 0; i < randomArray.length; i++) cOrderedMap.setElement(randomArray[i], randomArray[i]); + }); +} + export { suite }; diff --git a/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts b/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts index 877737d..9e57980 100644 --- a/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +++ b/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts @@ -1,12 +1,4 @@ -import { - AVLTreeMultiMap, - AVLTreeMultiMapNode, - AVLTreeNode, - BinaryTreeNode, - BSTNode, - CP, - IterationType -} from '../../../../src'; +import { AVLTreeMultiMap, AVLTreeMultiMapNode, AVLTreeNode, BinaryTreeNode, BSTNode } from '../../../../src'; import { isDebugTest } from '../../../config'; const isDebug = isDebugTest; @@ -36,7 +28,7 @@ describe('AVLTreeMultiMap count', () => { [3, 3] ]); tm.add([2, 2], undefined, 10); - tm.lesserOrGreaterTraverse(node => (node.count += 2), CP.gt, 1); + tm.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 1); tm.delete(2); expect(tm.count).toBe(12); expect(tm.getMutableCount()).toBe(16); @@ -102,7 +94,7 @@ describe('AVLTreeMultiMap operations test1', () => { node15 && treeMultimap.dfs(node => (subTreeSum += node.key), 'pre', 15); expect(subTreeSum).toBe(31); let lesserSum = 0; - treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode) => (lesserSum += node.key), CP.lt, 10); + treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode) => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); expect(node15 instanceof AVLTreeMultiMapNode); @@ -113,7 +105,7 @@ describe('AVLTreeMultiMap operations test1', () => { const node11 = treeMultimap.getNode(11); expect(node11 instanceof AVLTreeMultiMapNode); if (node11 instanceof AVLTreeMultiMapNode) { - const allGreaterNodesAdded = treeMultimap.lesserOrGreaterTraverse(node => (node.count += 2), CP.gt, 11); + const allGreaterNodesAdded = treeMultimap.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 11); expect(allGreaterNodesAdded); } @@ -299,7 +291,7 @@ describe('AVLTreeMultiMap operations test1', () => { describe('AVLTreeMultiMap operations test recursively1', () => { it('should perform various operations on a Binary Search Tree with numeric values1', () => { - const treeMultimap = new AVLTreeMultiMap([], { iterationType: IterationType.RECURSIVE }); + const treeMultimap = new AVLTreeMultiMap([], { iterationType: 'RECURSIVE' }); expect(treeMultimap instanceof AVLTreeMultiMap); treeMultimap.add([11, 11]); @@ -356,7 +348,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { node15 && treeMultimap.dfs(node => (subTreeSum += node.key), 'pre', 15); expect(subTreeSum).toBe(31); let lesserSum = 0; - treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode) => (lesserSum += node.key), CP.lt, 10); + treeMultimap.lesserOrGreaterTraverse((node: AVLTreeMultiMapNode) => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); expect(node15 instanceof AVLTreeMultiMapNode); @@ -367,7 +359,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => { const node11 = treeMultimap.getNode(11); expect(node11 instanceof AVLTreeMultiMapNode); if (node11 instanceof AVLTreeMultiMapNode) { - const allGreaterNodesAdded = treeMultimap.lesserOrGreaterTraverse(node => (node.count += 2), CP.gt, 11); + const allGreaterNodesAdded = treeMultimap.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 11); expect(allGreaterNodesAdded); } @@ -572,7 +564,7 @@ describe('AVLTreeMultiMap Performance test', function () { } isDebug && console.log('---add', performance.now() - start); const startL = performance.now(); - treeMS.lesserOrGreaterTraverse(node => (node.count += 1), CP.lt, inputSize / 2); + treeMS.lesserOrGreaterTraverse(node => (node.count += 1), 'LT', inputSize / 2); isDebug && console.log('---lesserOrGreaterTraverse', performance.now() - startL); }); diff --git a/test/unit/data-structures/binary-tree/avl-tree.test.ts b/test/unit/data-structures/binary-tree/avl-tree.test.ts index 334a47e..900693d 100644 --- a/test/unit/data-structures/binary-tree/avl-tree.test.ts +++ b/test/unit/data-structures/binary-tree/avl-tree.test.ts @@ -1,4 +1,4 @@ -import { AVLTree, AVLTreeNode, BinaryTreeNode, BSTNode, CP, IterationType } from '../../../../src'; +import { AVLTree, AVLTreeNode, BinaryTreeNode, BSTNode } from '../../../../src'; describe('AVL Tree Test', () => { it('should perform various operations on a AVL Tree', () => { @@ -28,7 +28,7 @@ describe('AVL Tree Test', () => { expect(subTreeSum).toBe(70); let lesserSum = 0; - tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10); + tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); // node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class. @@ -112,7 +112,7 @@ describe('AVL Tree Test', () => { describe('AVL Tree Test recursively', () => { it('should perform various operations on a AVL Tree', () => { const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]; - const tree = new AVLTree([], { iterationType: IterationType.RECURSIVE }); + const tree = new AVLTree([], { iterationType: 'RECURSIVE' }); for (const i of arr) tree.add([i, i]); @@ -136,7 +136,7 @@ describe('AVL Tree Test recursively', () => { expect(subTreeSum).toBe(70); let lesserSum = 0; - tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10); + tree.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); // node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class. diff --git a/test/unit/data-structures/binary-tree/binary-tree.test.ts b/test/unit/data-structures/binary-tree/binary-tree.test.ts index b80d909..96b8a8e 100644 --- a/test/unit/data-structures/binary-tree/binary-tree.test.ts +++ b/test/unit/data-structures/binary-tree/binary-tree.test.ts @@ -1,4 +1,4 @@ -import { BinaryTree, BinaryTreeNode, FamilyPosition, IterationType } from '../../../../src'; +import { BinaryTree, BinaryTreeNode } from '../../../../src'; import { getRandomIntArray } from '../../../utils'; // import { isDebugTest } from '../../../config'; @@ -81,7 +81,7 @@ describe('BinaryTreeNode', () => { root.right = rightChild; expect(rightChild.familyPosition).toBe('RIGHT'); - expect(isolated.familyPosition).toBe(FamilyPosition.ISOLATED); + expect(isolated.familyPosition).toBe('ISOLATED'); expect(root.familyPosition).toBe('ROOT'); }); }); @@ -104,7 +104,7 @@ describe('BinaryTree', () => { }); it('should delete nodes', () => { - expect(tree.getHeight(tree.root, IterationType.ITERATIVE)).toBe(-1); + expect(tree.getHeight(tree.root, 'ITERATIVE')).toBe(-1); expect(tree.getMinHeight()).toBe(-1); const node1 = tree.createNode(1); tree.add(node1); @@ -132,7 +132,7 @@ describe('BinaryTree', () => { const result = tree.delete(node1); expect(result).toHaveLength(1); expect(tree.size).toBe(4); - expect(tree.getMinHeight(tree.root, IterationType.RECURSIVE)).toBe(1); + expect(tree.getMinHeight(tree.root, 'RECURSIVE')).toBe(1); } }); @@ -171,16 +171,25 @@ describe('BinaryTree', () => { expect(cloned.root?.right?.key).toBe(6); expect(cloned.root?.right?.left?.key).toBe(3); expect(cloned.root?.right?.right).toBe(null); - expect(cloned.dfs(node => node.key, 'pre', cloned.getNode(6), IterationType.ITERATIVE)).toEqual([6, 3, 7]); - expect( - cloned.dfs(node => (node ? node.key : null), 'pre', cloned.getNode(6), IterationType.ITERATIVE, true) - ).toEqual([6, 3, 7, null]); - expect( - cloned.dfs(node => (node ? node.key : node), 'pre', cloned.getNode(6), IterationType.ITERATIVE, true) - ).toEqual([6, 3, 7, null]); - expect( - cloned.dfs(node => (node ? node.key : null), 'pre', cloned.getNode(6), IterationType.RECURSIVE, true) - ).toEqual([6, 3, 7, null]); + expect(cloned.dfs(node => node.key, 'pre', cloned.getNode(6), 'ITERATIVE')).toEqual([6, 3, 7]); + expect(cloned.dfs(node => (node ? node.key : null), 'pre', cloned.getNode(6), 'ITERATIVE', true)).toEqual([ + 6, + 3, + 7, + null + ]); + expect(cloned.dfs(node => (node ? node.key : node), 'pre', cloned.getNode(6), 'ITERATIVE', true)).toEqual([ + 6, + 3, + 7, + null + ]); + expect(cloned.dfs(node => (node ? node.key : null), 'pre', cloned.getNode(6), 'RECURSIVE', true)).toEqual([ + 6, + 3, + 7, + null + ]); cloned.delete(6); cloned.delete(3); cloned.delete(7); @@ -234,9 +243,9 @@ describe('BinaryTree', () => { tree.add(4); tree.add(2); expect(tree.getHeight()).toBe(1); - tree.iterationType = IterationType.RECURSIVE; + tree.iterationType = 'RECURSIVE'; expect(tree.getHeight()).toBe(1); - tree.iterationType = IterationType.ITERATIVE; + tree.iterationType = 'ITERATIVE'; tree.add(6); tree.add(1); @@ -252,9 +261,9 @@ describe('BinaryTree', () => { it('should getLeftMost', () => { tree.addMany([4, 2, 6, 1, 3, 5, 7]); - const leftMost = tree.getLeftMost(tree.root, IterationType.RECURSIVE); + const leftMost = tree.getLeftMost(tree.root, 'RECURSIVE'); expect(leftMost?.key).toEqual(1); - const rightMost = tree.getRightMost(tree.root, IterationType.RECURSIVE); + const rightMost = tree.getRightMost(tree.root, 'RECURSIVE'); expect(rightMost?.key).toEqual(7); }); @@ -270,37 +279,37 @@ describe('BinaryTree', () => { new BinaryTreeNode(4, 4) ]); - expect(tree.isBST(tree.getNode(4), IterationType.RECURSIVE)).toBe(true); - expect(tree.isBST(tree.getNode(4), IterationType.ITERATIVE)).toBe(true); + expect(tree.isBST(tree.getNode(4), 'RECURSIVE')).toBe(true); + expect(tree.isBST(tree.getNode(4), 'ITERATIVE')).toBe(true); }); it('should isSubtreeBST', () => { tree.addMany([4, 2, 6, 1, 3, 5, 7, 4]); - expect(tree.isBST(tree.getNode(4), IterationType.RECURSIVE)).toBe(true); - expect(tree.isBST(tree.getNode(4), IterationType.ITERATIVE)).toBe(true); + expect(tree.isBST(tree.getNode(4), 'RECURSIVE')).toBe(true); + expect(tree.isBST(tree.getNode(4), 'ITERATIVE')).toBe(true); expect(tree.getNodes(2, undefined, false, null)).toEqual([]); expect(tree.getNodes(tree.getNodeByKey(2), undefined, false, tree.root)).toEqual([tree.getNodeByKey(2)]); }); it('should sub tree traverse', () => { tree.addMany([4, 2, 6, null, 1, 3, null, 5, null, 7]); - expect(tree.dfs(node => node.key, 'pre', tree.getNode(6), IterationType.ITERATIVE)).toEqual([6, 3, 7]); - expect(tree.dfs(node => node.key, 'pre', tree.getNode(6), IterationType.ITERATIVE, false)).toEqual([6, 3, 7]); - expect(tree.dfs(node => node.key, 'pre', tree.getNode(6), IterationType.RECURSIVE)).toEqual([6, 3, 7]); - expect(tree.dfs(node => (node ? node.key : null), 'pre', tree.getNode(6), IterationType.ITERATIVE, true)).toEqual([ + expect(tree.dfs(node => node.key, 'pre', tree.getNode(6), 'ITERATIVE')).toEqual([6, 3, 7]); + expect(tree.dfs(node => node.key, 'pre', tree.getNode(6), 'ITERATIVE', false)).toEqual([6, 3, 7]); + expect(tree.dfs(node => node.key, 'pre', tree.getNode(6), 'RECURSIVE')).toEqual([6, 3, 7]); + expect(tree.dfs(node => (node ? node.key : null), 'pre', tree.getNode(6), 'ITERATIVE', true)).toEqual([ 6, 3, 7, null ]); - expect(tree.dfs(node => (node ? node.key : node), 'pre', tree.getNode(6), IterationType.ITERATIVE, true)).toEqual([ + expect(tree.dfs(node => (node ? node.key : node), 'pre', tree.getNode(6), 'ITERATIVE', true)).toEqual([ 6, 3, 7, null ]); - expect(tree.dfs(node => (node ? node.key : null), 'pre', tree.getNode(6), IterationType.RECURSIVE, true)).toEqual([ + expect(tree.dfs(node => (node ? node.key : null), 'pre', tree.getNode(6), 'RECURSIVE', true)).toEqual([ 6, 3, 7, @@ -360,7 +369,7 @@ describe('BinaryTree Morris Traversal', () => { expect(result).toEqual(expected); expect(tree.dfs(node => node.key, 'in')).toEqual(expected); - expect(tree.dfs(node => node.key, 'in', tree.root, IterationType.RECURSIVE)).toEqual(expected); + expect(tree.dfs(node => node.key, 'in', tree.root, 'RECURSIVE')).toEqual(expected); }); it('should perform pre-order Morris traversal correctly as dfs traversal', () => { @@ -399,57 +408,101 @@ describe('BinaryTree traversals', () => { const arr = [35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]; tree.refill(arr); - expect( - tree.bfs(node => node, tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null)) - ).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]); - expect( - tree.bfs(node => node, tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null)) - ).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]); - expect( - tree.bfs(node => node, tree.root, IterationType.ITERATIVE).map(node => (node === null ? null : node.key)) - ).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]); - expect( - tree.bfs(node => node, tree.root, IterationType.RECURSIVE).map(node => (node === null ? null : node.key)) - ).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]); + expect(tree.bfs(node => node, tree.root, 'ITERATIVE', true).map(node => (node ? node.key : null))).toEqual([ + 35, + 20, + 40, + 15, + 29, + null, + 50, + null, + 16, + 28, + 30, + 45, + 55 + ]); + expect(tree.bfs(node => node, tree.root, 'RECURSIVE', true).map(node => (node ? node.key : null))).toEqual([ + 35, + 20, + 40, + 15, + 29, + null, + 50, + null, + 16, + 28, + 30, + 45, + 55 + ]); + expect(tree.bfs(node => node, tree.root, 'ITERATIVE').map(node => (node === null ? null : node.key))).toEqual([ + 35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55 + ]); + expect(tree.bfs(node => node, tree.root, 'RECURSIVE').map(node => (node === null ? null : node.key))).toEqual([ + 35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55 + ]); expect(tree.dfs(node => node.key, 'pre')).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]); - expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([ + expect(tree.dfs(node => node.key, 'pre', tree.root, 'RECURSIVE')).toEqual([ 35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55 ]); - expect( - tree.dfs(node => node, 'pre', tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null)) - ).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]); - expect( - tree.dfs(node => node, 'pre', tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null)) - ).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]); + expect(tree.dfs(node => node, 'pre', tree.root, 'ITERATIVE', true).map(node => (node ? node.key : null))).toEqual([ + 35, + 20, + 15, + null, + 16, + 29, + 28, + 30, + 40, + null, + 50, + 45, + 55 + ]); + expect(tree.dfs(node => node, 'pre', tree.root, 'RECURSIVE', true).map(node => (node ? node.key : null))).toEqual([ + 35, + 20, + 15, + null, + 16, + 29, + 28, + 30, + 40, + null, + 50, + 45, + 55 + ]); expect(tree.dfs(node => node.key, 'in')).toEqual([15, 16, 20, 28, 29, 30, 35, 40, 45, 50, 55]); expect(tree.dfs(node => node.key, 'post')).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]); - expect(tree.dfs(node => node.key, 'post', tree.root, IterationType.RECURSIVE)).toEqual([ + expect(tree.dfs(node => node.key, 'post', tree.root, 'RECURSIVE')).toEqual([ 16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35 ]); - expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([ - 35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55 - ]); - expect(tree.bfs(node => node.key, tree.root, IterationType.ITERATIVE)).toEqual([ - 35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55 - ]); + expect(tree.bfs(node => node.key, tree.root, 'RECURSIVE')).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]); + expect(tree.bfs(node => node.key, tree.root, 'ITERATIVE')).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]); expect(tree.listLevels(node => node.key)).toEqual([[35], [20, 40], [15, 29, 50], [16, 28, 30, 45, 55]]); - expect(tree.listLevels(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([ + expect(tree.listLevels(node => node.key, tree.root, 'RECURSIVE')).toEqual([ [35], [20, 40], [15, 29, 50], [16, 28, 30, 45, 55] ]); - expect(tree.listLevels(node => (node ? node.key : null), tree.root, IterationType.ITERATIVE, true)).toEqual([ + expect(tree.listLevels(node => (node ? node.key : null), tree.root, 'ITERATIVE', true)).toEqual([ [35], [20, 40], [15, 29, null, 50], [null, 16, 28, 30, 45, 55] ]); - expect(tree.listLevels(node => (node ? node.key : null), tree.root, IterationType.RECURSIVE, true)).toEqual([ + expect(tree.listLevels(node => (node ? node.key : null), tree.root, 'RECURSIVE', true)).toEqual([ [35], [20, 40], [15, 29, null, 50], @@ -461,7 +514,7 @@ describe('BinaryTree', () => { let tree: BinaryTree; beforeEach(() => { - tree = new BinaryTree([], { iterationType: IterationType.RECURSIVE }); + tree = new BinaryTree([], { iterationType: 'RECURSIVE' }); }); afterEach(() => { @@ -533,8 +586,8 @@ describe('BinaryTree', () => { tree.add([7, 'C']); expect(tree.getHeight()).toBe(1); - expect(tree.getHeight(undefined, IterationType.RECURSIVE)).toBe(1); - expect(tree.getMinHeight(undefined, IterationType.RECURSIVE)).toBe(1); + expect(tree.getHeight(undefined, 'RECURSIVE')).toBe(1); + expect(tree.getMinHeight(undefined, 'RECURSIVE')).toBe(1); }); it('should check if the tree is a binary search tree', () => { @@ -604,7 +657,7 @@ describe('BinaryTree', () => { expect(nodes.length).toBe(1); expect(nodes[0].key).toBe(3); - const nodesRec = tree.getNodes('B', node => node.value, false, tree.root, IterationType.RECURSIVE); + const nodesRec = tree.getNodes('B', node => node.value, false, tree.root, 'RECURSIVE'); expect(nodesRec.length).toBe(1); expect(nodesRec[0].key).toBe(3); @@ -615,19 +668,19 @@ describe('BinaryTree', () => { tree.add([3, 'B']); tree.add([7, 'C']); - tree.iterationType = IterationType.ITERATIVE; + tree.iterationType = 'ITERATIVE'; expect([...tree]).toEqual([ [3, 'B'], [5, 'A'], [7, 'C'] ]); - tree.iterationType = IterationType.RECURSIVE; + tree.iterationType = 'RECURSIVE'; expect([...tree]).toEqual([ [3, 'B'], [5, 'A'], [7, 'C'] ]); - tree.iterationType = IterationType.ITERATIVE; + tree.iterationType = 'ITERATIVE'; const result = tree.morris(); expect(result).toEqual([3, 5, 7]); diff --git a/test/unit/data-structures/binary-tree/bst.test.ts b/test/unit/data-structures/binary-tree/bst.test.ts index f49c347..d5b274d 100644 --- a/test/unit/data-structures/binary-tree/bst.test.ts +++ b/test/unit/data-structures/binary-tree/bst.test.ts @@ -1,4 +1,4 @@ -import { BinaryTreeNode, BST, BSTNode, BSTVariant, CP, IterationType } from '../../../../src'; +import { BinaryTreeNode, BST, BSTNode } from '../../../../src'; import { isDebugTest } from '../../../config'; const isDebug = isDebugTest; @@ -58,7 +58,7 @@ describe('BST operations test', () => { expect(subTreeSum).toBe(70); let lesserSum = 0; - bst.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10); + bst.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); expect(node15).toBeInstanceOf(BSTNode); @@ -261,7 +261,7 @@ describe('BST operations test', () => { expect(subTreeSum).toBe(70); let lesserSum = 0; - objBST.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10); + objBST.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); expect(node15).toBeInstanceOf(BSTNode); @@ -411,7 +411,7 @@ describe('BST operations test', () => { describe('BST operations test recursively', () => { it('should perform various operations on a Binary Search Tree with numeric values', () => { - const bst = new BST([], { iterationType: IterationType.RECURSIVE }); + const bst = new BST([], { iterationType: 'RECURSIVE' }); expect(bst).toBeInstanceOf(BST); bst.add([11, 11]); bst.add([3, 3]); @@ -448,7 +448,7 @@ describe('BST operations test recursively', () => { expect(subTreeSum).toBe(70); let lesserSum = 0; - bst.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10); + bst.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); expect(node15).toBeInstanceOf(BSTNode); @@ -649,7 +649,7 @@ describe('BST operations test recursively', () => { expect(subTreeSum).toBe(70); let lesserSum = 0; - objBST.lesserOrGreaterTraverse(node => (lesserSum += node.key), CP.lt, 10); + objBST.lesserOrGreaterTraverse(node => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); expect(node15).toBeInstanceOf(BSTNode); @@ -869,7 +869,7 @@ describe('BST isBST', function () { }); test('isBST when variant is Max', () => { - const bst = new BST([1, 2, 3, 9, 8, 5, 6, 7, 4], { variant: BSTVariant.INVERSE }); + const bst = new BST([1, 2, 3, 9, 8, 5, 6, 7, 4], { variant: 'INVERSE' }); bst.addMany([1, 2, 3, 9, 8, 5, 6, 7, 4]); expect(bst.isBST()).toBe(true); }); @@ -902,7 +902,7 @@ describe('BST Performance test', function () { node => { node.key - 1; }, - CP.lt, + 'LT', inputSize / 2 ); isDebug && console.log('---lesserOrGreaterTraverse', performance.now() - startL); @@ -932,10 +932,10 @@ describe('BST Performance test', function () { it('should dfs as sub tree traversal, null should be ignored', () => { const bst = new BST(); bst.addMany([4, 2, 6, 1, 3, 5, 7]); - expect(bst.dfs(node => node.key, 'pre', bst.getNode(6), IterationType.ITERATIVE)).toEqual([6, 5, 7]); - expect(bst.dfs(node => node.key, 'pre', bst.getNode(6), IterationType.RECURSIVE)).toEqual([6, 5, 7]); - expect(bst.dfs(node => node?.key ?? undefined, 'pre', bst.getNode(6), IterationType.ITERATIVE)).toEqual([6, 5, 7]); - expect(bst.dfs(node => node?.key ?? undefined, 'pre', bst.getNode(6), IterationType.RECURSIVE)).toEqual([6, 5, 7]); + expect(bst.dfs(node => node.key, 'pre', bst.getNode(6), 'ITERATIVE')).toEqual([6, 5, 7]); + expect(bst.dfs(node => node.key, 'pre', bst.getNode(6), 'RECURSIVE')).toEqual([6, 5, 7]); + expect(bst.dfs(node => node?.key ?? undefined, 'pre', bst.getNode(6), 'ITERATIVE')).toEqual([6, 5, 7]); + expect(bst.dfs(node => node?.key ?? undefined, 'pre', bst.getNode(6), 'RECURSIVE')).toEqual([6, 5, 7]); }); }); diff --git a/test/unit/data-structures/binary-tree/overall.test.ts b/test/unit/data-structures/binary-tree/overall.test.ts index 98f7f55..68ad2c6 100644 --- a/test/unit/data-structures/binary-tree/overall.test.ts +++ b/test/unit/data-structures/binary-tree/overall.test.ts @@ -1,4 +1,4 @@ -import { AVLTree, BST, BSTVariant, IterationType, RedBlackTree, TreeMultiMap } from '../../../../src'; +import { AVLTree, BST, RedBlackTree, TreeMultiMap } from '../../../../src'; describe('Overall BinaryTree Test', () => { it('should perform various operations on BinaryTree', () => { @@ -63,8 +63,8 @@ describe('Overall BinaryTree Test', () => { it('Should clone a BST works fine', () => { const bst = new BST([3, 6, 7, 1, 9], { - iterationType: IterationType.RECURSIVE, - variant: BSTVariant.INVERSE, + iterationType: 'RECURSIVE', + variant: 'INVERSE', extractor: key => key }); expect(bst.size).toBe(5); @@ -104,8 +104,8 @@ describe('Overall BinaryTree Test', () => { it('Should clone a AVLTree works fine', () => { const avl = new AVLTree([3, 6, 7, 1, 9], { - iterationType: IterationType.RECURSIVE, - variant: BSTVariant.INVERSE, + iterationType: 'RECURSIVE', + variant: 'INVERSE', extractor: key => key }); expect(avl.size).toBe(5); @@ -148,7 +148,7 @@ describe('Overall BinaryTree Test', () => { it('Should clone a TreeMultiMap works fine', () => { const tmm = new TreeMultiMap([3, 6, 7, 1, 9], { - iterationType: IterationType.RECURSIVE, + iterationType: 'RECURSIVE', extractor: key => key }); expect(tmm.size).toBe(5); @@ -197,7 +197,7 @@ describe('Overall BinaryTree Test', () => { it('Should clone a RedBlackTree works fine', () => { const rbTree = new RedBlackTree([3, 6, 7, 1, 9], { - iterationType: IterationType.RECURSIVE, + iterationType: 'RECURSIVE', extractor: key => key }); expect(rbTree.size).toBe(5); diff --git a/test/unit/data-structures/binary-tree/rb-tree.test.ts b/test/unit/data-structures/binary-tree/rb-tree.test.ts index 759a298..d1456ed 100644 --- a/test/unit/data-structures/binary-tree/rb-tree.test.ts +++ b/test/unit/data-structures/binary-tree/rb-tree.test.ts @@ -1,4 +1,4 @@ -import { BinaryTreeNode, BSTNode, IterationType, RBTNColor, RedBlackTree, RedBlackTreeNode } from '../../../../src'; +import { BinaryTreeNode, BSTNode, RBTNColor, RedBlackTree, RedBlackTreeNode } from '../../../../src'; import { getRandomInt, getRandomIntArray, magnitude } from '../../../utils'; import { OrderedMap } from 'js-sdsl'; @@ -53,6 +53,11 @@ describe('RedBlackTree 1', () => { expect(rbTree.getNode(15)).toBe(undefined); }); + + it('should getNode performance O(log n)', () => { + for (let i = 0; i < 10; i++) rbTree.add(i); + rbTree.getNode(6); + }); }); describe('minimum', () => { @@ -477,13 +482,13 @@ describe('RedBlackTree 2', () => { expect(rbTree.size).toBe(51); expect(rbTree.isBST()).toBe(true); - expect(rbTree.isBST(rbTree.root, IterationType.RECURSIVE)).toBe(true); + expect(rbTree.isBST(rbTree.root, 'RECURSIVE')).toBe(true); - expect(rbTree.dfs(n => n.key, 'in', rbTree.root, IterationType.ITERATIVE)).toEqual([ + expect(rbTree.dfs(n => n.key, 'in', rbTree.root, 'ITERATIVE')).toEqual([ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 ]); - expect(rbTree.dfs(n => n.key, 'in', rbTree.root, IterationType.RECURSIVE)).toEqual([ + expect(rbTree.dfs(n => n.key, 'in', rbTree.root, 'RECURSIVE')).toEqual([ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 ]); @@ -499,7 +504,7 @@ describe('RedBlackTree 2', () => { expect(rbTree.size).toBe(0); expect(rbTree.isBST()).toBe(true); - expect(rbTree.dfs(n => n.key, 'in', rbTree.root, IterationType.ITERATIVE)).toEqual([]); + expect(rbTree.dfs(n => n.key, 'in', rbTree.root, 'ITERATIVE')).toEqual([]); rbTree.clear(); for (let i = 0; i < 1000; i++) { 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 b619340..c6fcba8 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 @@ -1,12 +1,4 @@ -import { - BinaryTreeNode, - BSTNode, - CP, - IterationType, - RedBlackTreeNode, - TreeMultiMap, - TreeMultiMapNode -} from '../../../../src'; +import { BinaryTreeNode, BSTNode, RedBlackTreeNode, TreeMultiMap, TreeMultiMapNode } from '../../../../src'; import { isDebugTest } from '../../../config'; import { getRandomInt } from '../../../utils'; @@ -40,7 +32,7 @@ describe('TreeMultiMap count', () => { [2, 2], [3, 3] ]); - tmm.lesserOrGreaterTraverse(node => (node.count += 2), CP.gt, 1); + tmm.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 1); expect(tmm.getMutableCount()).toBe(7); expect(tmm.count).toBe(3); }); @@ -159,7 +151,7 @@ describe('TreeMultiMap operations test1', () => { node15 && tmm.dfs(node => (subTreeSum += node.key), 'pre', 15); expect(subTreeSum).toBe(45); let lesserSum = 0; - tmm.lesserOrGreaterTraverse((node: TreeMultiMapNode) => (lesserSum += node.key), CP.lt, 10); + tmm.lesserOrGreaterTraverse((node: TreeMultiMapNode) => (lesserSum += node.key), 'LT', 10); expect(lesserSum).toBe(45); expect(node15 instanceof TreeMultiMapNode); @@ -170,7 +162,7 @@ describe('TreeMultiMap operations test1', () => { const node11 = tmm.getNode(11); expect(node11 instanceof TreeMultiMapNode); if (node11 instanceof TreeMultiMapNode) { - const allGreaterNodesAdded = tmm.lesserOrGreaterTraverse(node => (node.count += 2), CP.gt, 11); + const allGreaterNodesAdded = tmm.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 11); expect(allGreaterNodesAdded); } @@ -357,7 +349,7 @@ describe('TreeMultiMap operations test1', () => { describe('TreeMultiMap operations test recursively1', () => { it('should perform various operations on a Binary Search Tree with numeric values1', () => { - const tmm = new TreeMultiMap([], { iterationType: IterationType.RECURSIVE }); + const tmm = new TreeMultiMap([], { iterationType: 'RECURSIVE' }); expect(tmm instanceof TreeMultiMap); tmm.add([11, 11]); @@ -421,7 +413,7 @@ describe('TreeMultiMap operations test recursively1', () => { lesserSum += node.key; return node.key; }, - CP.lt, + 'LT', 10 ); expect(lesserSum).toBe(45); @@ -434,7 +426,7 @@ describe('TreeMultiMap operations test recursively1', () => { const node11 = tmm.getNode(11); expect(node11 instanceof TreeMultiMapNode); if (node11 instanceof TreeMultiMapNode) { - const allGreaterNodesAdded = tmm.lesserOrGreaterTraverse(node => (node.count += 2), CP.gt, 11); + const allGreaterNodesAdded = tmm.lesserOrGreaterTraverse(node => (node.count += 2), 'GT', 11); expect(allGreaterNodesAdded); }