From 2d1010b3523fbfdfbb956cbb9508f4066b10efe2 Mon Sep 17 00:00:00 2001 From: Revone Date: Thu, 31 Aug 2023 20:02:31 +0800 Subject: [PATCH] Rework the add, addMany, and fill methods of AbstractBinaryTree. Refactor the AddMany method of TreeMultiset. Fix the bug in TreeMultiset where all Node counts become 1 after calling the perfectBalance method. Remove the unnecessary configuration of autoIncrementId. --- package-lock.json | 228 +++++++++++++++-- package.json | 25 +- .../binary-tree/abstract-binary-tree.ts | 134 ++++------ src/data-structures/binary-tree/avl-tree.ts | 3 + .../binary-tree/binary-tree.ts | 6 +- src/data-structures/binary-tree/bst.ts | 4 +- src/data-structures/binary-tree/rb-tree.ts | 6 +- .../binary-tree/tree-multiset.ts | 235 ++++++++++-------- src/data-structures/graph/abstract-graph.ts | 1 + src/data-structures/heap/heap.ts | 50 +--- .../interfaces/abstract-binary-tree.ts | 8 +- .../types/abstract-binary-tree.ts | 1 - tests/integration/heap.test.js | 18 +- .../data-structures/binary-tree/bst.test.ts | 9 +- .../binary-tree/tree-multiset.test.ts | 11 +- 15 files changed, 456 insertions(+), 283 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7e7f4db..ca90252 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,27 +1,43 @@ { "name": "data-structure-typed", - "version": "1.19.5", + "version": "1.19.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-structure-typed", - "version": "1.19.5", + "version": "1.19.7", "license": "MIT", "dependencies": { - "avl-tree-typed": "^1.19.5", - "bst-typed": "^1.19.5", - "heap-typed": "^1.19.5", "zod": "^3.22.2" }, "devDependencies": { "@types/jest": "^29.5.3", "@types/node": "^20.4.9", + "avl-tree-typed": "^1.19.7", + "binary-tree-typed": "^1.19.7", + "bst-typed": "^1.19.7", "dependency-cruiser": "^13.1.2", + "deque-typed": "^1.19.7", + "directed-graph-typed": "^1.19.7", + "doubly-linked-list-typed": "^1.19.7", + "graph-typed": "^1.19.7", + "heap-typed": "^1.19.7", "jest": "^29.6.2", + "linked-list-typed": "^1.19.7", + "max-heap-typed": "^1.19.7", + "max-priority-queue-typed": "^1.19.7", + "min-heap-typed": "^1.19.7", + "min-priority-queue-typed": "^1.19.7", + "priority-queue-typed": "^1.19.7", + "singly-linked-list-typed": "^1.19.7", + "stack-typed": "^1.19.7", + "tree-multiset-typed": "^1.19.7", + "trie-typed": "^1.19.7", "ts-jest": "^29.1.1", "typedoc": "^0.24.8", - "typescript": "^4.9.5" + "typescript": "^4.9.5", + "undirected-graph-typed": "^1.19.7" } }, "node_modules/@ampproject/remapping": { @@ -1627,11 +1643,12 @@ } }, "node_modules/avl-tree-typed": { - "version": "1.19.45", - "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.19.45.tgz", - "integrity": "sha512-/uluq7j+c5iTmcVzHHvuMKWdoIJ9ZqSfDgRXkPIqBHXxOEr05jxfwt1IRgdxJhsv3gOv4/mRzKJKfwNqjKv1Qg==", + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.19.7.tgz", + "integrity": "sha512-aoOVWmf8egxEc8qclllznUAWJrqzHtFPiSX4flM6G4NnxOOxsDAXGTU8gpo0tzfn3dM8/J6oBkm2OsV7HeXsoQ==", + "dev": true, "dependencies": { - "data-structure-typed": "^1.19.4", + "data-structure-typed": "^1.19.7", "zod": "^3.22.2" } }, @@ -1806,6 +1823,16 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/binary-tree-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.19.7.tgz", + "integrity": "sha512-oW7fa2zWAxBcsAD8Wdl4+//L02W+pocggPNEg5nhL/tOl1EUcY6aoVJ2hmrJg9C1VclRvGpVV57VFyEMfCxpXQ==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -1881,11 +1908,12 @@ } }, "node_modules/bst-typed": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.19.5.tgz", - "integrity": "sha512-xvW7t2v6G6YA3pyLTAnxTrIeOy+Lpuwi9Sr/lVnif7sJhAh4qutUu9PQZgttTfqdySGfBHux4N7bOCj5/l17KQ==", + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.19.7.tgz", + "integrity": "sha512-ngXIfUtNJ22BNWnxo27x3sAgOCPXTcHk4jFdYaaoAqyxJKbUcmquNV0XRym0JfEAuscwSXr6+JtQMS5OFpNxDw==", + "dev": true, "dependencies": { - "data-structure-typed": "^1.19.5", + "data-structure-typed": "^1.19.7", "zod": "^3.22.2" } }, @@ -2147,12 +2175,14 @@ } }, "node_modules/data-structure-typed": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.19.5.tgz", - "integrity": "sha512-Q6rn8ww6AN8es5FD49p1pRuka5TIH3bp/nb3LmsAuL0ChecskVf2V94iNk33aRQXnvQwN8R+4YBsEn2j1/xqQA==", + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.19.7.tgz", + "integrity": "sha512-01z8P6DDXy044GitWYxds7sQzAYS1USxVAQEl7v8gSSa4YG7nzg0ZhL/xyU3QjzFjn+XsJWCOaiNG8eMFr54HQ==", + "dev": true, "dependencies": { - "avl-tree-typed": "^1.19.44", - "bst-typed": "^1.19.45", + "avl-tree-typed": "^1.19.6", + "bst-typed": "^1.19.6", + "heap-typed": "^1.19.6", "zod": "^3.22.2" } }, @@ -2160,6 +2190,7 @@ "version": "1.19.45", "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.19.45.tgz", "integrity": "sha512-x/vLIaFDdgv4zcTVgpJmTwW6BanpPPM9eE/P8v72VE9eFgBEspDGOSJsd4Fel7fO8DF+MUqwksMreCln0ECy3g==", + "dev": true, "dependencies": { "data-structure-typed": "^1.19.4", "zod": "^3.22.2" @@ -2250,6 +2281,16 @@ "node": "^16.14||>=18" } }, + "node_modules/deque-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/deque-typed/-/deque-typed-1.19.7.tgz", + "integrity": "sha512-boNOe04x7q1AC1OIZumU81rwCd6t0wh4CUHH6eWFpibgJmjLQRCgWgqHoXpRX2z6k1nS16MsliCbexk/2YAkiQ==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2268,6 +2309,26 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/directed-graph-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/directed-graph-typed/-/directed-graph-typed-1.19.7.tgz", + "integrity": "sha512-mHoiatm3UpCZjBd/L33bnPHsKGR5WRslR5fiS9+dmmmcT8PDpBiHVtVrNLkEKNVFXrl9nTkwC0e08/elNhhaMg==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, + "node_modules/doubly-linked-list-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/doubly-linked-list-typed/-/doubly-linked-list-typed-1.19.7.tgz", + "integrity": "sha512-N6/D0ET5siuQbsPVf6VuiYDnGXH6FUF/bJv6bwtX0Pse0+N8AVayd1mUUcuZT00tyMm3Tb4CxqKrqIuW195riQ==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2603,6 +2664,16 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/graph-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/graph-typed/-/graph-typed-1.19.7.tgz", + "integrity": "sha512-9vo//L6UAMR9NfvHNYgFzAMF4Jx6aBpA1fx+n1WVOdP4kpni1kNRVCJQ98c51zFtkEuZvRie9g4hkYqv598aSQ==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -2625,11 +2696,12 @@ } }, "node_modules/heap-typed": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.19.5.tgz", - "integrity": "sha512-E7H53VmkgDIa1+sVqao2i/QcUE2k85ZYLAmknM9+2QMb9wjJOCaFNiPjuZJLb0J7q+4nrgGedF7kxGFZFa+gwQ==", + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.19.7.tgz", + "integrity": "sha512-837IoAkdgeoRWXam/RG/bYPnMyDORBiEPPV/Bs0NOj6sCVe9p81VjtkGYnz2DPgdFk5C/DEfriExuZiTqPsjhQ==", + "dev": true, "dependencies": { - "data-structure-typed": "^1.19.5", + "data-structure-typed": "^1.19.7", "zod": "^3.22.2" } }, @@ -4326,6 +4398,16 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/linked-list-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/linked-list-typed/-/linked-list-typed-1.19.7.tgz", + "integrity": "sha512-P68uY6aRX47Ett8zgHKK7tp6nBlAB86cXwqpREEgEv5ruk70HPH4M/7RO7LD0J6x8VJiTF0Ws3/ikBTHjPZjeg==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -4407,6 +4489,26 @@ "node": ">= 12" } }, + "node_modules/max-heap-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/max-heap-typed/-/max-heap-typed-1.19.7.tgz", + "integrity": "sha512-iix1moDPx5bL784FfSv+6ocbme0etHMm3ezK8NKkixDp0gmTbHmzOA7lQ9EimFhVTUYs6W/PipO8BPdE0UxFnw==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, + "node_modules/max-priority-queue-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/max-priority-queue-typed/-/max-priority-queue-typed-1.19.7.tgz", + "integrity": "sha512-qjGVxjoQYrk8O52WSkq0LwQ0EWAfOEzVQZ/LCX2tIRbePuw0HaDh7LQ4+Z3Pi5BXG6E/6JwJPljNNGoBvinFxQ==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -4435,6 +4537,26 @@ "node": ">=6" } }, + "node_modules/min-heap-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/min-heap-typed/-/min-heap-typed-1.19.7.tgz", + "integrity": "sha512-CEbz/U1qRo14udGnc2AW6Zo83EZmQBP43KhG/dE7BM8Bbbq+QCD6M1JVpc349AbUgGpV8e75S4jPaS2nO/QbaQ==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, + "node_modules/min-priority-queue-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/min-priority-queue-typed/-/min-priority-queue-typed-1.19.7.tgz", + "integrity": "sha512-he+5IOCkBAeES9v/v9zBLUQVL7BNopt2uegyYUZESRb9I12ii3jQNfzhK1tTejMtXzmkPbgrSLe7RbMXAeq8fw==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", @@ -4717,6 +4839,16 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/priority-queue-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/priority-queue-typed/-/priority-queue-typed-1.19.7.tgz", + "integrity": "sha512-+ffaKPE8I09fKErdAZXevSO8fAvv9A5ADomAPBRa+LDyfsm3TrTRCXBWpt1KLlBI3DB2ZJczUsbrCfnDKDcqwg==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -4946,6 +5078,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/singly-linked-list-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/singly-linked-list-typed/-/singly-linked-list-typed-1.19.7.tgz", + "integrity": "sha512-iYik+sWJwInLIXVWlrKT52jfLP5iv7xZRA4eeaMhEwDJCa4Nb/BcTFAaWZeo8cELxCcDxP8w/vvDSsmePbftDQ==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -4986,6 +5128,16 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/stack-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/stack-typed/-/stack-typed-1.19.7.tgz", + "integrity": "sha512-QlGwJ1GhgXynVDgRWQYmcTdVtt3457dd4ZywPp05aQOMw//H9au4FVm+VmZ0cW4nm7MNhTkjuf4oFjMz8hZSZQ==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -5289,6 +5441,26 @@ "node": ">=8.0" } }, + "node_modules/tree-multiset-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/tree-multiset-typed/-/tree-multiset-typed-1.19.7.tgz", + "integrity": "sha512-TqX9ALuiSNbTj22NxCjrHLfCbwzl4talhixXjw7+8FbgCGJEatJgqqs4/5/kMxo6dK5KH+Wwu9aA0yxYadX67w==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, + "node_modules/trie-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/trie-typed/-/trie-typed-1.19.7.tgz", + "integrity": "sha512-/IIosdfQKEaLyK4VQ/pCEX4Ya02d+wylrhLJNxW/wA2JbMhSRCmQoVkvZhyFX328CnQE1q9SIovD7g3BHbzbTA==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/ts-jest": { "version": "29.1.1", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", @@ -5473,6 +5645,16 @@ "node": ">=4.2.0" } }, + "node_modules/undirected-graph-typed": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/undirected-graph-typed/-/undirected-graph-typed-1.19.7.tgz", + "integrity": "sha512-9+lFDIy/aUO8rpudzRYQI51n+X9xGdMevId2Cs70oDQoxX2dDGgm1iN1SG5hHl3Bb3YpjLh9aJ40WVke+HGt5Q==", + "dev": true, + "dependencies": { + "data-structure-typed": "^1.19.7", + "zod": "^3.22.2" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", diff --git a/package.json b/package.json index 6c4919f..5e4897e 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "build": "rm -rf dist && npx tsc", "test": "jest", + "update:test-deps": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed --save-dev", "build:docs": "typedoc --out docs ./src", "deps:check": "dependency-cruiser src", "build:publish": "npm run test && npm run build && npm run build:docs && npm publish" @@ -58,16 +59,32 @@ "devDependencies": { "@types/jest": "^29.5.3", "@types/node": "^20.4.9", + "avl-tree-typed": "^1.19.7", + "binary-tree-typed": "^1.19.7", + "bst-typed": "^1.19.7", "dependency-cruiser": "^13.1.2", + "deque-typed": "^1.19.7", + "directed-graph-typed": "^1.19.7", + "doubly-linked-list-typed": "^1.19.7", + "graph-typed": "^1.19.7", + "heap-typed": "^1.19.7", "jest": "^29.6.2", + "linked-list-typed": "^1.19.7", + "max-heap-typed": "^1.19.7", + "max-priority-queue-typed": "^1.19.7", + "min-heap-typed": "^1.19.7", + "min-priority-queue-typed": "^1.19.7", + "priority-queue-typed": "^1.19.7", + "singly-linked-list-typed": "^1.19.7", + "stack-typed": "^1.19.7", + "tree-multiset-typed": "^1.19.7", + "trie-typed": "^1.19.7", "ts-jest": "^29.1.1", "typedoc": "^0.24.8", - "typescript": "^4.9.5" + "typescript": "^4.9.5", + "undirected-graph-typed": "^1.19.7" }, "dependencies": { - "avl-tree-typed": "^1.19.6", - "bst-typed": "^1.19.6", - "heap-typed": "^1.19.6", "zod": "^3.22.2" } } diff --git a/src/data-structures/binary-tree/abstract-binary-tree.ts b/src/data-structures/binary-tree/abstract-binary-tree.ts index 03dc5a8..e3ec846 100644 --- a/src/data-structures/binary-tree/abstract-binary-tree.ts +++ b/src/data-structures/binary-tree/abstract-binary-tree.ts @@ -6,7 +6,7 @@ * @license MIT License */ -import {ObjectWithNumberId, trampoline} from '../../utils'; +import {trampoline} from '../../utils'; import type { AbstractBinaryTreeNodeNested, AbstractBinaryTreeNodeProperties, @@ -22,7 +22,6 @@ import {IAbstractBinaryTree, IAbstractBinaryTreeNode} from '../interfaces'; export abstract class AbstractBinaryTreeNode = AbstractBinaryTreeNodeNested> implements IAbstractBinaryTreeNode { - /** * The constructor function initializes a BinaryTreeNode object with an id and an optional value. * @param {BinaryTreeNodeId} id - The `id` parameter is of type `BinaryTreeNodeId` and represents the unique identifier @@ -30,7 +29,7 @@ export abstract class AbstractBinaryTreeNode { const queue: Array = [root]; while (queue.length > 0) { @@ -292,21 +280,30 @@ export abstract class AbstractBinaryTree} data - The `data` parameter can be either an array of `N` objects or an array of - * `N['val']` values. - * @returns The function `addMany` returns an array of values of type `N | null | undefined`. + * @param {(BinaryTreeNodeId|N)[]} idsOrNodes - An array of BinaryTreeNodeId or N objects. These can be either the ID + * of a binary tree node or the actual node object itself. + * @param {N['val'][]} [data] - Optional array of values to be added to the nodes. If provided, the length of this + * array should be the same as the length of the `idsOrNodes` array. + * @returns The function `addMany` returns an array of values `(N | null | undefined)[]`. */ - addMany(data: N[] | Array): (N | null | undefined)[] { + addMany(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N['val'][]): (N | null | undefined)[] { // TODO not sure addMany not be run multi times const inserted: (N | null | undefined)[] = []; - const map: Map = new Map(); + const map: Map = new Map(); if (this.isMergeDuplicatedVal) { - for (const nodeOrId of data) map.set(nodeOrId, (map.get(nodeOrId) ?? 0) + 1); + for (const idOrNode of idsOrNodes) map.set(idOrNode, (map.get(idOrNode) ?? 0) + 1); } - for (const nodeOrId of data) { - - if (nodeOrId instanceof AbstractBinaryTreeNode) { - inserted.push(this.add(nodeOrId.id, nodeOrId.val)); + for (let i = 0; i < idsOrNodes.length; i++) { + const idOrNode = idsOrNodes[i]; + if (idOrNode instanceof AbstractBinaryTreeNode) { + inserted.push(this.add(idOrNode.id, idOrNode.val)); continue; } - if (nodeOrId === null) { - inserted.push(this.add(NaN, null, 0)); - continue; - } - - // TODO will this cause an issue? - const count = this.isMergeDuplicatedVal ? map.get(nodeOrId) : 1; - let newId: BinaryTreeNodeId; - if (typeof nodeOrId === 'number') { - newId = this.autoIncrementId ? this.maxId + 1 : nodeOrId; - } else if (nodeOrId instanceof Object) { - if (this.autoIncrementId) { - newId = this.maxId + 1; - } else { - if (Object.keys(nodeOrId).includes('id')) { - newId = (nodeOrId as ObjectWithNumberId).id; - } else { - console.warn(nodeOrId, 'Object value must has an id property when the autoIncrementId is false'); - continue; - } - } - } else { - console.warn(nodeOrId, ` is not added`); + if (idOrNode === null) { + inserted.push(this.add(null)); continue; } + const val = data?.[i]; if (this.isMergeDuplicatedVal) { - if (map.has(nodeOrId)) { - inserted.push(this.add(newId, nodeOrId, count)); - map.delete(nodeOrId); + if (map.has(idOrNode)) { + inserted.push(this.add(idOrNode, val)); + map.delete(idOrNode); } } else { - inserted.push(this.add(newId, nodeOrId, 1)); + inserted.push(this.add(idOrNode, val)); } - - this._setMaxId(newId); } return inserted; } /** - * The `fill` function clears the current data and adds new data, returning a boolean indicating if the operation was - * successful. - * @param {N[] | Array} data - The `data` parameter can be either an array of objects or an array of arrays. - * Each object or array should have a property called `val`. - * @returns a boolean value. + * The `fill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data. + * @param {(BinaryTreeNodeId | N)[]} idsOrNodes - The `idsOrNodes` parameter is an array that can contain either + * `BinaryTreeNodeId` or `N` values. + * @param {N[] | Array} [data] - The `data` parameter is an optional array of values that will be assigned to + * the nodes being added. If provided, the length of the `data` array should be equal to the length of the `idsOrNodes` + * array. Each value in the `data` array will be assigned to the + * @returns The method is returning a boolean value. */ - fill(data: N[] | Array): boolean { + fill(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N[] | Array): boolean { this.clear(); - return data.length === this.addMany(data).length; + return idsOrNodes.length === this.addMany(idsOrNodes, data).length; } /** @@ -1375,15 +1354,6 @@ export abstract class AbstractBinaryTree = AVLTreeNodeNested> extends BSTNode implements IAVLTreeNode { + constructor(id: BinaryTreeNodeId, val?: T) { + super(id, val); + } } export class AVLTree = AVLTreeNode> extends BST implements IAVLTree { diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index 604b564..f7ffa17 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -8,10 +8,12 @@ import type {BinaryTreeNodeId, BinaryTreeNodeNested, BinaryTreeOptions} from '../types'; import {AbstractBinaryTree, AbstractBinaryTreeNode} from './abstract-binary-tree'; -import {IBinaryTree, IBinaryTreeNode} from '../interfaces/binary-tree'; +import {IBinaryTree, IBinaryTreeNode} from '../interfaces'; export class BinaryTreeNode = BinaryTreeNodeNested> extends AbstractBinaryTreeNode implements IBinaryTreeNode { - + constructor(id: BinaryTreeNodeId, val?: T) { + super(id, val); + } } export class BinaryTree = BinaryTreeNode> extends AbstractBinaryTree implements IBinaryTree { diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index ec9ebd7..224047f 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -11,7 +11,9 @@ import {BinaryTree, BinaryTreeNode} from './binary-tree'; import {IBST, IBSTNode} from '../interfaces'; export class BSTNode = BSTNodeNested> extends BinaryTreeNode implements IBSTNode { - + constructor(id: BinaryTreeNodeId, val?: T) { + super(id, val); + } } export class BST = BSTNode> extends BinaryTree implements IBST { diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts index fcfb570..d404ac7 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -4,12 +4,12 @@ import {BST, BSTNode} from './bst'; export class RBTreeNode = RBTreeNodeNested> extends BSTNode implements IRBTreeNode { - constructor(id: BinaryTreeNodeId, color: RBColor, val?: T) { + constructor(id: BinaryTreeNodeId, val?: T, color: RBColor = RBColor.RED) { super(id, val); this._color = color; } - private _color: RBColor = RBColor.RED; + private _color: RBColor; get color(): RBColor { return this._color; @@ -60,7 +60,7 @@ export class RBTree = RBTreeNode> extends BST< } override createNode(id: BinaryTreeNodeId, val?: N['val']): N { - return new RBTreeNode(id, RBColor.RED, val) as N; + return new RBTreeNode(id, val, RBColor.RED) as N; } // private override _root: BinaryTreeNode | null = null; diff --git a/src/data-structures/binary-tree/tree-multiset.ts b/src/data-structures/binary-tree/tree-multiset.ts index e9e9c35..dce06b2 100644 --- a/src/data-structures/binary-tree/tree-multiset.ts +++ b/src/data-structures/binary-tree/tree-multiset.ts @@ -9,7 +9,6 @@ import type {BinaryTreeNodeId, TreeMultisetNodeNested, TreeMultisetOptions} from import {BinaryTreeDeletedResult, CP, DFSOrderPattern, FamilyPosition, LoopType, NodeOrPropertyName} from '../types'; import {ITreeMultiset, ITreeMultisetNode} from '../interfaces'; import {AVLTree, AVLTreeNode} from './avl-tree'; -import {ObjectWithNumberId} from '../../utils'; export class TreeMultisetNode = TreeMultisetNodeNested> extends AVLTreeNode implements ITreeMultisetNode { @@ -28,7 +27,7 @@ export class TreeMultisetNode = TreeMultiset return destNode; } + /** - * The `add` function adds a new node to a binary tree, updating the size and count properties accordingly, and - * balancing the tree if necessary. - * @param {BinaryTreeNodeId} id - The id parameter represents the identifier of the binary tree node that we want to - * add. It is of type BinaryTreeNodeId. - * @param [val] - The `val` parameter is an optional value that can be assigned to the node being added. If no value is - * provided, it will default to `undefined`. - * @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the node - * with the given `id` should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1. - * @returns The `add` method returns the inserted node (`N`), `null`, or `undefined`. + * The `add` function adds a new node to a binary search tree, maintaining the tree's properties and balancing if + * necessary. + * @param {BinaryTreeNodeId | N} idOrNode - The `idOrNode` parameter can be either a `BinaryTreeNodeId` or a `N` (which + * represents a `BinaryTreeNode`). + * @param [val] - The `val` parameter represents the value to be added to the binary tree node. + * @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the + * value should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1. + * @returns The method `add` returns either the inserted node (`N`), `null`, or `undefined`. */ - override add(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null | undefined { + override add(idOrNode: BinaryTreeNodeId | N | null, val?: N['val'], count?: number): N | null | undefined { count = count ?? 1; - let inserted: N | null = null; - const newNode = this.createNode(id, val, count); - if (this.root === null) { + let inserted: N | null | undefined = undefined; + let newNode; + let id; + if (idOrNode instanceof TreeMultisetNode) { + newNode = this.createNode(idOrNode.id, idOrNode.val, idOrNode.count); + } else if (idOrNode === null) { + newNode = null; + } else { + newNode = this.createNode(idOrNode, val, count); + } + if (!this.root) { this._setRoot(newNode); this._setSize(this.size + 1); - this._setCount(this.count + count); - inserted = (this.root); + newNode && this._setCount(this.count + newNode.count); + inserted = this.root; } else { let cur = this.root; let traversing = true; while (traversing) { - if (cur !== null && newNode !== null) { - if (this._compare(cur.id, id) === CP.eq) { - if (newNode) { + if (cur) { + if (newNode) { + if (this._compare(cur.id, newNode.id) === CP.eq) { cur.val = newNode.val; - cur.count += count; + cur.count += newNode.count; this._setCount(this.count + newNode.count); - } - //Duplicates are not accepted. - traversing = false; - inserted = cur; - } else if (this._compare(cur.id, id) === CP.gt) { - // Traverse left of the node - if (cur.left === undefined) { - if (newNode) { - newNode.parent = cur; - } - //Add to the left of the current node - cur.left = newNode; - this._setSize(this.size + 1); - this._setCount(this.count + newNode.count); - traversing = false; - inserted = cur.left; - } else { - //Traverse the left of the current node - if (cur.left) cur = cur.left; - } - } else if (this._compare(cur.id, id) === CP.lt) { - // Traverse right of the node - if (cur.right === undefined) { - if (newNode) { - newNode.parent = cur; - } - //Add to the right of the current node - cur.right = newNode; - this._setSize(this.size + 1); - this._setCount(this.count + newNode.count); + inserted = cur; + } else if (this._compare(cur.id, newNode.id) === CP.gt) { + // Traverse left of the node + if (cur.left === undefined) { + //Add to the left of the current node + cur.left = newNode; + this._setSize(this.size + 1); + this._setCount(this.count + newNode.count); - traversing = false; - inserted = (cur.right); - } else { - //Traverse the left of the current node - if (cur.right) cur = cur.right; + traversing = false; + inserted = cur.left; + } else { + //Traverse the left of the current node + if (cur.left) cur = cur.left; + } + } else if (this._compare(cur.id, newNode.id) === CP.lt) { + // Traverse right of the node + if (cur.right === undefined) { + //Add to the right of the current node + cur.right = newNode; + this._setSize(this.size + 1); + this._setCount(this.count + newNode.count); + + traversing = false; + inserted = (cur.right); + } else { + //Traverse the left of the current node + if (cur.right) cur = cur.right; + } } + } else { + // TODO may need to support null inserted } } else { traversing = false; @@ -192,24 +194,20 @@ export class TreeMultiset = TreeMultiset override addTo(newNode: N | null, parent: N): N | null | undefined { if (parent) { if (parent.left === undefined) { - if (newNode) { - newNode.parent = parent; - } + parent.left = newNode; if (newNode !== null) { this._setSize(this.size + 1); - this._setCount(this.count + newNode.count ?? 0) + this._setCount(this.count + newNode.count) } return parent.left; } else if (parent.right === undefined) { - if (newNode) { - newNode.parent = parent; - } + parent.right = newNode; if (newNode !== null) { this._setSize(this.size + 1); - this._setCount(this.count + newNode.count ?? 0); + this._setCount(this.count + newNode.count); } return parent.right; } else { @@ -221,68 +219,89 @@ export class TreeMultiset = TreeMultiset } /** - * The `addMany` function inserts multiple items into a binary tree and returns an array of the inserted nodes or - * null/undefined values. - * @param {N[] | N[]} data - The `data` parameter can be either an array of elements of type `N` or an - * array of `N` objects. + * The `addMany` function adds multiple nodes to a binary tree and returns an array of the inserted nodes. + * @param {BinaryTreeNodeId[] | N[]} idsOrNodes - An array of BinaryTreeNodeId objects or N objects. These objects + * represent the IDs or nodes of the binary tree where the values will be added. + * @param {N['val'][]} [data] - Optional array of values to be associated with each node being added. If provided, the + * length of the `data` array should be equal to the length of the `idsOrNodes` array. * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values. */ - override addMany(data: N[] | Array): (N | null | undefined)[] { + override addMany(idsOrNodes: (BinaryTreeNodeId | N)[], data?: N['val'][]): (N | null | undefined)[] { // TODO not sure addMany not be run multi times const inserted: (N | null | undefined)[] = []; - const map: Map = new Map(); + const map: Map = new Map(); if (this.isMergeDuplicatedVal) { - for (const nodeOrId of data) map.set(nodeOrId, (map.get(nodeOrId) ?? 0) + 1); + for (const idOrNode of idsOrNodes) map.set(idOrNode, (map.get(idOrNode) ?? 0) + 1); } - for (const nodeOrId of data) { - - if (nodeOrId instanceof TreeMultisetNode) { - inserted.push(this.add(nodeOrId.id, nodeOrId.val, nodeOrId.count)); + for (let i = 0; i < idsOrNodes.length; i++) { + const idOrNode = idsOrNodes[i]; + if (idOrNode instanceof TreeMultisetNode) { + inserted.push(this.add(idOrNode.id, idOrNode.val, idOrNode.count)); continue; } - if (nodeOrId === null) { + if (idOrNode === null) { inserted.push(this.add(NaN, null, 0)); continue; } - // TODO will this cause an issue? - const count = this.isMergeDuplicatedVal ? map.get(nodeOrId) : 1; - let newId: BinaryTreeNodeId; - if (typeof nodeOrId === 'number') { - newId = this.autoIncrementId ? this.maxId + 1 : nodeOrId; - } else if (nodeOrId instanceof Object) { - if (this.autoIncrementId) { - newId = this.maxId + 1; - } else { - if (Object.keys(nodeOrId).includes('id')) { - newId = (nodeOrId as ObjectWithNumberId).id; - } else { - console.warn(nodeOrId, 'Object value must has an id property when the autoIncrementId is false'); - continue; - } - } - } else { - console.warn(nodeOrId, ` is not added`); - continue; - } - + const count = this.isMergeDuplicatedVal ? map.get(idOrNode) : 1; + const val = data?.[i]; if (this.isMergeDuplicatedVal) { - if (map.has(nodeOrId)) { - inserted.push(this.add(newId, nodeOrId, count)); - map.delete(nodeOrId); + if (map.has(idOrNode)) { + inserted.push(this.add(idOrNode, val, count)); + map.delete(idOrNode); } } else { - inserted.push(this.add(newId, nodeOrId, 1)); + inserted.push(this.add(idOrNode, val, 1)); } - - this._setMaxId(newId); } return inserted; } + /** + * The `perfectlyBalance` function takes a binary tree, performs a depth-first search to sort the nodes, and then + * constructs a balanced binary search tree using either a recursive or iterative approach. + * @returns The function `perfectlyBalance()` returns a boolean value. + */ + override perfectlyBalance(): boolean { + const sorted = this.DFS('in', 'node'), n = sorted.length; + this.clear(); + + if (sorted.length < 1) return false; + if (this.loopType === LoopType.RECURSIVE) { + const buildBalanceBST = (l: number, r: number) => { + if (l > r) return; + const m = l + Math.floor((r - l) / 2); + const midNode = sorted[m]; + this.add(midNode.id, midNode.val, midNode.count); + buildBalanceBST(l, m - 1); + buildBalanceBST(m + 1, r); + }; + + buildBalanceBST(0, n - 1); + return true; + } else { + const stack: [[number, number]] = [[0, n - 1]]; + while (stack.length > 0) { + const popped = stack.pop(); + if (popped) { + const [l, r] = popped; + if (l <= r) { + const m = l + Math.floor((r - l) / 2); + const midNode = sorted[m]; + this.add(midNode.id, midNode.val, midNode.count); + stack.push([m + 1, r]); + stack.push([l, m - 1]); + } + } + } + return true; + } + } + /** * The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent * node that needs to be balanced. @@ -296,7 +315,7 @@ export class TreeMultiset = TreeMultiset const bstDeletedResult: BinaryTreeDeletedResult[] = []; if (!this.root) return bstDeletedResult; - const curr: N | null = (typeof nodeOrId === 'number') ? this.get(nodeOrId) : nodeOrId; + const curr: N | null = this.get(nodeOrId); if (!curr) return bstDeletedResult; const parent: N | null = curr?.parent ? curr.parent : null; @@ -324,13 +343,17 @@ export class TreeMultiset = TreeMultiset const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent; orgCurrent = this.swapLocation(curr, leftSubTreeRightMost); if (parentOfLeftSubTreeMax) { - if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left; - else parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left; + if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) { + parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left; + } else { + parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left; + } needBalanced = parentOfLeftSubTreeMax; } } } this._setSize(this.size - 1); + // TODO How to handle when the count of target node is lesser than current node's count this._setCount(this.count - orgCurrent.count); } diff --git a/src/data-structures/graph/abstract-graph.ts b/src/data-structures/graph/abstract-graph.ts index 99e105d..a2d8962 100644 --- a/src/data-structures/graph/abstract-graph.ts +++ b/src/data-structures/graph/abstract-graph.ts @@ -170,6 +170,7 @@ export abstract class AbstractGraph, E extends Abs addVertex(idOrVertex: VertexId | V, val?: V['val']): boolean { if (idOrVertex instanceof AbstractVertex) { return this._addVertexOnly(idOrVertex); + } else { const newVertex = this.createVertex(idOrVertex, val); return this._addVertexOnly(newVertex); diff --git a/src/data-structures/heap/heap.ts b/src/data-structures/heap/heap.ts index d311198..4e47546 100644 --- a/src/data-structures/heap/heap.ts +++ b/src/data-structures/heap/heap.ts @@ -44,9 +44,9 @@ export class HeapItem { } export abstract class Heap { - /** - * The constructor function initializes a priority queue with an optional priority extractor function. + * The function is a constructor for a class that initializes a priority callback function based on the + * options provided. * @param [options] - An optional object that contains configuration options for the Heap. */ protected constructor(options?: HeapOptions) { @@ -91,16 +91,9 @@ export abstract class Heap { peek(isItem?: undefined): T | undefined; peek(isItem: false): T | undefined; peek(isItem: true): HeapItem | null; - /** - * The `peek` function returns the top item or value in a priority queue, depending on the value of the `isItem` - * parameter. - * @param {boolean} [isItem] - The `isItem` parameter is an optional boolean parameter that determines whether the - * method should return the entire `HeapItem` object or just the value of the item. If `isItem` is set to `true`, the - * method will return the `HeapItem` object. If `isItem` - * @returns The `peek` method returns either a `HeapItem` object, `null`, `T`, or `undefined`. The specific return - * type depends on the value of the `isItem` parameter. If `isItem` is `true`, then the method returns a `HeapItem` - * object or `null` if the heap is empty. If `isItem` is `false` + * The `peek` function returns the top item in the priority queue without removing it. + * @returns The `peek()` method is returning either a `HeapItem` object or `null`.Returns an val with the highest priority in the queue */ peek(isItem?: boolean): HeapItem | null | T | undefined { isItem = isItem ?? false; @@ -111,16 +104,9 @@ export abstract class Heap { peekLast(isItem?: undefined): T | undefined; peekLast(isItem: false): T | undefined; peekLast(isItem: true): HeapItem | null; - /** - * The `peekLast` function returns the last item in the heap, either as a `HeapItem` object or just the value depending - * on the `isItem` parameter. - * @param {boolean} [isItem] - A boolean parameter that indicates whether the method should return the HeapItem object - * or just the value of the last item in the heap. If isItem is true, the method will return the HeapItem object. If - * isItem is false or not provided, the method will return the value of the last item - * @returns The method `peekLast` returns either a `HeapItem` object, `null`, `T`, or `undefined`. The specific - * return type depends on the value of the `isItem` parameter. If `isItem` is `true`, then the method returns a - * `HeapItem` object or `null` if there are no items in the heap. If `isItem` + * The `peekLast` function returns the last item in the heap. + * @returns The method `peekLast()` returns either a `HeapItem` object or `null`.Returns an val with the lowest priority in the queue */ peekLast(isItem?: boolean): HeapItem | null | T | undefined { isItem = isItem ?? false; @@ -147,15 +133,9 @@ export abstract class Heap { poll(isItem?: undefined): T | undefined; poll(isItem: false): T | undefined; poll(isItem: true): HeapItem | null; - /** - * The `poll` function returns the top item from a priority queue, either as a HeapItem object or its value, depending - * on the value of the `isItem` parameter. - * @param {boolean} [isItem] - The `isItem` parameter is a boolean flag that indicates whether the returned value - * should be a `HeapItem` object or just the value `T` itself. If `isItem` is `true`, the method will return the - * `HeapItem` object, otherwise it will return just - * @returns The function `poll` returns either a `HeapItem` object, `null`, or `T` (the value of the `val` property - * of the `HeapItem` object). + * The `poll` function returns the top item from a priority queue or null if the queue is empty.Removes and returns an val with the highest priority in the queue + * @returns either a HeapItem object or null. */ poll(isItem?: boolean): HeapItem | null | T | undefined { isItem = isItem ?? false; @@ -167,8 +147,8 @@ export abstract class Heap { } /** - * The `has` function checks if a given node or value exists in the priority queue. - * @param {T | HeapItem} node - The `node` parameter can be of type `T` or `HeapItem`. + * The function checks if a given node or value exists in the priority queue. + * @param {T | HeapItem} node - The parameter `node` can be of type `T` or `HeapItem`. * @returns a boolean value. */ has(node: T | HeapItem): boolean { @@ -184,15 +164,9 @@ export abstract class Heap { toArray(isItem?: undefined): (T | undefined)[]; toArray(isItem: false): (T | undefined)[]; toArray(isItem: true): (HeapItem | null)[]; - /** - * The `toArray` function returns an array of either HeapItem objects or their values, depending on the value of the - * `isItem` parameter. - * @param {boolean} [isItem] - isItem is an optional boolean parameter that determines whether the returned array - * should contain the HeapItem objects or just the values of the HeapItem objects. If isItem is true, the array will - * contain the HeapItem objects. If isItem is false or not provided, the array will contain only the values - * @returns The method `toArray` returns an array of `HeapItem` objects, or an array of `T` values if the `isItem` - * parameter is set to `false`. + * The `toArray` function returns an array of `HeapItem` objects. + * @returns An array of HeapItem objects.Returns a sorted list of vals */ toArray(isItem?: boolean): (HeapItem | null | T | undefined)[] { isItem = isItem ?? false; diff --git a/src/data-structures/interfaces/abstract-binary-tree.ts b/src/data-structures/interfaces/abstract-binary-tree.ts index 04bc077..2a0eff3 100644 --- a/src/data-structures/interfaces/abstract-binary-tree.ts +++ b/src/data-structures/interfaces/abstract-binary-tree.ts @@ -55,8 +55,6 @@ export interface IAbstractBinaryTree): (N | null | undefined)[] + addMany(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N['val'][]): (N | null | undefined)[] - fill(data: N[] | Array): boolean + fill(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N[] | Array): boolean remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult[] diff --git a/src/data-structures/types/abstract-binary-tree.ts b/src/data-structures/types/abstract-binary-tree.ts index c5df456..9391112 100644 --- a/src/data-structures/types/abstract-binary-tree.ts +++ b/src/data-structures/types/abstract-binary-tree.ts @@ -37,6 +37,5 @@ export type AbstractBinaryTreeNodeNested = AbstractBinaryTreeNode { it('should numeric heap work well', function () { const minNumHeap = new MinHeap(); - // minNumHeap.add(1).add(6).add(2).add(0).add(5).add(9); - // expect(minNumHeap.poll()).toBe(0); - // expect(minNumHeap.poll()).toBe(1); - // expect(minNumHeap.peek()).toBe(2); - // expect(minNumHeap.toArray().length).toBe(4); - // expect(minNumHeap.toArray()[0]).toBe(2); - // expect(minNumHeap.toArray()[1]).toBe(5); - // expect(minNumHeap.toArray()[2]).toBe(9); - // expect(minNumHeap.toArray()[3]).toBe(6); + minNumHeap.add(1).add(6).add(2).add(0).add(5).add(9); + expect(minNumHeap.poll()).toBe(0); + expect(minNumHeap.poll()).toBe(1); + expect(minNumHeap.peek()).toBe(2); + expect(minNumHeap.toArray().length).toBe(4); + expect(minNumHeap.toArray()[0]).toBe(2); + expect(minNumHeap.toArray()[1]).toBe(5); + expect(minNumHeap.toArray()[2]).toBe(9); + expect(minNumHeap.toArray()[3]).toBe(6); }); diff --git a/tests/unit/data-structures/binary-tree/bst.test.ts b/tests/unit/data-structures/binary-tree/bst.test.ts index 782d451..074addd 100644 --- a/tests/unit/data-structures/binary-tree/bst.test.ts +++ b/tests/unit/data-structures/binary-tree/bst.test.ts @@ -4,9 +4,10 @@ describe('BST operations test', () => { it('should perform various operations on a Binary Search Tree with numeric values', () => { const bst = new BST(); expect(bst).toBeInstanceOf(BST); - bst.add(11); - bst.add(3); - bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]); + bst.add(11, 11); + bst.add(3, 3); + const idsAndValues = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]; + bst.addMany(idsAndValues, idsAndValues); expect(bst.root).toBeInstanceOf(BSTNode); if (bst.root) expect(bst.root.id).toBe(11); @@ -193,7 +194,7 @@ describe('BST operations test', () => { {id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7}, {id: 10, keyA: 10}, {id: 5, keyA: 5}]; - objBST.addMany(values); + objBST.addMany(values.map(item => item.id), values); expect(objBST.root).toBeInstanceOf(BSTNode); diff --git a/tests/unit/data-structures/binary-tree/tree-multiset.test.ts b/tests/unit/data-structures/binary-tree/tree-multiset.test.ts index 6aae1a4..7d91969 100644 --- a/tests/unit/data-structures/binary-tree/tree-multiset.test.ts +++ b/tests/unit/data-structures/binary-tree/tree-multiset.test.ts @@ -5,9 +5,10 @@ describe('TreeMultiset operations test', () => { const treeMultiset = new TreeMultiset(); expect(treeMultiset instanceof TreeMultiset); - treeMultiset.add(11); - treeMultiset.add(3); - treeMultiset.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]); + treeMultiset.add(11, 11); + treeMultiset.add(3, 3); + const idAndValues = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]; + treeMultiset.addMany(idAndValues, idAndValues); expect(treeMultiset.root instanceof TreeMultisetNode); if (treeMultiset.root) expect(treeMultiset.root.id == 11); @@ -199,7 +200,7 @@ describe('TreeMultiset operations test', () => { expect(bfsNodes[1].id).toBe(2); expect(bfsNodes[2].id).toBe(16); - expect(treeMultiset.count).toBe(3); + expect(treeMultiset.count).toBe(9); }); it('should perform various operations on a Binary Search Tree with object values', () => { @@ -213,7 +214,7 @@ describe('TreeMultiset operations test', () => { {id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7}, {id: 10, keyA: 10}, {id: 5, keyA: 5}]; - objTreeMultiset.addMany(values); + objTreeMultiset.addMany(values.map(item => item.id), values); expect(objTreeMultiset.root).toBeInstanceOf(TreeMultisetNode);