From 063b702236d812ace84af35bf29701f107f337f2 Mon Sep 17 00:00:00 2001 From: Revone Date: Wed, 25 Oct 2023 11:19:03 +0800 Subject: [PATCH] [project] Achieve a rational subpackage structure that enables individual subpackages to be independently exportable. --- package-lock.json | 62 ++- package.json | 10 +- scripts/copy_to_all_subs.sh | 20 +- scripts/publish_all_subs.sh | 4 +- src/data-structures/binary-tree/avl-tree.ts | 54 +-- .../binary-tree/binary-tree.ts | 110 +++--- src/data-structures/binary-tree/bst.ts | 4 + src/data-structures/binary-tree/rb-tree.ts | 4 +- .../binary-tree/tree-multiset.ts | 58 +-- src/data-structures/hash/hash-map.ts | 160 ++++---- src/data-structures/hash/hash-table.ts | 231 +++++------ src/data-structures/heap/heap.ts | 363 +++++++++--------- .../linked-list/doubly-linked-list.ts | 8 +- .../linked-list/skip-linked-list.ts | 93 ++--- src/data-structures/matrix/matrix2d.ts | 20 +- src/data-structures/trie/trie.ts | 18 +- src/types/helpers.ts | 6 +- .../binary-tree/binary-index-tree.test.ts | 2 +- 18 files changed, 629 insertions(+), 598 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f14577..b57f885 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "data-structure-typed", - "version": "1.37.9", + "version": "1.38.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-structure-typed", - "version": "1.37.9", + "version": "1.38.1", "license": "MIT", "dependencies": { "data-structure-typed": "^1.37.5" @@ -18,17 +18,17 @@ "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "auto-changelog": "^2.4.0", - "avl-tree-typed": "^1.37.9", + "avl-tree-typed": "^1.38.1", "benchmark": "^2.1.4", - "binary-tree-typed": "^1.37.9", - "bst-typed": "^1.37.9", + "binary-tree-typed": "^1.38.1", + "bst-typed": "^1.38.1", "dependency-cruiser": "^14.1.0", "eslint": "^8.50.0", "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.28.1", - "heap-typed": "^1.37.9", + "heap-typed": "^1.38.1", "istanbul-badges-readme": "^1.8.5", "jest": "^29.7.0", "prettier": "^3.0.3", @@ -2405,13 +2405,10 @@ } }, "node_modules/avl-tree-typed": { - "version": "1.37.9", - "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.37.9.tgz", - "integrity": "sha512-FC7ezzT3Yw8H65oZgf/3RGYo9gnZRgORzlGGO4PyC19ZeIu0UZMHu1+kT0yEfbIE1qGBb4lnuwk4ia8CitcgLg==", - "dev": true, - "dependencies": { - "data-structure-typed": "^1.37.9" - } + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.38.1.tgz", + "integrity": "sha512-owzl0/cOijCKDyL8RAR+8Q2ibtqA+datgKQEbs1qNpCvMgYBtaytIgwyR68jYD+u7QGTXWYdO288H6NiKI0eTA==", + "dev": true }, "node_modules/babel-jest": { "version": "29.7.0", @@ -2595,13 +2592,10 @@ } }, "node_modules/binary-tree-typed": { - "version": "1.37.9", - "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.37.9.tgz", - "integrity": "sha512-8nCjU4V6ViR8NQfxCBsLRFx5Z8D4jpUIx4NuvjliR1R8YIzL6wMmahemve+UbCUWhZJNG5Dv0kVnnCWIK+T0hw==", - "dev": true, - "dependencies": { - "data-structure-typed": "^1.37.9" - } + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.38.1.tgz", + "integrity": "sha512-h4dBfVSaqUPfpVRHI7ZWUv3BSFYF9VtzoRu5X2rIq4se89QX+1cQTirQ7bCG0mDLJ9A4GfmEVMvQvvmVhorBEQ==", + "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -2679,13 +2673,10 @@ } }, "node_modules/bst-typed": { - "version": "1.37.9", - "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.37.9.tgz", - "integrity": "sha512-KUp29JhTbNVdA1ePP7gUdi7uaRpM8DVhve9LMHQSUzxTDtHGc8mFTA+njFY7LLU2Rqtu/vqBgTu7bJRVJbWrPA==", - "dev": true, - "dependencies": { - "data-structure-typed": "^1.37.9" - } + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.38.1.tgz", + "integrity": "sha512-jNBmdOaSAApSx5iYo5ijunp3rtATcTmNOVnRiasCqKzSYTLfCJiGqIoXkDYMIFWK7hlgbAsVJkzTLciKf4RjcQ==", + "dev": true }, "node_modules/buffer-from": { "version": "1.1.2", @@ -3037,9 +3028,9 @@ } }, "node_modules/data-structure-typed": { - "version": "1.37.9", - "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.37.9.tgz", - "integrity": "sha512-6CUX8ANDv2IsJTB8tbdUrXFgWV1AAPxWdcco1ZRUX8caCM0Ge6Snwfse1G1BF6M8kVEuGO2r4q6zkw1z2DxAtQ==", + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.38.0.tgz", + "integrity": "sha512-KXYXlyQm7k09Gp4hhsneMOL1bLEPse6Kv3qeE6CU78jidJEh8SY66K9auAUio1mpkjbKTCqjf7q3Ep4pXkhB2w==", "dependencies": { "data-structure-typed": "^1.37.5" } @@ -4387,13 +4378,10 @@ } }, "node_modules/heap-typed": { - "version": "1.37.9", - "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.37.9.tgz", - "integrity": "sha512-oYkcappLoSb8Zs9gbMaUfIwsm2arykNoQ6gF28x1PQuKa0/a9zonEqqRN6dKlfOT28JIvqhnrSed039YDlZhrQ==", - "dev": true, - "dependencies": { - "data-structure-typed": "^1.37.9" - } + "version": "1.38.1", + "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.38.1.tgz", + "integrity": "sha512-PvLlO5lSds9zOOX4GvVS2mgZfLk0f7Ev+++hYkGrlCqpcCGDsXVn+B0k/Jel0mkTXIK3zVkev2if7Cxsmk1pEQ==", + "dev": true }, "node_modules/html-escaper": { "version": "2.0.2", diff --git a/package.json b/package.json index 55f3561..f8753bb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "data-structure-typed", - "version": "1.37.9", + "version": "1.38.1", "description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.", "main": "dist/index.js", "module": "lib/index.js", @@ -59,17 +59,17 @@ "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "auto-changelog": "^2.4.0", - "avl-tree-typed": "^1.37.9", + "avl-tree-typed": "^1.38.1", "benchmark": "^2.1.4", - "binary-tree-typed": "^1.37.9", - "bst-typed": "^1.37.9", + "binary-tree-typed": "^1.38.1", + "bst-typed": "^1.38.1", "dependency-cruiser": "^14.1.0", "eslint": "^8.50.0", "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-alias": "^1.1.2", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.28.1", - "heap-typed": "^1.37.9", + "heap-typed": "^1.38.1", "istanbul-badges-readme": "^1.8.5", "jest": "^29.7.0", "prettier": "^3.0.3", diff --git a/scripts/copy_to_all_subs.sh b/scripts/copy_to_all_subs.sh index f8befe0..a12a000 100644 --- a/scripts/copy_to_all_subs.sh +++ b/scripts/copy_to_all_subs.sh @@ -12,7 +12,25 @@ source_dir_default=$(jq -r .sourceDir ./scripts/config.json) # List of directories directories=( "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" + "queue-typed" + "stack-typed" + "tree-multiset-typed" + "trie-typed" + "undirected-graph-typed" ) # Loop through each directory diff --git a/scripts/publish_all_subs.sh b/scripts/publish_all_subs.sh index 7b7da2f..6f52833 100755 --- a/scripts/publish_all_subs.sh +++ b/scripts/publish_all_subs.sh @@ -61,8 +61,8 @@ for dir in "${directories[@]}"; do # jq ".dependencies[\"data-structure-typed\"] = \"$version_prompted\"" package.json > temp.json # mv temp.json package.json - # Install data-structure-typed package and build - npm i data-structure-typed@"$version_prompted" +# # Install data-structure-typed package and build +# npm i data-structure-typed@"$version_prompted" npm run build:publish cd .. diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts index a1f8fb0..1b1c88d 100644 --- a/src/data-structures/binary-tree/avl-tree.ts +++ b/src/data-structures/binary-tree/avl-tree.ts @@ -32,33 +32,6 @@ export class AVLTree = AVLTreeNode> extends B super(options); } - /** - * The function swaps the key, value, and height properties between two nodes in a binary tree. - * @param {N} srcNode - The `srcNode` parameter represents the source node that needs to be swapped - * with the `destNode`. - * @param {N} destNode - The `destNode` parameter represents the destination node where the values - * from the source node (`srcNode`) will be swapped to. - * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`. - */ - protected override _swap(srcNode: N, destNode: N): N { - const {key, val, height} = destNode; - const tempNode = this.createNode(key, val); - - if (tempNode) { - tempNode.height = height; - - destNode.key = srcNode.key; - destNode.val = srcNode.val; - destNode.height = srcNode.height; - - srcNode.key = tempNode.key; - srcNode.val = tempNode.val; - srcNode.height = tempNode.height; - } - - return destNode; - } - /** * The function creates a new AVL tree node with the specified key and value. * @param {BinaryTreeNodeKey} key - The key parameter is the key value that will be associated with @@ -105,6 +78,33 @@ export class AVLTree = AVLTreeNode> extends B return deletedResults; } + /** + * The function swaps the key, value, and height properties between two nodes in a binary tree. + * @param {N} srcNode - The `srcNode` parameter represents the source node that needs to be swapped + * with the `destNode`. + * @param {N} destNode - The `destNode` parameter represents the destination node where the values + * from the source node (`srcNode`) will be swapped to. + * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`. + */ + protected override _swap(srcNode: N, destNode: N): N { + const {key, val, height} = destNode; + const tempNode = this.createNode(key, val); + + if (tempNode) { + tempNode.height = height; + + destNode.key = srcNode.key; + destNode.val = srcNode.val; + destNode.height = srcNode.height; + + srcNode.key = tempNode.key; + srcNode.val = tempNode.val; + srcNode.height = tempNode.height; + } + + return destNode; + } + /** * The function calculates the balance factor of a node in a binary tree. * @param {N} node - The parameter "node" represents a node in a binary tree data structure. diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index e654f31..a82f8a3 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -26,16 +26,6 @@ import {Queue} from '../queue'; * @template FAMILY - The type of the family relationship in the binary tree. */ export class BinaryTreeNode = BinaryTreeNodeNested> { - /** - * Creates a new instance of BinaryTreeNode. - * @param {BinaryTreeNodeKey} key - The key associated with the node. - * @param {V} val - The value stored in the node. - */ - constructor(key: BinaryTreeNodeKey, val?: V) { - this.key = key; - this.val = val; - } - /** * The key associated with the node. */ @@ -46,6 +36,21 @@ export class BinaryTreeNode = */ val: V | undefined; + /** + * The parent node of the current node. + */ + parent: FAMILY | null | undefined; + + /** + * Creates a new instance of BinaryTreeNode. + * @param {BinaryTreeNodeKey} key - The key associated with the node. + * @param {V} val - The value stored in the node. + */ + constructor(key: BinaryTreeNodeKey, val?: V) { + this.key = key; + this.val = val; + } + private _left: FAMILY | null | undefined; /** @@ -86,11 +91,6 @@ export class BinaryTreeNode = this._right = v; } - /** - * The parent node of the current node. - */ - parent: FAMILY | null | undefined; - /** * Get the position of the node within its family. * @returns {FamilyPosition} - The family position of the node. @@ -128,6 +128,8 @@ export class BinaryTreeNode = * @template N - The type of the binary tree's nodes. */ export class BinaryTree = BinaryTreeNode> implements IBinaryTree { + private _loopType: IterationType = IterationType.ITERATIVE; + /** * Creates a new instance of BinaryTree. * @param {BinaryTreeOptions} [options] - The options for the binary tree. @@ -139,16 +141,6 @@ export class BinaryTree = BinaryTreeNode> } } - /** - * Creates a new instance of BinaryTreeNode with the given key and value. - * @param {BinaryTreeNodeKey} key - The key for the new node. - * @param {N['val']} val - The value for the new node. - * @returns {N} - The newly created BinaryTreeNode. - */ - createNode(key: BinaryTreeNodeKey, val?: N['val']): N { - return new BinaryTreeNode(key, val) as N; - } - private _root: N | null = null; /** @@ -167,8 +159,6 @@ export class BinaryTree = BinaryTreeNode> return this._size; } - private _loopType: IterationType = IterationType.ITERATIVE; - /** * Get the iteration type used in the binary tree. */ @@ -185,24 +175,13 @@ export class BinaryTree = BinaryTreeNode> } /** - * Swap the data of two nodes in the binary tree. - * @param {N} srcNode - The source node to swap. - * @param {N} destNode - The destination node to swap. - * @returns {N} - The destination node after the swap. + * Creates a new instance of BinaryTreeNode with the given key and value. + * @param {BinaryTreeNodeKey} key - The key for the new node. + * @param {N['val']} val - The value for the new node. + * @returns {N} - The newly created BinaryTreeNode. */ - protected _swap(srcNode: N, destNode: N): N { - const {key, val} = destNode; - const tempNode = this.createNode(key, val); - - if (tempNode) { - destNode.key = srcNode.key; - destNode.val = srcNode.val; - - srcNode.key = tempNode.key; - srcNode.val = tempNode.val; - } - - return destNode; + createNode(key: BinaryTreeNodeKey, val?: N['val']): N { + return new BinaryTreeNode(key, val) as N; } /** @@ -449,8 +428,6 @@ export class BinaryTree = BinaryTreeNode> } } - protected _defaultCallbackByKey: MapCallback = node => node.key; - /** * The `getMinHeight` function calculates the minimum height of a binary tree using either a * recursive or iterative approach. @@ -902,8 +879,6 @@ export class BinaryTree = BinaryTreeNode> return ans; } - // --- start additional methods --- - /** * The bfs function performs a breadth-first search traversal on a binary tree, executing a callback * function on each node. @@ -973,13 +948,7 @@ export class BinaryTree = BinaryTreeNode> } } - /** - * Time complexity is O(n) - * Space complexity of Iterative dfs equals to recursive dfs which is O(n) because of the stack - * The Morris algorithm only modifies the tree's structure during traversal; once the traversal is complete, - * the tree's structure should be restored to its original state to maintain the tree's integrity. - * This is because the purpose of the Morris algorithm is to save space rather than permanently alter the tree's shape. - */ + // --- start additional methods --- /** * The `morris` function performs a depth-first traversal of a binary tree using the Morris traversal @@ -1080,6 +1049,37 @@ export class BinaryTree = BinaryTreeNode> return ans; } + /** + * Swap the data of two nodes in the binary tree. + * @param {N} srcNode - The source node to swap. + * @param {N} destNode - The destination node to swap. + * @returns {N} - The destination node after the swap. + */ + protected _swap(srcNode: N, destNode: N): N { + const {key, val} = destNode; + const tempNode = this.createNode(key, val); + + if (tempNode) { + destNode.key = srcNode.key; + destNode.val = srcNode.val; + + srcNode.key = tempNode.key; + srcNode.val = tempNode.val; + } + + return destNode; + } + + /** + * Time complexity is O(n) + * Space complexity of Iterative dfs equals to recursive dfs which is O(n) because of the stack + * The Morris algorithm only modifies the tree's structure during traversal; once the traversal is complete, + * the tree's structure should be restored to its original state to maintain the tree's integrity. + * This is because the purpose of the Morris algorithm is to save space rather than permanently alter the tree's shape. + */ + + protected _defaultCallbackByKey: MapCallback = node => node.key; + /** * The function `_addTo` adds a new node to a binary tree if there is an available position. * @param {N | null} newNode - The `newNode` parameter represents the node that you want to add to diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index f9bd32b..b16ec02 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -153,22 +153,26 @@ export class BST = BSTNode> extends BinaryTree function hasNoNull(arr: (BinaryTreeNodeKey | null)[] | (N | null)[]): arr is BinaryTreeNodeKey[] | N[] { return arr.indexOf(null) === -1; } + if (!isBalanceAdd || !hasNoNull(keysOrNodes)) { return super.addMany(keysOrNodes, data); } const inserted: (N | null | undefined)[] = []; const combinedArr: [BinaryTreeNodeKey | N, N['val']][] = keysOrNodes.map((value, index) => [value, data?.[index]]); let sorted = []; + function isNodeOrNullTuple(arr: [BinaryTreeNodeKey | N, N['val']][]): arr is [N, N['val']][] { for (const [keyOrNode] of arr) if (keyOrNode instanceof BSTNode) return true; return false; } + function isBinaryTreeKeyOrNullTuple( arr: [BinaryTreeNodeKey | N, N['val']][] ): arr is [BinaryTreeNodeKey, N['val']][] { for (const [keyOrNode] of arr) if (typeof keyOrNode === 'number') return true; return false; } + let sortedKeysOrNodes: (number | N | null)[] = [], sortedData: (N['val'] | undefined)[] | undefined = []; diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts index fafb4f1..d8d1685 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -6,13 +6,13 @@ export class RBTreeNode = RBTreeNo V, FAMILY > { - private _color: RBColor; - constructor(key: BinaryTreeNodeKey, val?: V) { super(key, val); this._color = RBColor.RED; } + private _color: RBColor; + get color(): RBColor { return this._color; } diff --git a/src/data-structures/binary-tree/tree-multiset.ts b/src/data-structures/binary-tree/tree-multiset.ts index 7dce900..a36826b 100644 --- a/src/data-structures/binary-tree/tree-multiset.ts +++ b/src/data-structures/binary-tree/tree-multiset.ts @@ -14,6 +14,8 @@ export class TreeMultisetNode< V = any, FAMILY extends TreeMultisetNode = TreeMultisetNodeNested > extends AVLTreeNode { + count: number; + /** * The constructor function initializes a BinaryTreeNode object with a key, value, and count. * @param {BinaryTreeNodeKey} key - The `key` parameter is of type `BinaryTreeNodeKey` and represents the unique identifier @@ -28,8 +30,6 @@ export class TreeMultisetNode< super(key, val); this.count = count; } - - count: number; } /** @@ -68,33 +68,6 @@ export class TreeMultiset = TreeMultiset return new TreeMultisetNode(key, val, count) as N; } - /** - * The function swaps the values of two nodes in a binary tree. - * @param {N} srcNode - The source node that needs to be swapped with the destination node. - * @param {N} destNode - The `destNode` parameter represents the destination node where the values - * from `srcNode` will be swapped into. - * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`. - */ - protected override _swap(srcNode: N, destNode: N): N { - const {key, val, count, height} = destNode; - const tempNode = this.createNode(key, val, count); - if (tempNode) { - tempNode.height = height; - - destNode.key = srcNode.key; - destNode.val = srcNode.val; - destNode.count = srcNode.count; - destNode.height = srcNode.height; - - srcNode.key = tempNode.key; - srcNode.val = tempNode.val; - srcNode.count = tempNode.count; - srcNode.height = tempNode.height; - } - - return destNode; - } - /** * The `add` function adds a new node to a binary search tree, updating the count if the key already * exists, and balancing the tree if necessary. @@ -365,6 +338,33 @@ export class TreeMultiset = TreeMultiset this._setCount(0); } + /** + * The function swaps the values of two nodes in a binary tree. + * @param {N} srcNode - The source node that needs to be swapped with the destination node. + * @param {N} destNode - The `destNode` parameter represents the destination node where the values + * from `srcNode` will be swapped into. + * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`. + */ + protected override _swap(srcNode: N, destNode: N): N { + const {key, val, count, height} = destNode; + const tempNode = this.createNode(key, val, count); + if (tempNode) { + tempNode.height = height; + + destNode.key = srcNode.key; + destNode.val = srcNode.val; + destNode.count = srcNode.count; + destNode.height = srcNode.height; + + srcNode.key = tempNode.key; + srcNode.val = tempNode.val; + srcNode.count = tempNode.count; + srcNode.height = tempNode.height; + } + + return destNode; + } + /** * The function sets the value of the "_count" property. * @param {number} v - number diff --git a/src/data-structures/hash/hash-map.ts b/src/data-structures/hash/hash-map.ts index 7661bf0..f3a5213 100644 --- a/src/data-structures/hash/hash-map.ts +++ b/src/data-structures/hash/hash-map.ts @@ -8,60 +8,6 @@ import {HashFunction} from '../../types'; * @license MIT License */ export class HashMap { - get hashFn(): HashFunction { - return this._hashFn; - } - - set hashFn(value: HashFunction) { - this._hashFn = value; - } - get table(): Array> { - return this._table; - } - - set table(value: Array>) { - this._table = value; - } - - get capacityMultiplier(): number { - return this._capacityMultiplier; - } - - set capacityMultiplier(value: number) { - this._capacityMultiplier = value; - } - - get loadFactor(): number { - return this._loadFactor; - } - - set loadFactor(value: number) { - this._loadFactor = value; - } - - get initialCapacity(): number { - return this._initialCapacity; - } - - set initialCapacity(value: number) { - this._initialCapacity = value; - } - - get size(): number { - return this._size; - } - - set size(value: number) { - this._size = value; - } - - private _initialCapacity: number; - private _loadFactor: number; - private _capacityMultiplier: number; - private _size: number; - private _table: Array>; - private _hashFn: HashFunction; - /** * The constructor initializes the properties of a hash table, including the initial capacity, load factor, capacity * multiplier, size, table array, and hash function. @@ -92,31 +38,64 @@ export class HashMap { }); } - private _hash(key: K): number { - return this._hashFn(key); + private _initialCapacity: number; + + get initialCapacity(): number { + return this._initialCapacity; } - /** - * The `resizeTable` function resizes the table used in a hash map by creating a new table with a specified capacity and - * rehashing the key-value pairs from the old table into the new table. - * @param {number} newCapacity - The newCapacity parameter is the desired capacity for the resized table. It represents - * the number of buckets that the new table should have. - */ - private resizeTable(newCapacity: number): void { - const newTable = new Array(newCapacity); - for (const bucket of this._table) { - // Note that this is this._table - if (bucket) { - for (const [key, value] of bucket) { - const newIndex = this._hash(key) % newCapacity; - if (!newTable[newIndex]) { - newTable[newIndex] = []; - } - newTable[newIndex].push([key, value]); - } - } - } - this._table = newTable; // Again, here is this._table + set initialCapacity(value: number) { + this._initialCapacity = value; + } + + private _loadFactor: number; + + get loadFactor(): number { + return this._loadFactor; + } + + set loadFactor(value: number) { + this._loadFactor = value; + } + + private _capacityMultiplier: number; + + get capacityMultiplier(): number { + return this._capacityMultiplier; + } + + set capacityMultiplier(value: number) { + this._capacityMultiplier = value; + } + + private _size: number; + + get size(): number { + return this._size; + } + + set size(value: number) { + this._size = value; + } + + private _table: Array>; + + get table(): Array> { + return this._table; + } + + set table(value: Array>) { + this._table = value; + } + + private _hashFn: HashFunction; + + get hashFn(): HashFunction { + return this._hashFn; + } + + set hashFn(value: HashFunction) { + this._hashFn = value; } set(key: K, value: V): void { @@ -200,4 +179,31 @@ export class HashMap { isEmpty(): boolean { return this.size === 0; } + + private _hash(key: K): number { + return this._hashFn(key); + } + + /** + * The `resizeTable` function resizes the table used in a hash map by creating a new table with a specified capacity and + * rehashing the key-value pairs from the old table into the new table. + * @param {number} newCapacity - The newCapacity parameter is the desired capacity for the resized table. It represents + * the number of buckets that the new table should have. + */ + private resizeTable(newCapacity: number): void { + const newTable = new Array(newCapacity); + for (const bucket of this._table) { + // Note that this is this._table + if (bucket) { + for (const [key, value] of bucket) { + const newIndex = this._hash(key) % newCapacity; + if (!newTable[newIndex]) { + newTable[newIndex] = []; + } + newTable[newIndex].push([key, value]); + } + } + } + this._table = newTable; // Again, here is this._table + } } diff --git a/src/data-structures/hash/hash-table.ts b/src/data-structures/hash/hash-table.ts index 00ac8da..bf0116e 100644 --- a/src/data-structures/hash/hash-table.ts +++ b/src/data-structures/hash/hash-table.ts @@ -21,21 +21,17 @@ export class HashTableNode { import {HashFunction} from '../../types'; export class HashTable { - get hashFn(): HashFunction { - return this._hashFn; + private static readonly DEFAULT_CAPACITY = 16; + private static readonly LOAD_FACTOR = 0.75; + + constructor(capacity: number = HashTable.DEFAULT_CAPACITY, hashFn?: HashFunction) { + this._hashFn = hashFn || this._defaultHashFn; + this._capacity = Math.max(capacity, HashTable.DEFAULT_CAPACITY); + this._size = 0; + this._buckets = new Array | null>(this._capacity).fill(null); } - set hashFn(value: HashFunction) { - this._hashFn = value; - } - - get buckets(): Array | null> { - return this._buckets; - } - - set buckets(value: Array | null>) { - this._buckets = value; - } + private _capacity: number; get capacity(): number { return this._capacity; @@ -45,19 +41,118 @@ export class HashTable { this._capacity = value; } - private static readonly DEFAULT_CAPACITY = 16; - private static readonly LOAD_FACTOR = 0.75; - - private _capacity: number; private _size: number; + + get size(): number { + return this._size; + } + private _buckets: Array | null>; + + get buckets(): Array | null> { + return this._buckets; + } + + set buckets(value: Array | null>) { + this._buckets = value; + } + private _hashFn: HashFunction; - constructor(capacity: number = HashTable.DEFAULT_CAPACITY, hashFn?: HashFunction) { - this._hashFn = hashFn || this._defaultHashFn; - this._capacity = Math.max(capacity, HashTable.DEFAULT_CAPACITY); - this._size = 0; - this._buckets = new Array | null>(this._capacity).fill(null); + get hashFn(): HashFunction { + return this._hashFn; + } + + set hashFn(value: HashFunction) { + this._hashFn = value; + } + + /** + * The set function adds a key-value pair to the hash table, handling collisions and resizing if necessary. + * @param {K} key - The key parameter represents the key of the key-value pair that you want to insert into the hash + * table. It is of type K, which is a generic type representing the key's data type. + * @param {V} val - The parameter `val` represents the value that you want to associate with the given key in the hash + * table. + * @returns Nothing is being returned. The return type of the `put` method is `void`, which means it does not return any + * value. + */ + set(key: K, val: V): void { + const index = this._hash(key); + const newNode = new HashTableNode(key, val); + + if (!this._buckets[index]) { + this._buckets[index] = newNode; + } else { + // Handle collisions, consider using open addressing, etc. + let currentNode = this._buckets[index]!; + while (currentNode) { + if (currentNode.key === key) { + // If the key already exists, update the value + currentNode.val = val; + return; + } + if (!currentNode.next) { + break; + } + currentNode = currentNode.next; + } + // Add to the end of the linked list + currentNode.next = newNode; + } + this._size++; + + // If the load factor is too high, resize the hash table + if (this._size / this._capacity >= HashTable.LOAD_FACTOR) { + this._expand(); + } + } + + /** + * The `get` function retrieves the value associated with a given key from a hash table. + * @param {K} key - The `key` parameter represents the key of the element that we want to retrieve from the data + * structure. + * @returns The method is returning the value associated with the given key if it exists in the hash table. If the key is + * not found, it returns `undefined`. + */ + get(key: K): V | undefined { + const index = this._hash(key); + let currentNode = this._buckets[index]; + + while (currentNode) { + if (currentNode.key === key) { + return currentNode.val; + } + currentNode = currentNode.next; + } + return undefined; // Key not found + } + + /** + * The delete function removes a key-value pair from a hash table. + * @param {K} key - The `key` parameter represents the key of the key-value pair that needs to be removed from the hash + * table. + * @returns Nothing is being returned. The `delete` method has a return type of `void`, which means it does not return + * any value. + */ + delete(key: K): void { + const index = this._hash(key); + let currentNode = this._buckets[index]; + let prevNode: HashTableNode | null = null; + + while (currentNode) { + if (currentNode.key === key) { + if (prevNode) { + prevNode.next = currentNode.next; + } else { + this._buckets[index] = currentNode.next; + } + this._size--; + currentNode.next = null; // Release memory + return; + } + prevNode = currentNode; + currentNode = currentNode.next; + } } /** @@ -152,94 +247,6 @@ export class HashTable { return this._stringHash(JSON.stringify(key)); } - /** - * The set function adds a key-value pair to the hash table, handling collisions and resizing if necessary. - * @param {K} key - The key parameter represents the key of the key-value pair that you want to insert into the hash - * table. It is of type K, which is a generic type representing the key's data type. - * @param {V} val - The parameter `val` represents the value that you want to associate with the given key in the hash - * table. - * @returns Nothing is being returned. The return type of the `put` method is `void`, which means it does not return any - * value. - */ - set(key: K, val: V): void { - const index = this._hash(key); - const newNode = new HashTableNode(key, val); - - if (!this._buckets[index]) { - this._buckets[index] = newNode; - } else { - // Handle collisions, consider using open addressing, etc. - let currentNode = this._buckets[index]!; - while (currentNode) { - if (currentNode.key === key) { - // If the key already exists, update the value - currentNode.val = val; - return; - } - if (!currentNode.next) { - break; - } - currentNode = currentNode.next; - } - // Add to the end of the linked list - currentNode.next = newNode; - } - this._size++; - - // If the load factor is too high, resize the hash table - if (this._size / this._capacity >= HashTable.LOAD_FACTOR) { - this._expand(); - } - } - - /** - * The `get` function retrieves the value associated with a given key from a hash table. - * @param {K} key - The `key` parameter represents the key of the element that we want to retrieve from the data - * structure. - * @returns The method is returning the value associated with the given key if it exists in the hash table. If the key is - * not found, it returns `undefined`. - */ - get(key: K): V | undefined { - const index = this._hash(key); - let currentNode = this._buckets[index]; - - while (currentNode) { - if (currentNode.key === key) { - return currentNode.val; - } - currentNode = currentNode.next; - } - return undefined; // Key not found - } - - /** - * The delete function removes a key-value pair from a hash table. - * @param {K} key - The `key` parameter represents the key of the key-value pair that needs to be removed from the hash - * table. - * @returns Nothing is being returned. The `delete` method has a return type of `void`, which means it does not return - * any value. - */ - delete(key: K): void { - const index = this._hash(key); - let currentNode = this._buckets[index]; - let prevNode: HashTableNode | null = null; - - while (currentNode) { - if (currentNode.key === key) { - if (prevNode) { - prevNode.next = currentNode.next; - } else { - this._buckets[index] = currentNode.next; - } - this._size--; - currentNode.next = null; // Release memory - return; - } - prevNode = currentNode; - currentNode = currentNode.next; - } - } - /** * The `expand` function increases the capacity of a hash table by creating a new array of buckets with double the * capacity and rehashing all the existing key-value pairs into the new buckets. @@ -270,8 +277,4 @@ export class HashTable { this._buckets = newBuckets; this._capacity = newCapacity; } - - get size(): number { - return this._size; - } } diff --git a/src/data-structures/heap/heap.ts b/src/data-structures/heap/heap.ts index 55bbbf1..177b1e7 100644 --- a/src/data-structures/heap/heap.ts +++ b/src/data-structures/heap/heap.ts @@ -15,6 +15,34 @@ export class Heap { this.comparator = comparator; } + /** + * Get the size (number of elements) of the heap. + */ + get size(): number { + return this.nodes.length; + } + + /** + * Get the last element in the heap, which is not necessarily a leaf node. + * @returns The last element or undefined if the heap is empty. + */ + get leaf(): E | undefined { + return this.nodes[this.size - 1] ?? undefined; + } + + /** + * Static method that creates a binary heap from an array of nodes and a comparison function. + * @param nodes + * @param comparator - Comparison function. + * @returns A new Heap instance. + */ + static heapify(nodes: E[], comparator: Comparator): Heap { + const binaryHeap = new Heap(comparator); + binaryHeap.nodes = [...nodes]; + binaryHeap.fix(); // Fix heap properties + return binaryHeap; + } + /** * Insert an element into the heap and maintain the heap properties. * @param element - The element to be inserted. @@ -59,57 +87,6 @@ export class Heap { return this.poll(); } - /** - * Float operation to maintain heap properties after adding an element. - * @param index - The index of the newly added element. - */ - protected bubbleUp(index: number): void { - const element = this.nodes[index]; - while (index > 0) { - const parentIndex = Math.floor((index - 1) / 2); - const parent = this.nodes[parentIndex]; - if (this.comparator(element, parent) < 0) { - this.nodes[index] = parent; - this.nodes[parentIndex] = element; - index = parentIndex; - } else { - break; - } - } - } - - /** - * Sinking operation to maintain heap properties after removing the top element. - * @param index - The index from which to start sinking. - */ - protected sinkDown(index: number): void { - const leftChildIndex = 2 * index + 1; - const rightChildIndex = 2 * index + 2; - const length = this.nodes.length; - let targetIndex = index; - - if (leftChildIndex < length && this.comparator(this.nodes[leftChildIndex], this.nodes[targetIndex]) < 0) { - targetIndex = leftChildIndex; - } - if (rightChildIndex < length && this.comparator(this.nodes[rightChildIndex], this.nodes[targetIndex]) < 0) { - targetIndex = rightChildIndex; - } - - if (targetIndex !== index) { - const temp = this.nodes[index]; - this.nodes[index] = this.nodes[targetIndex]; - this.nodes[targetIndex] = temp; - this.sinkDown(targetIndex); - } - } - - /** - * Fix the entire heap to maintain heap properties. - */ - protected fix() { - for (let i = Math.floor(this.size / 2); i >= 0; i--) this.sinkDown(i); - } - /** * Peek at the top element of the heap without removing it. * @returns The top element or undefined if the heap is empty. @@ -121,21 +98,6 @@ export class Heap { return this.nodes[0]; } - /** - * Get the size (number of elements) of the heap. - */ - get size(): number { - return this.nodes.length; - } - - /** - * Get the last element in the heap, which is not necessarily a leaf node. - * @returns The last element or undefined if the heap is empty. - */ - get leaf(): E | undefined { - return this.nodes[this.size - 1] ?? undefined; - } - /** * Check if the heap is empty. * @returns True if the heap is empty, otherwise false. @@ -238,16 +200,54 @@ export class Heap { } /** - * Static method that creates a binary heap from an array of nodes and a comparison function. - * @param nodes - * @param comparator - Comparison function. - * @returns A new Heap instance. + * Float operation to maintain heap properties after adding an element. + * @param index - The index of the newly added element. */ - static heapify(nodes: E[], comparator: Comparator): Heap { - const binaryHeap = new Heap(comparator); - binaryHeap.nodes = [...nodes]; - binaryHeap.fix(); // Fix heap properties - return binaryHeap; + protected bubbleUp(index: number): void { + const element = this.nodes[index]; + while (index > 0) { + const parentIndex = Math.floor((index - 1) / 2); + const parent = this.nodes[parentIndex]; + if (this.comparator(element, parent) < 0) { + this.nodes[index] = parent; + this.nodes[parentIndex] = element; + index = parentIndex; + } else { + break; + } + } + } + + /** + * Sinking operation to maintain heap properties after removing the top element. + * @param index - The index from which to start sinking. + */ + protected sinkDown(index: number): void { + const leftChildIndex = 2 * index + 1; + const rightChildIndex = 2 * index + 2; + const length = this.nodes.length; + let targetIndex = index; + + if (leftChildIndex < length && this.comparator(this.nodes[leftChildIndex], this.nodes[targetIndex]) < 0) { + targetIndex = leftChildIndex; + } + if (rightChildIndex < length && this.comparator(this.nodes[rightChildIndex], this.nodes[targetIndex]) < 0) { + targetIndex = rightChildIndex; + } + + if (targetIndex !== index) { + const temp = this.nodes[index]; + this.nodes[index] = this.nodes[targetIndex]; + this.nodes[targetIndex] = temp; + this.sinkDown(targetIndex); + } + } + + /** + * Fix the entire heap to maintain heap properties. + */ + protected fix() { + for (let i = Math.floor(this.size / 2); i >= 0; i--) this.sinkDown(i); } } @@ -259,6 +259,7 @@ export class FibonacciHeapNode { child?: FibonacciHeapNode; parent?: FibonacciHeapNode; marked: boolean; + constructor(element: E, degree = 0) { this.element = element; this.degree = degree; @@ -268,8 +269,8 @@ export class FibonacciHeapNode { export class FibonacciHeap { root?: FibonacciHeapNode; - protected min?: FibonacciHeapNode; size: number = 0; + protected min?: FibonacciHeapNode; protected readonly comparator: Comparator; constructor(comparator?: Comparator) { @@ -281,18 +282,6 @@ export class FibonacciHeap { } } - /** - * Default comparator function used by the heap. - * @param {E} a - * @param {E} b - * @protected - */ - protected defaultComparator(a: E, b: E): number { - if (a < b) return -1; - if (a > b) return 1; - return 0; - } - /** * Get the size (number of elements) of the heap. * @returns {number} The size of the heap. Returns 0 if the heap is empty. Returns -1 if the heap is invalid. @@ -303,30 +292,6 @@ export class FibonacciHeap { this.size = 0; } - /** - * Create a new node. - * @param element - * @protected - */ - protected createNode(element: E): FibonacciHeapNode { - return new FibonacciHeapNode(element); - } - - /** - * Merge the given node with the root list. - * @param node - The node to be merged. - */ - protected mergeWithRoot(node: FibonacciHeapNode): void { - if (!this.root) { - this.root = node; - } else { - node.right = this.root.right; - node.left = this.root; - this.root.right!.left = node; - this.root.right = node; - } - } - /** * O(1) time operation. * Insert an element into the heap and maintain the heap properties. @@ -394,18 +359,6 @@ export class FibonacciHeap { return nodes; } - /** - * O(log n) time operation. - * Remove and return the top element (smallest or largest element) from the heap. - * @param node - The node to be removed. - * @protected - */ - protected removeFromRoot(node: FibonacciHeapNode): void { - if (this.root === node) this.root = node.right; - if (node.left) node.left.right = node.right; - if (node.right) node.right.left = node.left; - } - /** * O(log n) time operation. * Remove and return the top element (smallest or largest element) from the heap. @@ -423,63 +376,6 @@ export class FibonacciHeap { } } - /** - * O(log n) time operation. - * Remove and return the top element (smallest or largest element) from the heap. - * @param y - * @param x - * @protected - */ - protected link(y: FibonacciHeapNode, x: FibonacciHeapNode): void { - this.removeFromRoot(y); - y.left = y; - y.right = y; - this.mergeWithChild(x, y); - x.degree++; - y.parent = x; - } - - /** - * O(log n) time operation. - * Remove and return the top element (smallest or largest element) from the heap. - * @protected - */ - protected consolidate(): void { - const A: (FibonacciHeapNode | undefined)[] = new Array(this.size); - const nodes = this.consumeLinkedList(this.root); - let x: FibonacciHeapNode | undefined, - y: FibonacciHeapNode | undefined, - d: number, - t: FibonacciHeapNode | undefined; - - for (const node of nodes) { - x = node; - d = x.degree; - - while (A[d]) { - y = A[d] as FibonacciHeapNode; - - if (this.comparator(x.element, y.element) > 0) { - t = x; - x = y; - y = t; - } - - this.link(y, x); - A[d] = undefined; - d++; - } - - A[d] = x; - } - - for (let i = 0; i < this.size; i++) { - if (A[i] && this.comparator(A[i]!.element, this.min!.element) <= 0) { - this.min = A[i]!; - } - } - } - /** * O(log n) time operation. * Remove and return the top element (smallest or largest element) from the heap. @@ -557,4 +453,109 @@ export class FibonacciHeap { // Clear the heap that was merged heapToMerge.clear(); } + + /** + * Default comparator function used by the heap. + * @param {E} a + * @param {E} b + * @protected + */ + protected defaultComparator(a: E, b: E): number { + if (a < b) return -1; + if (a > b) return 1; + return 0; + } + + /** + * Create a new node. + * @param element + * @protected + */ + protected createNode(element: E): FibonacciHeapNode { + return new FibonacciHeapNode(element); + } + + /** + * Merge the given node with the root list. + * @param node - The node to be merged. + */ + protected mergeWithRoot(node: FibonacciHeapNode): void { + if (!this.root) { + this.root = node; + } else { + node.right = this.root.right; + node.left = this.root; + this.root.right!.left = node; + this.root.right = node; + } + } + + /** + * O(log n) time operation. + * Remove and return the top element (smallest or largest element) from the heap. + * @param node - The node to be removed. + * @protected + */ + protected removeFromRoot(node: FibonacciHeapNode): void { + if (this.root === node) this.root = node.right; + if (node.left) node.left.right = node.right; + if (node.right) node.right.left = node.left; + } + + /** + * O(log n) time operation. + * Remove and return the top element (smallest or largest element) from the heap. + * @param y + * @param x + * @protected + */ + protected link(y: FibonacciHeapNode, x: FibonacciHeapNode): void { + this.removeFromRoot(y); + y.left = y; + y.right = y; + this.mergeWithChild(x, y); + x.degree++; + y.parent = x; + } + + /** + * O(log n) time operation. + * Remove and return the top element (smallest or largest element) from the heap. + * @protected + */ + protected consolidate(): void { + const A: (FibonacciHeapNode | undefined)[] = new Array(this.size); + const nodes = this.consumeLinkedList(this.root); + let x: FibonacciHeapNode | undefined, + y: FibonacciHeapNode | undefined, + d: number, + t: FibonacciHeapNode | undefined; + + for (const node of nodes) { + x = node; + d = x.degree; + + while (A[d]) { + y = A[d] as FibonacciHeapNode; + + if (this.comparator(x.element, y.element) > 0) { + t = x; + x = y; + y = t; + } + + this.link(y, x); + A[d] = undefined; + d++; + } + + A[d] = x; + } + + for (let i = 0; i < this.size; i++) { + if (A[i] && this.comparator(A[i]!.element, this.min!.element) <= 0) { + this.min = A[i]!; + } + } + } } diff --git a/src/data-structures/linked-list/doubly-linked-list.ts b/src/data-structures/linked-list/doubly-linked-list.ts index 58e917d..cbd69d5 100644 --- a/src/data-structures/linked-list/doubly-linked-list.ts +++ b/src/data-structures/linked-list/doubly-linked-list.ts @@ -84,6 +84,10 @@ export class DoublyLinkedList { return this._length; } + get size(): number { + return this.length; + } + /** * The `fromArray` function creates a new instance of a DoublyLinkedList and populates it with the elements from the * given array. @@ -222,10 +226,6 @@ export class DoublyLinkedList { return this.tail?.val; } - get size(): number { - return this.length; - } - /** * The `getAt` function returns the value at a specified index in a linked list, or null if the index is out of bounds. * @param {number} index - The index parameter is a number that represents the position of the element we want to diff --git a/src/data-structures/linked-list/skip-linked-list.ts b/src/data-structures/linked-list/skip-linked-list.ts index 23778eb..59842ae 100644 --- a/src/data-structures/linked-list/skip-linked-list.ts +++ b/src/data-structures/linked-list/skip-linked-list.ts @@ -19,39 +19,6 @@ export class SkipListNode { } export class SkipList { - get probability(): number { - return this._probability; - } - - set probability(value: number) { - this._probability = value; - } - get maxLevel(): number { - return this._maxLevel; - } - - set maxLevel(value: number) { - this._maxLevel = value; - } - get level(): number { - return this._level; - } - - set level(value: number) { - this._level = value; - } - get head(): SkipListNode { - return this._head; - } - - set head(value: SkipListNode) { - this._head = value; - } - private _head: SkipListNode; - private _level: number; - private _maxLevel: number; - private _probability: number; - /** * The constructor initializes a SkipList with a specified maximum level and probability. * @param [maxLevel=16] - The `maxLevel` parameter represents the maximum level that a skip list can have. It determines @@ -66,16 +33,44 @@ export class SkipList { this._probability = probability; } - /** - * The function "randomLevel" generates a random level based on a given probability and maximum level. - * @returns the level, which is a number. - */ - private randomLevel(): number { - let level = 1; - while (Math.random() < this.probability && level < this.maxLevel) { - level++; - } - return level; + private _head: SkipListNode; + + get head(): SkipListNode { + return this._head; + } + + set head(value: SkipListNode) { + this._head = value; + } + + private _level: number; + + get level(): number { + return this._level; + } + + set level(value: number) { + this._level = value; + } + + private _maxLevel: number; + + get maxLevel(): number { + return this._maxLevel; + } + + set maxLevel(value: number) { + this._maxLevel = value; + } + + private _probability: number; + + get probability(): number { + return this._probability; + } + + set probability(value: number) { + this._probability = value; } /** @@ -163,4 +158,16 @@ export class SkipList { return false; } + + /** + * The function "randomLevel" generates a random level based on a given probability and maximum level. + * @returns the level, which is a number. + */ + private randomLevel(): number { + let level = 1; + while (Math.random() < this.probability && level < this.maxLevel) { + level++; + } + return level; + } } diff --git a/src/data-structures/matrix/matrix2d.ts b/src/data-structures/matrix/matrix2d.ts index 0914d48..f6cfd72 100644 --- a/src/data-structures/matrix/matrix2d.ts +++ b/src/data-structures/matrix/matrix2d.ts @@ -58,16 +58,6 @@ export class Matrix2D { return this._matrix; } - /** - * The function "toVector" returns a new Vector2D object with the values from the first and second elements of the - * _matrix array. - * @returns A new instance of the Vector2D class is being returned. The values of the returned vector are taken from - * the first column of the matrix. - */ - toVector(): Vector2D { - return new Vector2D(this._matrix[0][0], this._matrix[1][0]); - } - /** * The function takes two 2D matrices as input and returns their sum as a new 2D matrix. * @param {Matrix2D} matrix1 - Matrix2D - The first matrix to be added. @@ -208,6 +198,16 @@ export class Matrix2D { [0, 0, vector.w] ]); } + + /** + * The function "toVector" returns a new Vector2D object with the values from the first and second elements of the + * _matrix array. + * @returns A new instance of the Vector2D class is being returned. The values of the returned vector are taken from + * the first column of the matrix. + */ + toVector(): Vector2D { + return new Vector2D(this._matrix[0][0], this._matrix[1][0]); + } } export default Matrix2D; diff --git a/src/data-structures/trie/trie.ts b/src/data-structures/trie/trie.ts index 83f71c7..d5ba4c8 100644 --- a/src/data-structures/trie/trie.ts +++ b/src/data-structures/trie/trie.ts @@ -52,6 +52,8 @@ export class TrieNode { * Trie represents a Trie data structure. It provides basic Trie operations and additional methods. */ export class Trie { + private readonly _caseSensitive: boolean; + constructor(words?: string[], caseSensitive = true) { this._root = new TrieNode(''); this._caseSensitive = caseSensitive; @@ -72,8 +74,6 @@ export class Trie { this._root = v; } - private readonly _caseSensitive: boolean; - /** * Add a word to the Trie structure. * @param {string} word - The word to add. @@ -110,13 +110,6 @@ export class Trie { return cur.isEnd; } - private _caseProcess(str: string) { - if (!this._caseSensitive) { - str = str.toLowerCase(); // Convert str to lowercase if case-insensitive - } - return str; - } - /** * Remove a word from the Trie structure. * @param{string} word - The word to delete. @@ -282,5 +275,12 @@ export class Trie { return words; } + private _caseProcess(str: string) { + if (!this._caseSensitive) { + str = str.toLowerCase(); // Convert str to lowercase if case-insensitive + } + return str; + } + // --- end additional methods --- } diff --git a/src/types/helpers.ts b/src/types/helpers.ts index 35c570b..ca84f77 100644 --- a/src/types/helpers.ts +++ b/src/types/helpers.ts @@ -6,4 +6,8 @@ export type MapCallback = (node: N) => any; export type MapCallbackReturn = ReturnType>; -export enum CP {lt = 'lt', eq = 'eq', gt = 'gt'} +export enum CP { + lt = 'lt', + eq = 'eq', + gt = 'gt' +} diff --git a/test/unit/data-structures/binary-tree/binary-index-tree.test.ts b/test/unit/data-structures/binary-tree/binary-index-tree.test.ts index 1e43598..a11a93e 100644 --- a/test/unit/data-structures/binary-tree/binary-index-tree.test.ts +++ b/test/unit/data-structures/binary-tree/binary-index-tree.test.ts @@ -1,7 +1,7 @@ import {BinaryIndexedTree} from '../../../../src'; import {isDebugTest} from '../../../config'; -const isDebug = isDebugTest; +// const isDebug = isDebugTest; describe('BinaryIndexedTree simple', () => { let bit: BinaryIndexedTree;