diff --git a/package.json b/package.json index 41e8e4f..2d15880 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "lint:test": "eslint --fix 'test/**/*.{js,ts}'", "lint": "npm run lint:src && npm run lint:test", "format:src": "prettier --write 'src/**/*.{js,ts}'", + "format:specific": "prettier --write 'src/data-structures/binary-tree/bst.ts'", "format:test": "prettier --write 'test/**/*.{js,ts}'", "format": "npm run format:src && npm run format:test", "fix:src": "npm run lint:src && npm run format:src", diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts index e1c7bc7..e232497 100644 --- a/src/data-structures/binary-tree/avl-tree.ts +++ b/src/data-structures/binary-tree/avl-tree.ts @@ -10,8 +10,8 @@ import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BinaryT import {MapCallback} from '../../types'; import {IBinaryTree} from '../../interfaces'; -export class AVLTreeNode = AVLTreeNodeNested> extends - BSTNode { +export class AVLTreeNode = AVLTreeNodeNested> extends + BSTNode { height: number; constructor(key: BinaryTreeNodeKey, val?: V) { @@ -20,7 +20,7 @@ export class AVLTreeNode = AVLTre } } -export class AVLTree = AVLTreeNode> extends BST implements IBinaryTree { +export class AVLTree = AVLTreeNode> extends BST implements IBinaryTree{ /** * This is a constructor function for an AVL tree data structure in TypeScript. * @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the @@ -36,12 +36,12 @@ export class AVLTree = AVLTreeNode> extends B * @param {BinaryTreeNodeKey} key - The key parameter is the key value that will be associated with * the new node. It is used to determine the position of the node in the binary search tree. * @param [val] - The parameter `val` is an optional value that can be assigned to the node. It is of - * type `N['val']`, which means it can be any value that is assignable to the `val` property of the + * type `V`, which means it can be any value that is assignable to the `val` property of the * node type `N`. * @returns a new AVLTreeNode object with the specified key and value. */ - override createNode(key: BinaryTreeNodeKey, val?: N['val']): N { - return new AVLTreeNode(key, val) as N; + override createNode(key: BinaryTreeNodeKey, val?: V): N { + return new AVLTreeNode(key, val) as N; } /** @@ -53,7 +53,7 @@ export class AVLTree = AVLTreeNode> extends B * are adding to the binary search tree. * @returns The method is returning the inserted node (`N`), `null`, or `undefined`. */ - override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined { + override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V): N | null | undefined { // TODO support node as a param const inserted = super.add(keyOrNode, val); if (inserted) this._balancePath(inserted); diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index b18e848..5a30edf 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -23,9 +23,9 @@ import {Queue} from '../queue'; /** * Represents a node in a binary tree. * @template V - The type of data stored in the node. - * @template FAMILY - The type of the family relationship in the binary tree. + * @template N - The type of the family relationship in the binary tree. */ -export class BinaryTreeNode = BinaryTreeNodeNested> { +export class BinaryTreeNode = BinaryTreeNode>> { /** * The key associated with the node. */ @@ -39,7 +39,7 @@ export class BinaryTreeNode = /** * The parent node of the current node. */ - parent: FAMILY | null | undefined; + parent: N | null | undefined; /** * Creates a new instance of BinaryTreeNode. @@ -51,42 +51,42 @@ export class BinaryTreeNode = this.val = val; } - private _left: FAMILY | null | undefined; + private _left: N | null | undefined; /** * Get the left child node. */ - get left(): FAMILY | null | undefined { + get left(): N | null | undefined { return this._left; } /** * Set the left child node. - * @param {FAMILY | null | undefined} v - The left child node. + * @param {N | null | undefined} v - The left child node. */ - set left(v: FAMILY | null | undefined) { + set left(v: N | null | undefined) { if (v) { - v.parent = this as unknown as FAMILY; + v.parent = this as unknown as N; } this._left = v; } - private _right: FAMILY | null | undefined; + private _right: N | null | undefined; /** * Get the right child node. */ - get right(): FAMILY | null | undefined { + get right(): N | null | undefined { return this._right; } /** * Set the right child node. - * @param {FAMILY | null | undefined} v - The right child node. + * @param {N | null | undefined} v - The right child node. */ - set right(v: FAMILY | null | undefined) { + set right(v: N | null | undefined) { if (v) { - v.parent = this as unknown as FAMILY; + v.parent = this as unknown as N; } this._right = v; } @@ -96,7 +96,7 @@ export class BinaryTreeNode = * @returns {FamilyPosition} - The family position of the node. */ get familyPosition(): FamilyPosition { - const that = this as unknown as FAMILY; + const that = this as unknown as N; if (!this.parent) { return this.left || this.right ? FamilyPosition.ROOT : FamilyPosition.ISOLATED; } @@ -115,7 +115,7 @@ export class BinaryTreeNode = * Represents a binary tree data structure. * @template N - The type of the binary tree's nodes. */ -export class BinaryTree = BinaryTreeNode> implements IBinaryTree { +export class BinaryTree = BinaryTreeNode> implements IBinaryTree{ /** * Creates a new instance of BinaryTree. * @param {BinaryTreeOptions} [options] - The options for the binary tree. @@ -165,11 +165,11 @@ 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. + * @param {V} 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; + createNode(key: BinaryTreeNodeKey, val?: V): N { + return new BinaryTreeNode(key, val) as N; } /** @@ -191,10 +191,10 @@ export class BinaryTree = BinaryTreeNode> /** * Add a node with the given key and value to the binary tree. * @param {BinaryTreeNodeKey | N | null} keyOrNode - The key or node to add to the binary tree. - * @param {N['val']} val - The value for the new node (optional). + * @param {V} val - The value for the new node (optional). * @returns {N | null | undefined} - The inserted node, or null if nothing was inserted, or undefined if the operation failed. */ - add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined { + add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V): N | null | undefined { const _bfs = (root: N, newNode: N | null): N | undefined | null => { const queue = new Queue([root]); while (queue.size > 0) { @@ -249,12 +249,12 @@ export class BinaryTree = BinaryTreeNode> * values, and adds them to the binary tree. * @param {(BinaryTreeNodeKey | null)[] | (N | null)[]} keysOrNodes - An array of BinaryTreeNodeKey or BinaryTreeNode * objects, or null values. - * @param {N['val'][]} [values] - The `values` parameter is an optional array of values (`N['val'][]`) that corresponds to + * @param {V[]} [values] - The `values` parameter is an optional array of values (`V[]`) that corresponds to * the nodes or node IDs being added. It is used to set the value of each node being added. If `values` is not provided, * the value of the nodes will be `undefined`. * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values. */ - addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], values?: N['val'][]): (N | null | undefined)[] { + addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], values?: V[]): (N | null | undefined)[] { // TODO not sure addMany not be run multi times return keysOrNodes.map((keyOrNode, i) => { if (keyOrNode instanceof BinaryTreeNode) { @@ -274,12 +274,12 @@ export class BinaryTree = BinaryTreeNode> * The `refill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data. * @param {(BinaryTreeNodeKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either * `BinaryTreeNodeKey` or `N` values. - * @param {N[] | Array} [data] - The `data` parameter is an optional array of values that will be assigned to + * @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 `keysOrNodes` * array. Each value in the `data` array will be assigned to the * @returns The method is returning a boolean value. */ - refill(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], data?: N[] | Array): boolean { + refill(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], data?: Array): boolean { this.clear(); return keysOrNodes.length === this.addMany(keysOrNodes, data).length; } diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index 1e632aa..9c2a22d 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -18,13 +18,13 @@ import {BinaryTree, BinaryTreeNode} from './binary-tree'; import {IBinaryTree} from '../../interfaces'; import {Queue} from '../queue'; -export class BSTNode = BSTNodeNested> extends BinaryTreeNode { +export class BSTNode = BSTNodeNested> extends BinaryTreeNode { constructor(key: BinaryTreeNodeKey, val?: V) { super(key, val); } } -export class BST = BSTNode> extends BinaryTree implements IBinaryTree { +export class BST = BSTNode> extends BinaryTree implements IBinaryTree { /** * The constructor function initializes a binary search tree object with an optional comparator * function. @@ -49,8 +49,8 @@ export class BST = BSTNode> extends BinaryTree * represents the value associated with the node in a binary search tree. * @returns a new instance of the BSTNode class with the specified key and value. */ - override createNode(key: BinaryTreeNodeKey, val?: N['val']): N { - return new BSTNode(key, val) as N; + override createNode(key: BinaryTreeNodeKey, val?: V): N { + return new BSTNode(key, val) as N; } /** @@ -63,7 +63,7 @@ export class BST = BSTNode> extends BinaryTree * @returns the inserted node (N) if it was successfully added to the binary search tree. If the node * was not added or if the parameters were invalid, it returns null or undefined. */ - override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined { + override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V): N | null | undefined { // TODO support node as a parameter let inserted: N | null = null; let newNode: N | null = null; @@ -136,7 +136,7 @@ export class BST = BSTNode> extends BinaryTree * represents an array of keys or nodes that need to be added to the binary search tree. It can be an * array of `BinaryTreeNodeKey` or `N` (which represents the node type in the binary search tree) or * `null - * @param {N['val'][]} data - The values of tree nodes + * @param {V[]} data - The values of tree nodes * @param {boolean} isBalanceAdd - If true the nodes will be balance inserted in binary search method. * @param iterationType - The `iterationType` parameter determines the type of iteration to be used. * It can have two possible values: @@ -145,7 +145,7 @@ export class BST = BSTNode> extends BinaryTree override addMany( keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], - data?: N['val'][], + data?: V[], isBalanceAdd = true, iterationType = this.iterationType ): (N | null | undefined)[] { @@ -174,7 +174,7 @@ export class BST = BSTNode> extends BinaryTree } let sortedKeysOrNodes: (number | N | null)[] = [], - sortedData: (N['val'] | undefined)[] | undefined = []; + sortedData: (V | undefined)[] | undefined = []; if (isNodeOrNullTuple(combinedArr)) { sorted = combinedArr.sort((a, b) => a[0].key - b[0].key); @@ -185,7 +185,7 @@ export class BST = BSTNode> extends BinaryTree } sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode); sortedData = sorted.map(([, val]) => val); - const recursive = (arr: (BinaryTreeNodeKey | null | N)[], data?: N['val'][]) => { + const recursive = (arr: (BinaryTreeNodeKey | null | N)[], data?: (V | undefined)[]) => { if (arr.length === 0) return; const mid = Math.floor((arr.length - 1) / 2); diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts index 475f058..b8ef6db 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -2,9 +2,9 @@ import {BinaryTreeNodeKey, RBColor, RBTreeNodeNested, RBTreeOptions} from '../.. import {IBinaryTree} from '../../interfaces'; import {BST, BSTNode} from './bst'; -export class RBTreeNode = RBTreeNodeNested> extends BSTNode< +export class RBTreeNode = RBTreeNodeNested> extends BSTNode< V, - FAMILY + N > { constructor(key: BinaryTreeNodeKey, val?: V) { super(key, val); @@ -22,16 +22,16 @@ export class RBTreeNode = RBTreeNo } } -export class RBTree = RBTreeNode> extends BST implements IBinaryTree { +export class RBTree = RBTreeNode> extends BST implements IBinaryTree { constructor(options?: RBTreeOptions) { super(options); } - override createNode(key: BinaryTreeNodeKey, val?: N['val']): N { + override createNode(key: BinaryTreeNodeKey, val?: V): N { return new RBTreeNode(key, val) as N; } - // override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined { + // override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V): N | null | undefined { // const inserted = super.add(keyOrNode, val); // if (inserted) this._fixInsertViolation(inserted); // return inserted; diff --git a/src/data-structures/binary-tree/tree-multiset.ts b/src/data-structures/binary-tree/tree-multiset.ts index 9dbf025..3cc76f4 100644 --- a/src/data-structures/binary-tree/tree-multiset.ts +++ b/src/data-structures/binary-tree/tree-multiset.ts @@ -12,8 +12,8 @@ import {AVLTree, AVLTreeNode} from './avl-tree'; export class TreeMultisetNode< V = any, - FAMILY extends TreeMultisetNode = TreeMultisetNodeNested -> extends AVLTreeNode { + N extends TreeMultisetNode = TreeMultisetNodeNested +> extends AVLTreeNode { count: number; /** @@ -35,9 +35,9 @@ export class TreeMultisetNode< /** * The only distinction between a TreeMultiset and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters. */ -export class TreeMultiset = TreeMultisetNode> - extends AVLTree - implements IBinaryTree { +export class TreeMultiset = TreeMultisetNode> + extends AVLTree + implements IBinaryTree { /** * The constructor function for a TreeMultiset class in TypeScript, which extends another class and sets an option to * merge duplicated values. @@ -63,7 +63,7 @@ export class TreeMultiset = TreeMultiset * occurrences of the value in the binary search tree node. If not provided, the count will default to 1. * @returns A new instance of the BSTNode class with the specified key, value, and count (if provided). */ - override createNode(key: BinaryTreeNodeKey, val?: N['val'], count?: number): N { + override createNode(key: BinaryTreeNodeKey, val?: V, count?: number): N { return new TreeMultisetNode(key, val, count) as N; } @@ -80,7 +80,7 @@ export class TreeMultiset = TreeMultiset * count is specified, the default count will be 1. * @returns The function `add` returns a value of type `N | null | undefined`. */ - override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val'], count = 1): N | null | undefined { + override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V, count = 1): N | null | undefined { let inserted: N | null | undefined = undefined, newNode: N | null; if (keyOrNode instanceof TreeMultisetNode) { @@ -186,14 +186,14 @@ export class TreeMultiset = TreeMultiset * inserted nodes. * @param {(BinaryTreeNodeKey | null)[] | (N | null)[]} keysOrNodes - An array of keys or nodes to be * added to the multiset. Each element can be either a BinaryTreeNodeKey or a TreeMultisetNode. - * @param {N['val'][]} [data] - The `data` parameter is an optional array of values that correspond + * @param {V[]} [data] - The `data` parameter is an optional array of values that correspond * to the keys or nodes being added to the multiset. It is used to associate additional data with * each key or node. * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values. */ override addMany( keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], - data?: N['val'][] + data?: V[] ): (N | null | undefined)[] { const inserted: (N | null | undefined)[] = []; @@ -206,7 +206,7 @@ export class TreeMultiset = TreeMultiset } if (keyOrNode === null) { - inserted.push(this.add(NaN, null, 0)); + inserted.push(this.add(NaN, undefined, 0)); continue; } diff --git a/src/interfaces/binary-tree.ts b/src/interfaces/binary-tree.ts index a499659..61afbfd 100644 --- a/src/interfaces/binary-tree.ts +++ b/src/interfaces/binary-tree.ts @@ -1,7 +1,7 @@ import {BinaryTreeNode} from '../data-structures'; -import {BinaryTreeDeletedResult, BinaryTreeNodeKey, MapCallback} from '../types'; +import {BinaryTreeDeletedResult, BinaryTreeNodeKey, BinaryTreeNodeNested, MapCallback} from '../types'; -export interface IBinaryTree> { +export interface IBinaryTree = BinaryTreeNodeNested> { createNode(key: BinaryTreeNodeKey, val?: N['val']): N; add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined; diff --git a/test/unit/data-structures/binary-tree/avl-tree.test.ts b/test/unit/data-structures/binary-tree/avl-tree.test.ts index 1bd8174..01c0e16 100644 --- a/test/unit/data-structures/binary-tree/avl-tree.test.ts +++ b/test/unit/data-structures/binary-tree/avl-tree.test.ts @@ -3,7 +3,7 @@ import {AVLTree, AVLTreeNode, CP} from '../../../../src'; describe('AVL Tree Test', () => { it('should perform various operations on a AVL Tree', () => { const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]; - const tree = new AVLTree>(); + const tree = new AVLTree(); for (const i of arr) tree.add(i, i); @@ -110,7 +110,7 @@ describe('AVL Tree Test', () => { }); describe('AVLTree APIs test', () => { - const avl = new AVLTree>(); + const avl = new AVLTree<{id: number; text: string}>(); beforeEach(() => { avl.clear(); }); diff --git a/test/unit/data-structures/binary-tree/binary-tree.test.ts b/test/unit/data-structures/binary-tree/binary-tree.test.ts index fcb5f4e..49d87d8 100644 --- a/test/unit/data-structures/binary-tree/binary-tree.test.ts +++ b/test/unit/data-structures/binary-tree/binary-tree.test.ts @@ -196,7 +196,7 @@ describe('BinaryTree Morris Traversal', () => { }); describe('BinaryTree APIs test', () => { - const avl = new AVLTree>(); + const avl = new AVLTree<{id: number; text: string}>(); beforeEach(() => { avl.clear(); }); diff --git a/test/unit/data-structures/binary-tree/bst.test.ts b/test/unit/data-structures/binary-tree/bst.test.ts index 9683af9..872223f 100644 --- a/test/unit/data-structures/binary-tree/bst.test.ts +++ b/test/unit/data-structures/binary-tree/bst.test.ts @@ -189,7 +189,7 @@ describe('BST operations test', () => { }); it('should perform various operations on a Binary Search Tree with object values', () => { - const objBST = new BST>(); + const objBST = new BST<{key: number; keyA: number}>(); expect(objBST).toBeInstanceOf(BST); objBST.add(11, {key: 11, keyA: 11}); objBST.add(3, {key: 3, keyA: 3}); diff --git a/test/unit/data-structures/binary-tree/overall.test.ts b/test/unit/data-structures/binary-tree/overall.test.ts index 5325180..e4301b1 100644 --- a/test/unit/data-structures/binary-tree/overall.test.ts +++ b/test/unit/data-structures/binary-tree/overall.test.ts @@ -29,7 +29,7 @@ describe('Overall BinaryTree Test', () => { bfsIDs[0] === 11; // true expect(bfsIDs[0]).toBe(11); - const objBST = new BST>(); + const objBST = new BST<{key: number; keyA: number}>(); objBST.add(11, {key: 11, keyA: 11}); objBST.add(3, {key: 3, keyA: 3}); diff --git a/test/unit/data-structures/binary-tree/tree-multiset.test.ts b/test/unit/data-structures/binary-tree/tree-multiset.test.ts index e0f7125..795ce47 100644 --- a/test/unit/data-structures/binary-tree/tree-multiset.test.ts +++ b/test/unit/data-structures/binary-tree/tree-multiset.test.ts @@ -206,7 +206,7 @@ describe('TreeMultiset operations test', () => { }); it('should perform various operations on a Binary Search Tree with object values', () => { - const objTreeMultiset = new TreeMultiset>(); + const objTreeMultiset = new TreeMultiset<{key: number; keyA: number}>(); expect(objTreeMultiset).toBeInstanceOf(TreeMultiset); objTreeMultiset.add(11, {key: 11, keyA: 11}); objTreeMultiset.add(3, {key: 3, keyA: 3});