diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts index 17d74df..1464d04 100644 --- a/src/data-structures/binary-tree/avl-tree.ts +++ b/src/data-structures/binary-tree/avl-tree.ts @@ -7,7 +7,7 @@ */ import { BST, BSTNode } from './bst'; import type { AVLTreeNested, AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey } from '../../types'; -import { BTNCallback, IterationType } from '../../types'; +import { BTNCallback, IterableEntriesOrKeys } from '../../types'; import { IBinaryTree } from '../../interfaces'; export class AVLTreeNode = AVLTreeNodeNested> extends BSTNode { @@ -23,21 +23,15 @@ export class AVLTree = AVLTreeNode implements IBinaryTree { - override options: AVLTreeOptions; - /** * 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 * constructor of the AVLTree class. It allows you to customize the behavior of the AVL tree by providing different * options. */ - constructor(options?: AVLTreeOptions) { - super(options); - if (options) { - this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options } - } else { - this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b }; - } + constructor(elements?: IterableEntriesOrKeys, options?: Partial) { + super([], options); + if (elements) this.init(elements); } /** @@ -54,14 +48,12 @@ export class AVLTree = AVLTreeNode({ ...this.options, ...options }) as TREE; + return new AVLTree([], { + iterationType: this.iterationType, + comparator: this.comparator, ...options + }) as TREE; } - /** - * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity. - * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. - */ - /** * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity. * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. @@ -82,7 +74,7 @@ export class AVLTree = AVLTreeNode = AVLTreeNode): void { + if (elements) { + for (const entryOrKey of elements) { + if (Array.isArray(entryOrKey)) { + const [key, value] = entryOrKey; + this.add(key, value); + } else { + this.add(entryOrKey); + } + } + } + } + /** * The `_swap` function swaps the key, value, and height properties between two nodes in a binary * tree. diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index bac7644..909f7ed 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -13,6 +13,7 @@ import { BiTreeDeleteResult, DFSOrderPattern, FamilyPosition, + IterableEntriesOrKeys, IterationType, NodeDisplayLayout } from '../../types'; @@ -118,20 +119,24 @@ export class BinaryTreeNode = BinaryTree export class BinaryTree = BinaryTreeNode>, TREE extends BinaryTree = BinaryTree>> implements IBinaryTree { - options: BinaryTreeOptions; + iterationType = IterationType.ITERATIVE /** * Creates a new instance of BinaryTree. * @param {BinaryTreeOptions} [options] - The options for the binary tree. */ - constructor(options?: BinaryTreeOptions) { + constructor(elements?: IterableEntriesOrKeys, options?: Partial) { + if (options) { - this.options = { iterationType: IterationType.ITERATIVE, ...options } - } else { - this.options = { iterationType: IterationType.ITERATIVE }; + const { iterationType } = options; + if (iterationType) { + this.iterationType = iterationType; + } } this._size = 0; + + if (elements) this.init(elements); } protected _root?: N | null; @@ -162,16 +167,10 @@ export class BinaryTree = BinaryTreeNode return new BinaryTreeNode(key, value) as N; } - createTree(options?: BinaryTreeOptions): TREE { - return new BinaryTree({ ...this.options, ...options }) as TREE; + createTree(options?: Partial): TREE { + return new BinaryTree([], { iterationType: this.iterationType, ...options }) as TREE; } - /** - * Time Complexity: O(n) - * Space Complexity: O(1) - * Comments: The time complexity for adding a node depends on the depth of the tree. In the best case (when the tree is empty), it's O(1). In the worst case (when the tree is a degenerate tree), it's O(n). The space complexity is constant. - */ - /** * Time Complexity: O(n) * Space Complexity: O(1) @@ -228,8 +227,9 @@ export class BinaryTree = BinaryTreeNode } /** - * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted. + * Time Complexity: O(n) * Space Complexity: O(1) + * Comments: The time complexity for adding a node depends on the depth of the tree. In the best case (when the tree is empty), it's O(1). In the worst case (when the tree is a degenerate tree), it's O(n). The space complexity is constant. */ /** @@ -284,17 +284,17 @@ export class BinaryTree = BinaryTreeNode return keysOrNodes.length === this.addMany(keysOrNodes, values).length; } + /** + * Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted. + * Space Complexity: O(1) + */ + delete>(identifier: BTNKey, callback?: C): BiTreeDeleteResult[]; delete>(identifier: N | null | undefined, callback?: C): BiTreeDeleteResult[]; delete>(identifier: ReturnType, callback: C): BiTreeDeleteResult[]; - /** - * Time Complexity: O(n) - * Space Complexity: O(1) - */ - /** * Time Complexity: O(n) * Space Complexity: O(1) @@ -394,8 +394,7 @@ export class BinaryTree = BinaryTreeNode /** * Time Complexity: O(n) - * Space Complexity: O(log n) - * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType) + * Space Complexity: O(1) */ /** @@ -412,7 +411,7 @@ export class BinaryTree = BinaryTreeNode * values: * @returns the height of the binary tree. */ - getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.options.iterationType): number { + getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number { beginRoot = this.ensureNotKey(beginRoot); if (!beginRoot) return -1; @@ -461,7 +460,7 @@ export class BinaryTree = BinaryTreeNode * to calculate the minimum height of a binary tree. It can have two possible values: * @returns The function `getMinHeight` returns the minimum height of a binary tree. */ - getMinHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.options.iterationType): number { + getMinHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number { beginRoot = this.ensureNotKey(beginRoot); if (!beginRoot) return -1; @@ -507,6 +506,7 @@ export class BinaryTree = BinaryTreeNode /** * Time Complexity: O(n) * Space Complexity: O(log n) + * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType) */ /** @@ -524,6 +524,11 @@ export class BinaryTree = BinaryTreeNode return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot); } + /** + * Time Complexity: O(n) + * Space Complexity: O(log n) + */ + getNodes>( identifier: BTNKey, callback?: C, @@ -548,11 +553,6 @@ export class BinaryTree = BinaryTreeNode iterationType?: IterationType ): N[]; - /** - * Time Complexity: O(n) - * Space Complexity: O(log n). - */ - /** * Time Complexity: O(n) * Space Complexity: O(log n). @@ -583,7 +583,7 @@ export class BinaryTree = BinaryTreeNode callback: C = this._defaultOneParamCallback as C, onlyOne = false, beginRoot: BTNKey | N | null | undefined = this.root, - iterationType = this.options.iterationType + iterationType = this.iterationType ): N[] { if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C; @@ -622,6 +622,11 @@ export class BinaryTree = BinaryTreeNode return ans; } + /** + * Time Complexity: O(n) + * Space Complexity: O(log n). + */ + has>( identifier: BTNKey, callback?: C, @@ -643,11 +648,6 @@ export class BinaryTree = BinaryTreeNode iterationType?: IterationType ): boolean; - /** - * Time Complexity: O(n) - * Space Complexity: O(log n). - */ - /** * Time Complexity: O(n) * @@ -672,7 +672,7 @@ export class BinaryTree = BinaryTreeNode identifier: ReturnType | null | undefined, callback: C = this._defaultOneParamCallback as C, beginRoot: BTNKey | N | null | undefined = this.root, - iterationType = this.options.iterationType + iterationType = this.iterationType ): boolean { if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C; @@ -680,6 +680,11 @@ export class BinaryTree = BinaryTreeNode return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0; } + /** + * Time Complexity: O(n) + * Space Complexity: O(log n). + */ + getNode>( identifier: BTNKey, callback?: C, @@ -701,11 +706,6 @@ export class BinaryTree = BinaryTreeNode iterationType?: IterationType ): N | null | undefined; - /** - * Time Complexity: O(n) - * Space Complexity: O(log n) - */ - /** * Time Complexity: O(n) * Space Complexity: O(log n) @@ -731,7 +731,7 @@ export class BinaryTree = BinaryTreeNode identifier: ReturnType | null | undefined, callback: C = this._defaultOneParamCallback as C, beginRoot: BTNKey | N | null | undefined = this.root, - iterationType = this.options.iterationType + iterationType = this.iterationType ): N | null | undefined { if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C; @@ -783,6 +783,11 @@ export class BinaryTree = BinaryTreeNode } } + /** + * Time Complexity: O(n) + * Space Complexity: O(log n) + */ + /** * The function `ensureNotKey` returns the node corresponding to the given key if it is a valid node * key, otherwise it returns the key itself. @@ -819,11 +824,6 @@ export class BinaryTree = BinaryTreeNode iterationType?: IterationType ): V | undefined; - /** - * Time Complexity: O(n) - * Space Complexity: O(log n) - */ - /** * Time Complexity: O(n) * Space Complexity: O(log n) @@ -850,7 +850,7 @@ export class BinaryTree = BinaryTreeNode identifier: ReturnType | null | undefined, callback: C = this._defaultOneParamCallback as C, beginRoot: BTNKey | N | null | undefined = this.root, - iterationType = this.options.iterationType + iterationType = this.iterationType ): V | undefined { if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C; @@ -858,6 +858,11 @@ export class BinaryTree = BinaryTreeNode return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined; } + /** + * Time Complexity: O(n) + * Space Complexity: O(log n) + */ + /** * Clear the binary tree, removing all nodes. */ @@ -874,11 +879,6 @@ export class BinaryTree = BinaryTreeNode return this.size === 0; } - /** - * Time Complexity: O(log n) - * Space Complexity: O(log n) - */ - /** * Time Complexity: O(log n) * Space Complexity: O(log n) @@ -912,7 +912,7 @@ export class BinaryTree = BinaryTreeNode /** * Time Complexity: O(log n) - * Space Complexity: O(1) + * Space Complexity: O(log n) */ /** @@ -931,7 +931,7 @@ export class BinaryTree = BinaryTreeNode */ getLeftMost( beginRoot: BTNKey | N | null | undefined = this.root, - iterationType = this.options.iterationType + iterationType = this.iterationType ): N | null | undefined { beginRoot = this.ensureNotKey(beginRoot); @@ -977,7 +977,7 @@ export class BinaryTree = BinaryTreeNode */ getRightMost( beginRoot: BTNKey | N | null | undefined = this.root, - iterationType = this.options.iterationType + iterationType = this.iterationType ): N | null | undefined { // TODO support get right most by passing key in beginRoot = this.ensureNotKey(beginRoot); @@ -1002,7 +1002,7 @@ export class BinaryTree = BinaryTreeNode } /** - * Time Complexity: O(n) + * Time Complexity: O(log n) * Space Complexity: O(1) */ @@ -1018,7 +1018,7 @@ export class BinaryTree = BinaryTreeNode * possible values: * @returns a boolean value. */ - isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType = this.options.iterationType): boolean { + isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType = this.iterationType): boolean { // TODO there is a bug beginRoot = this.ensureNotKey(beginRoot); if (!beginRoot) return true; @@ -1065,11 +1065,16 @@ export class BinaryTree = BinaryTreeNode * expected to be * @returns a boolean value. */ - isBST(iterationType = this.options.iterationType): boolean { + isBST(iterationType = this.iterationType): boolean { if (this.root === null) return true; return this.isSubtreeBST(this.root, iterationType); } + /** + * Time Complexity: O(n) + * Space Complexity: O(1) + */ + subTreeTraverse>( callback?: C, beginRoot?: BTNKey | N | null | undefined, @@ -1091,11 +1096,6 @@ export class BinaryTree = BinaryTreeNode includeNull?: true ): ReturnType[]; - /** - * Time complexity: O(n) - * Space complexity: O(log n) - */ - /** * Time complexity: O(n) * Space complexity: O(log n) @@ -1121,7 +1121,7 @@ export class BinaryTree = BinaryTreeNode subTreeTraverse>( callback: C = this._defaultOneParamCallback as C, beginRoot: BTNKey | N | null | undefined = this.root, - iterationType = this.options.iterationType, + iterationType = this.iterationType, includeNull = false ): ReturnType[] { beginRoot = this.ensureNotKey(beginRoot); @@ -1164,6 +1164,11 @@ export class BinaryTree = BinaryTreeNode return ans; } + /** + * Time complexity: O(n) + * Space complexity: O(log n) + */ + /** * The function checks if a given node is a real node by verifying if it is an instance of * BinaryTreeNode and its key is not NaN. @@ -1226,11 +1231,6 @@ export class BinaryTree = BinaryTreeNode includeNull?: true ): ReturnType[]; - /** - * Time complexity: O(n) - * Space complexity: O(n) - */ - /** * Time complexity: O(n) * Space complexity: O(n) @@ -1349,6 +1349,11 @@ export class BinaryTree = BinaryTreeNode return ans; } + /** + * Time complexity: O(n) + * Space complexity: O(n) + */ + bfs>( callback?: C, beginRoot?: BTNKey | N | null | undefined, @@ -1370,11 +1375,6 @@ export class BinaryTree = BinaryTreeNode includeNull?: true ): ReturnType[]; - /** - * Time complexity: O(n) - * Space complexity: O(n) - */ - /** * Time complexity: O(n) * Space complexity: O(n) @@ -1399,7 +1399,7 @@ export class BinaryTree = BinaryTreeNode bfs>( callback: C = this._defaultOneParamCallback as C, beginRoot: BTNKey | N | null | undefined = this.root, - iterationType = this.options.iterationType, + iterationType = this.iterationType, includeNull = false ): ReturnType[] { beginRoot = this.ensureNotKey(beginRoot); @@ -1450,6 +1450,11 @@ export class BinaryTree = BinaryTreeNode return ans; } + /** + * Time complexity: O(n) + * Space complexity: O(n) + */ + listLevels>( callback?: C, beginRoot?: BTNKey | N | null | undefined, @@ -1471,11 +1476,6 @@ export class BinaryTree = BinaryTreeNode includeNull?: true ): ReturnType[][]; - /** - * Time complexity: O(n) - * Space complexity: O(n) - */ - /** * Time complexity: O(n) * Space complexity: O(n) @@ -1500,7 +1500,7 @@ export class BinaryTree = BinaryTreeNode listLevels>( callback: C = this._defaultOneParamCallback as C, beginRoot: BTNKey | N | null | undefined = this.root, - iterationType = this.options.iterationType, + iterationType = this.iterationType, includeNull = false ): ReturnType[][] { beginRoot = this.ensureNotKey(beginRoot); @@ -1544,6 +1544,11 @@ export class BinaryTree = BinaryTreeNode return levelsNodes; } + /** + * Time complexity: O(n) + * Space complexity: O(n) + */ + getPredecessor(node: N): N; /** @@ -1591,11 +1596,6 @@ export class BinaryTree = BinaryTreeNode return y; } - /** - * Time complexity: O(n) - * Space complexity: O(1) - */ - /** * Time complexity: O(n) * Space complexity: O(1) @@ -1700,6 +1700,11 @@ export class BinaryTree = BinaryTreeNode return ans; } + /** + * Time complexity: O(n) + * Space complexity: O(1) + */ + /** * The `forEach` function iterates over each entry in a tree and calls a callback function with the * entry and the tree as arguments. @@ -1730,15 +1735,6 @@ export class BinaryTree = BinaryTreeNode return newTree; } - // TODO Type error, need to return a TREE that is a value type only for callback function. - // map(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) { - // const newTree = this.createTree(); - // for (const [key, value] of this) { - // newTree.add(key, callback([key, value], this)); - // } - // return newTree; - // } - /** * The `map` function creates a new tree by applying a callback function to each entry in the current * tree. @@ -1753,6 +1749,15 @@ export class BinaryTree = BinaryTreeNode return newTree; } + // TODO Type error, need to return a TREE that is a value type only for callback function. + // map(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) { + // const newTree = this.createTree(); + // for (const [key, value] of this) { + // newTree.add(key, callback([key, value], this)); + // } + // return newTree; + // } + /** * The `reduce` function iterates over the entries of a tree and applies a callback function to each * entry, accumulating a single value. @@ -1773,7 +1778,6 @@ export class BinaryTree = BinaryTreeNode return accumulator; } - /** * The above function is an iterator for a binary tree that can be used to traverse the tree in * either an iterative or recursive manner. @@ -1786,7 +1790,7 @@ export class BinaryTree = BinaryTreeNode * [Symbol.iterator](node = this.root): Generator<[BTNKey, V | undefined], void, undefined> { if (!node) return; - if (this.options.iterationType === IterationType.ITERATIVE) { + if (this.iterationType === IterationType.ITERATIVE) { const stack: (N | null | undefined)[] = []; let current: N | null | undefined = node; @@ -1843,6 +1847,19 @@ export class BinaryTree = BinaryTreeNode display(beginRoot); } + init(elements: IterableEntriesOrKeys): void { + if (elements) { + for (const entryOrKey of elements) { + if (Array.isArray(entryOrKey)) { + const [key, value] = entryOrKey; + this.add(key, value); + } else { + this.add(entryOrKey); + } + } + } + } + protected _displayAux(node: N | null | undefined, options: BinaryTreePrintOptions): NodeDisplayLayout { const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options; const emptyDisplayLayout = [['─'], 1, 0, 0]; diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index e54f72e..30f4d96 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -5,8 +5,8 @@ * @copyright Copyright (c) 2022 Tyler Zeng * @license MIT License */ -import type { BSTNested, BSTNodeNested, BSTOptions, BTNCallback, BTNKey } from '../../types'; -import { CP, IterationType } from '../../types'; +import type { BSTNested, BSTNodeNested, BSTOptions, BTNCallback, BTNKey, Comparator } from '../../types'; +import { CP, IterableEntriesOrKeys, IterationType } from '../../types'; import { BinaryTree, BinaryTreeNode } from './binary-tree'; import { IBinaryTree } from '../../interfaces'; import { Queue } from '../queue'; @@ -66,21 +66,23 @@ export class BST = BSTNode> extends BinaryTree implements IBinaryTree { - override options: BSTOptions; - /** * The constructor function initializes a binary search tree with an optional comparator function. * @param {BSTOptions} [options] - An optional object that contains additional configuration options * for the binary search tree. */ - constructor(options?: BSTOptions) { - super(options); + constructor(elements?: IterableEntriesOrKeys, options?: Partial) { + super([], options); + if (options) { - this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options } - } else { - this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b }; + const { comparator } = options; + if (comparator) { + this.comparator = comparator; + } } + this._root = undefined; + if (elements) this.init(elements); } protected override _root?: N; @@ -92,6 +94,8 @@ export class BST = BSTNode> return this._root; } + comparator: Comparator = (a, b) => a - b + /** * The function creates a new binary search tree node with the given key and value. * @param {BTNKey} key - The key parameter is the key value that will be associated with @@ -104,15 +108,13 @@ export class BST = BSTNode> return new BSTNode(key, value) as N; } - override createTree(options?: BSTOptions): TREE { - return new BST({ ...this.options, ...options }) as TREE; + override createTree(options?: Partial): TREE { + return new BST([], { + iterationType: this.iterationType, + comparator: this.comparator, ...options + }) as TREE; } - /** - * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n). - * Space Complexity: O(1) - Constant space is used. - */ - /** * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n). * Space Complexity: O(1) - Constant space is used. @@ -193,8 +195,8 @@ export class BST = BSTNode> } /** - * Time Complexity: O(n log n) - Adding each element individually in a balanced tree. - * Space Complexity: O(n) - Additional space is required for the sorted array. + * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n). + * Space Complexity: O(1) - Constant space is used. */ /** @@ -221,7 +223,7 @@ export class BST = BSTNode> keysOrNodes: (BTNKey | N | undefined)[], data?: (V | undefined)[], isBalanceAdd = true, - iterationType = this.options.iterationType + iterationType = this.iterationType ): (N | undefined)[] { // TODO this addMany function is inefficient, it should be optimized function hasNoUndefined(arr: (BTNKey | N | undefined)[]): arr is (BTNKey | N)[] { @@ -297,8 +299,8 @@ export class BST = BSTNode> } /** - * Time Complexity: O(log n) - Average case for a balanced tree. - * Space Complexity: O(1) - Constant space is used. + * Time Complexity: O(n log n) - Adding each element individually in a balanced tree. + * Space Complexity: O(n) - Additional space is required for the sorted array. */ /** @@ -316,7 +318,7 @@ export class BST = BSTNode> * the key of the leftmost node if the comparison result is greater than, and the key of the * rightmost node otherwise. If no node is found, it returns 0. */ - lastKey(beginRoot: BTNKey | N | undefined = this.root, iterationType = this.options.iterationType): BTNKey { + lastKey(beginRoot: BTNKey | N | undefined = this.root, iterationType = this.iterationType): BTNKey { if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0; else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0; else return this.getRightMost(beginRoot, iterationType)?.key ?? 0; @@ -324,7 +326,7 @@ export class BST = BSTNode> /** * Time Complexity: O(log n) - Average case for a balanced tree. - * Space Complexity: O(log n) - Space for the recursive call stack in the worst case. + * Space Complexity: O(1) - Constant space is used. */ /** @@ -366,6 +368,11 @@ export class BST = BSTNode> } } + /** + * Time Complexity: O(log n) - Average case for a balanced tree. + * Space Complexity: O(log n) - Space for the recursive call stack in the worst case. + */ + /** * The function `ensureNotKey` returns the node corresponding to the given key if it is a node key, * otherwise it returns the key itself. @@ -379,11 +386,6 @@ export class BST = BSTNode> return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key; } - /** - * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key. - * Space Complexity: O(log n) - Space for the recursive call stack in the worst case. - */ - /** * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key. * Space Complexity: O(log n) - Space for the recursive call stack in the worst case. @@ -412,7 +414,7 @@ export class BST = BSTNode> callback: C = this._defaultOneParamCallback as C, onlyOne = false, beginRoot: BTNKey | N | undefined = this.root, - iterationType = this.options.iterationType + iterationType = this.iterationType ): N[] { beginRoot = this.ensureNotKey(beginRoot); if (!beginRoot) return []; @@ -493,7 +495,7 @@ export class BST = BSTNode> callback: C = this._defaultOneParamCallback as C, lesserOrGreater: CP = CP.lt, targetNode: BTNKey | N | undefined = this.root, - iterationType = this.options.iterationType + iterationType = this.iterationType ): ReturnType[] { targetNode = this.ensureNotKey(targetNode); const ans: ReturnType>[] = []; @@ -531,18 +533,8 @@ export class BST = BSTNode> } /** - * Balancing Adjustment: - * Perfectly Balanced Binary Tree: Since the balance of a perfectly balanced binary tree is already fixed, no additional balancing adjustment is needed. Any insertion or deletion operation will disrupt the perfect balance, often requiring a complete reconstruction of the tree. - * AVL Tree: After insertion or deletion operations, an AVL tree performs rotation adjustments based on the balance factor of nodes to restore the tree's balance. These rotations can be left rotations, right rotations, left-right rotations, or right-left rotations, performed as needed. - * - * Use Cases and Efficiency: - * Perfectly Balanced Binary Tree: Perfectly balanced binary trees are typically used in specific scenarios such as complete binary heaps in heap sort or certain types of Huffman trees. However, they are not suitable for dynamic operations requiring frequent insertions and deletions, as these operations often necessitate full tree reconstruction. - * AVL Tree: AVL trees are well-suited for scenarios involving frequent searching, insertion, and deletion operations. Through rotation adjustments, AVL trees maintain their balance, ensuring average and worst-case time complexity of O(log n). - */ - - /** - * Time Complexity: O(n) - Building a balanced tree from a sorted array. - * Space Complexity: O(n) - Additional space is required for the sorted array. + * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key. + * Space Complexity: O(log n) - Space for the recursive call stack in the worst case. */ /** @@ -556,7 +548,7 @@ export class BST = BSTNode> * values: * @returns The function `perfectlyBalance` returns a boolean value. */ - perfectlyBalance(iterationType = this.options.iterationType): boolean { + perfectlyBalance(iterationType = this.iterationType): boolean { const sorted = this.dfs(node => node, 'in'), n = sorted.length; this.clear(); @@ -595,8 +587,18 @@ export class BST = BSTNode> } /** - * Time Complexity: O(n) - Visiting each node once. - * Space Complexity: O(log n) - Space for the recursive call stack in the worst case. + * Balancing Adjustment: + * Perfectly Balanced Binary Tree: Since the balance of a perfectly balanced binary tree is already fixed, no additional balancing adjustment is needed. Any insertion or deletion operation will disrupt the perfect balance, often requiring a complete reconstruction of the tree. + * AVL Tree: After insertion or deletion operations, an AVL tree performs rotation adjustments based on the balance factor of nodes to restore the tree's balance. These rotations can be left rotations, right rotations, left-right rotations, or right-left rotations, performed as needed. + * + * Use Cases and Efficiency: + * Perfectly Balanced Binary Tree: Perfectly balanced binary trees are typically used in specific scenarios such as complete binary heaps in heap sort or certain types of Huffman trees. However, they are not suitable for dynamic operations requiring frequent insertions and deletions, as these operations often necessitate full tree reconstruction. + * AVL Tree: AVL trees are well-suited for scenarios involving frequent searching, insertion, and deletion operations. Through rotation adjustments, AVL trees maintain their balance, ensuring average and worst-case time complexity of O(log n). + */ + + /** + * Time Complexity: O(n) - Building a balanced tree from a sorted array. + * Space Complexity: O(n) - Additional space is required for the sorted array. */ /** @@ -608,7 +610,7 @@ export class BST = BSTNode> * to check if the AVL tree is balanced. It can have two possible values: * @returns a boolean value. */ - isAVLBalanced(iterationType = this.options.iterationType): boolean { + isAVLBalanced(iterationType = this.iterationType): boolean { if (!this.root) return true; let balanced = true; @@ -652,6 +654,24 @@ export class BST = BSTNode> return balanced; } + /** + * Time Complexity: O(n) - Visiting each node once. + * Space Complexity: O(log n) - Space for the recursive call stack in the worst case. + */ + + init(elements: IterableEntriesOrKeys): void { + if (elements) { + for (const entryOrKey of elements) { + if (Array.isArray(entryOrKey)) { + const [key, value] = entryOrKey; + this.add(key, value); + } else { + this.add(entryOrKey); + } + } + } + } + protected _setRoot(v: N | undefined) { if (v) { v.parent = undefined; @@ -668,7 +688,7 @@ export class BST = BSTNode> * than), CP.lt (less than), or CP.eq (equal). */ protected _compare(a: BTNKey, b: BTNKey): CP { - const compared = this.options.comparator!(a, b); + const compared = this.comparator(a, b); if (compared > 0) return CP.gt; else if (compared < 0) return CP.lt; else return CP.eq; diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts index b3f30f1..8ccf2b4 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -10,6 +10,7 @@ import { BiTreeDeleteResult, BTNCallback, BTNKey, + IterableEntriesOrKeys, IterationType, RBTNColor, RBTreeOptions, @@ -43,21 +44,18 @@ export class RedBlackTree = RedBlackTr extends BST implements IBinaryTree { Sentinel: N = new RedBlackTreeNode(NaN) as unknown as N; - override options: RBTreeOptions; + /** * The constructor function initializes a Red-Black Tree with an optional set of options. * @param {RBTreeOptions} [options] - The `options` parameter is an optional object that can be * passed to the constructor. It is used to configure the RBTree object with specific options. */ - constructor(options?: RBTreeOptions) { - super(options); - if (options) { - this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options } - } else { - this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b }; - } + constructor(elements?: IterableEntriesOrKeys, options?: Partial) { + super([], options); + this._root = this.Sentinel; + if (elements) this.init(elements); } protected _root: N; @@ -77,14 +75,12 @@ export class RedBlackTree = RedBlackTr } override createTree(options?: RBTreeOptions): TREE { - return new RedBlackTree({ ...this.options, ...options }) as TREE; + return new RedBlackTree([], { + iterationType: this.iterationType, + comparator: this.comparator, ...options + }) as TREE; } - /** - * Time Complexity: O(log n) on average (where n is the number of nodes in the tree) - * Space Complexity: O(1) - */ - /** * Time Complexity: O(log n) on average (where n is the number of nodes in the tree) * Space Complexity: O(1) @@ -235,6 +231,11 @@ export class RedBlackTree = RedBlackTr return ans; } + /** + * Time Complexity: O(log n) on average (where n is the number of nodes in the tree) + * Space Complexity: O(1) + */ + override isRealNode(node: N | undefined): node is N { return node !== this.Sentinel && node !== undefined; } @@ -260,11 +261,6 @@ export class RedBlackTree = RedBlackTr iterationType?: IterationType ): N | undefined; - /** - * Time Complexity: O(log n) on average (where n is the number of nodes in the tree) - * Space Complexity: O(1) - */ - /** * Time Complexity: O(log n) on average (where n is the number of nodes in the tree) * Space Complexity: O(1) @@ -290,7 +286,7 @@ export class RedBlackTree = RedBlackTr identifier: ReturnType | undefined, callback: C = this._defaultOneParamCallback as C, beginRoot: BTNKey | N | undefined = this.root, - iterationType = this.options.iterationType + iterationType = this.iterationType ): N | null | undefined { if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C; beginRoot = this.ensureNotKey(beginRoot); @@ -351,11 +347,29 @@ export class RedBlackTree = RedBlackTr return y!; } + /** + * Time Complexity: O(log n) on average (where n is the number of nodes in the tree) + * Space Complexity: O(1) + */ + override clear() { this._root = this.Sentinel; this._size = 0; } + init(elements: IterableEntriesOrKeys): void { + if (elements) { + for (const entryOrKey of elements) { + if (Array.isArray(entryOrKey)) { + const [key, value] = entryOrKey; + this.add(key, value); + } else { + this.add(entryOrKey); + } + } + } + } + protected override _setRoot(v: N) { if (v) { v.parent = undefined; diff --git a/src/data-structures/binary-tree/tree-multimap.ts b/src/data-structures/binary-tree/tree-multimap.ts index 68e0387..7e93faa 100644 --- a/src/data-structures/binary-tree/tree-multimap.ts +++ b/src/data-structures/binary-tree/tree-multimap.ts @@ -6,7 +6,15 @@ * @license MIT License */ import type { BTNKey, TreeMultimapNodeNested, TreeMultimapOptions } from '../../types'; -import { BiTreeDeleteResult, BTNCallback, CP, FamilyPosition, IterationType, TreeMultimapNested } from '../../types'; +import { + BiTreeDeleteResult, + BTNCallback, + CP, + FamilyPosition, + IterableEntriesOrKeys, + IterationType, + TreeMultimapNested +} from '../../types'; import { IBinaryTree } from '../../interfaces'; import { AVLTree, AVLTreeNode } from './avl-tree'; @@ -40,21 +48,15 @@ export class TreeMultimap = TreeMultim extends AVLTree implements IBinaryTree { - override options: TreeMultimapOptions; - /** * The constructor function for a TreeMultimap class in TypeScript, which extends another class and sets an option to * merge duplicated values. * @param {TreeMultimapOptions} [options] - An optional object that contains additional configuration options for the * TreeMultimap. */ - constructor(options: TreeMultimapOptions = { iterationType: IterationType.ITERATIVE }) { - super(options); - if (options) { - this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options } - } else { - this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b }; - } + constructor(elements?: IterableEntriesOrKeys, options?: Partial) { + super([], options); + if (elements) this.init(elements); } private _count = 0; @@ -77,14 +79,12 @@ export class TreeMultimap = TreeMultim } override createTree(options?: TreeMultimapOptions): TREE { - return new TreeMultimap({ ...this.options, ...options }) as TREE; + return new TreeMultimap([], { + iterationType: this.iterationType, + comparator: this.comparator, ...options + }) as TREE; } - /** - * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity. - * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. - */ - /** * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity. * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. @@ -169,8 +169,8 @@ export class TreeMultimap = TreeMultim } /** - * Time Complexity: O(1) - constant time, as it performs basic pointer assignments. - * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory. + * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity. + * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. */ /** @@ -208,8 +208,8 @@ export class TreeMultimap = TreeMultim } /** - * Time Complexity: O(k log n) - logarithmic time for each insertion, where "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted. This is because the method iterates through the keys and calls the add method for each. - * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. + * Time Complexity: O(1) - constant time, as it performs basic pointer assignments. + * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory. */ /** @@ -223,7 +223,7 @@ export class TreeMultimap = TreeMultim * values: * @returns a boolean value. */ - override perfectlyBalance(iterationType = this.options.iterationType): boolean { + override perfectlyBalance(iterationType = this.iterationType): boolean { const sorted = this.dfs(node => node, 'in'), n = sorted.length; if (sorted.length < 1) return false; @@ -262,8 +262,8 @@ export class TreeMultimap = TreeMultim } /** - * Time Complexity: O(n log n) - logarithmic time for each insertion, where "n" is the number of nodes in the tree. This is because the method calls the add method for each node. - * Space Complexity: O(n) - linear space, as it creates an array to store the sorted nodes. + * Time Complexity: O(k log n) - logarithmic time for each insertion, where "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted. This is because the method iterates through the keys and calls the add method for each. + * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. */ /** @@ -346,8 +346,8 @@ export class TreeMultimap = TreeMultim } /** - * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The delete method of the superclass (AVLTree) has logarithmic time complexity. - * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. + * Time Complexity: O(n log n) - logarithmic time for each insertion, where "n" is the number of nodes in the tree. This is because the method calls the add method for each node. + * Space Complexity: O(n) - linear space, as it creates an array to store the sorted nodes. */ /** @@ -358,6 +358,24 @@ export class TreeMultimap = TreeMultim this._count = 0; } + /** + * Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The delete method of the superclass (AVLTree) has logarithmic time complexity. + * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size. + */ + + init(elements: IterableEntriesOrKeys): void { + if (elements) { + for (const entryOrKey of elements) { + if (Array.isArray(entryOrKey)) { + const [key, value] = entryOrKey; + this.add(key, value); + } else { + this.add(entryOrKey); + } + } + } + } + /** * Time Complexity: O(1) - constant time, as it performs basic pointer assignments. * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory. diff --git a/src/interfaces/binary-tree.ts b/src/interfaces/binary-tree.ts index ba63ee3..f8a5595 100644 --- a/src/interfaces/binary-tree.ts +++ b/src/interfaces/binary-tree.ts @@ -1,9 +1,21 @@ import { BinaryTree, BinaryTreeNode } from '../data-structures'; -import { BinaryTreeNested, BinaryTreeNodeNested, BiTreeDeleteResult, BTNCallback, BTNKey } from '../types'; +import { + BinaryTreeNested, + BinaryTreeNodeNested, + BinaryTreeOptions, + BiTreeDeleteResult, + BTNCallback, + BTNKey, + IterableEntriesOrKeys +} from '../types'; export interface IBinaryTree = BinaryTreeNodeNested, TREE extends BinaryTree = BinaryTreeNested> { createNode(key: BTNKey, value?: N['value']): N; + createTree(options?: Partial): TREE; + + init(elements: IterableEntriesOrKeys): void; + add(keyOrNode: BTNKey | N | null, value?: N['value']): N | null | undefined; delete>(identifier: ReturnType | null, callback: C): BiTreeDeleteResult[]; diff --git a/src/types/common.ts b/src/types/common.ts index 63d4274..d5fb02a 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -1,3 +1,5 @@ +import { BTNKey } from "./data-structures"; + export type Comparator = (a: T, b: T) => number; export type DFSOrderPattern = 'pre' | 'in' | 'post'; @@ -20,4 +22,6 @@ export interface IterableWithLength extends Iterable { export type IterableWithSizeOrLength = IterableWithSize | IterableWithLength -export type BinaryTreePrintOptions = { isShowUndefined?: boolean, isShowNull?: boolean, isShowRedBlackNIL?: boolean } \ No newline at end of file +export type BinaryTreePrintOptions = { isShowUndefined?: boolean, isShowNull?: boolean, isShowRedBlackNIL?: boolean } + +export type IterableEntriesOrKeys = Iterable<[BTNKey, T | undefined] | BTNKey> \ No newline at end of file diff --git a/src/types/data-structures/binary-tree/binary-tree.ts b/src/types/data-structures/binary-tree/binary-tree.ts index a3960d8..668c6f6 100644 --- a/src/types/data-structures/binary-tree/binary-tree.ts +++ b/src/types/data-structures/binary-tree/binary-tree.ts @@ -30,6 +30,6 @@ export type BinaryTreeNodeNested = BinaryTreeNode> = BinaryTree>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -export type BinaryTreeOptions = { iterationType?: IterationType } +export type BinaryTreeOptions = { iterationType: IterationType } export type NodeDisplayLayout = [string[], number, number, number]; diff --git a/src/types/data-structures/binary-tree/bst.ts b/src/types/data-structures/binary-tree/bst.ts index 80b6733..f3cd84a 100644 --- a/src/types/data-structures/binary-tree/bst.ts +++ b/src/types/data-structures/binary-tree/bst.ts @@ -1,7 +1,6 @@ import { BST, BSTNode } from '../../../data-structures'; import type { BinaryTreeOptions, BTNKey } from './binary-tree'; - -export type BSTComparator = (a: BTNKey, b: BTNKey) => number; +import { Comparator } from "../../common"; // prettier-ignore export type BSTNodeNested = BSTNode>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -9,5 +8,5 @@ export type BSTNodeNested = BSTNode> = BST>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> export type BSTOptions = BinaryTreeOptions & { - comparator?: BSTComparator, + comparator: Comparator } diff --git a/test/performance/data-structures/comparison/comparison.test.ts b/test/performance/data-structures/comparison/comparison.test.ts index ab1acb5..ce05cc9 100644 --- a/test/performance/data-structures/comparison/comparison.test.ts +++ b/test/performance/data-structures/comparison/comparison.test.ts @@ -23,7 +23,7 @@ const arrHundredThousand = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSA suite .add(`SRC PQ ${TEN_THOUSAND.toLocaleString()} add`, () => { - const pq = new SRCPriorityQueue({ comparator: (a, b) => b - a }); + const pq = new SRCPriorityQueue([], { comparator: (a, b) => b - a }); for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i); }) .add(`CJS PQ ${TEN_THOUSAND.toLocaleString()} add`, () => { @@ -47,7 +47,7 @@ if (isCompetitor) { suite .add(`SRC PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => { - const pq = new SRCPriorityQueue({ comparator: (a, b) => b - a }); + const pq = new SRCPriorityQueue([], { comparator: (a, b) => b - a }); for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i); for (let i = 0; i < TEN_THOUSAND; i++) pq.pop(); diff --git a/test/performance/data-structures/heap/heap.test.ts b/test/performance/data-structures/heap/heap.test.ts index 1a2942b..2aff67f 100644 --- a/test/performance/data-structures/heap/heap.test.ts +++ b/test/performance/data-structures/heap/heap.test.ts @@ -7,7 +7,7 @@ const { HUNDRED_THOUSAND, TEN_THOUSAND } = magnitude; suite .add(`${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => { - const heap = new Heap({ comparator: (a, b) => b - a }); + const heap = new Heap([], { comparator: (a, b) => b - a }); for (let i = 0; i < HUNDRED_THOUSAND; i++) { heap.add(i); @@ -18,7 +18,7 @@ suite } }) .add(`${HUNDRED_THOUSAND.toLocaleString()} add & dfs`, () => { - const heap = new Heap({ comparator: (a, b) => b - a }); + const heap = new Heap([], { comparator: (a, b) => b - a }); for (let i = 0; i < HUNDRED_THOUSAND; i++) { heap.add(i); diff --git a/test/performance/data-structures/priority-queue/priority-queue.test.ts b/test/performance/data-structures/priority-queue/priority-queue.test.ts index d6f8d63..ca2bdc7 100644 --- a/test/performance/data-structures/priority-queue/priority-queue.test.ts +++ b/test/performance/data-structures/priority-queue/priority-queue.test.ts @@ -8,7 +8,7 @@ const suite = new Benchmark.Suite(); const { HUNDRED_THOUSAND } = magnitude; suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => { - const pq = new PriorityQueue({ comparator: (a, b) => b - a }); + const pq = new PriorityQueue([], { comparator: (a, b) => b - a }); for (let i = 0; i < HUNDRED_THOUSAND; i++) { pq.add(i); 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 9a62c00..2a31c59 100644 --- a/test/unit/data-structures/binary-tree/avl-tree.test.ts +++ b/test/unit/data-structures/binary-tree/avl-tree.test.ts @@ -112,7 +112,7 @@ describe('AVL Tree Test', () => { describe('AVL Tree Test recursively', () => { it('should perform various operations on a AVL Tree', () => { const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]; - const tree = new AVLTree({ iterationType: IterationType.RECURSIVE }); + const tree = new AVLTree([], { iterationType: IterationType.RECURSIVE }); for (const i of arr) tree.add(i, i); 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 9af491f..b4f2f60 100644 --- a/test/unit/data-structures/binary-tree/binary-tree.test.ts +++ b/test/unit/data-structures/binary-tree/binary-tree.test.ts @@ -189,9 +189,9 @@ describe('BinaryTree', () => { tree.add(4); tree.add(2); expect(tree.getHeight()).toBe(1); - tree.options.iterationType = IterationType.RECURSIVE; + tree.iterationType = IterationType.RECURSIVE; expect(tree.getHeight()).toBe(1); - tree.options.iterationType = IterationType.ITERATIVE; + tree.iterationType = IterationType.ITERATIVE; tree.add(6); tree.add(1); @@ -381,7 +381,7 @@ describe('BinaryTree', () => { let tree: BinaryTree; beforeEach(() => { - tree = new BinaryTree({ iterationType: IterationType.RECURSIVE }); + tree = new BinaryTree([], { iterationType: IterationType.RECURSIVE }); }); afterEach(() => { @@ -541,11 +541,11 @@ describe('BinaryTree', () => { tree.add(3, 'B'); tree.add(7, 'C'); - tree.options.iterationType = IterationType.ITERATIVE; + tree.iterationType = IterationType.ITERATIVE; expect([...tree]).toEqual([[3, "B"], [5, "A"], [7, "C"]]); - tree.options.iterationType = IterationType.RECURSIVE; + tree.iterationType = IterationType.RECURSIVE; expect([...tree]).toEqual([[3, "B"], [5, "A"], [7, "C"]]); - tree.options.iterationType = IterationType.ITERATIVE; + tree.iterationType = IterationType.ITERATIVE; const result = tree.morris(); expect(result).toEqual([3, 5, 7]); diff --git a/test/unit/data-structures/binary-tree/bst.test.ts b/test/unit/data-structures/binary-tree/bst.test.ts index 5fa0de7..20e513d 100644 --- a/test/unit/data-structures/binary-tree/bst.test.ts +++ b/test/unit/data-structures/binary-tree/bst.test.ts @@ -395,7 +395,7 @@ describe('BST operations test', () => { describe('BST operations test recursively', () => { it('should perform various operations on a Binary Search Tree with numeric values', () => { - const bst = new BST({ iterationType: IterationType.RECURSIVE }); + const bst = new BST([], { iterationType: IterationType.RECURSIVE }); expect(bst).toBeInstanceOf(BST); bst.add(11, 11); bst.add(3, 3); diff --git a/test/unit/data-structures/binary-tree/tree-multimap.test.ts b/test/unit/data-structures/binary-tree/tree-multimap.test.ts index f030bee..ceb71ce 100644 --- a/test/unit/data-structures/binary-tree/tree-multimap.test.ts +++ b/test/unit/data-structures/binary-tree/tree-multimap.test.ts @@ -245,7 +245,7 @@ describe('TreeMultimap operations test', () => { describe('TreeMultimap operations test recursively', () => { it('should perform various operations on a Binary Search Tree with numeric values', () => { - const treeMultimap = new TreeMultimap({ iterationType: IterationType.RECURSIVE }); + const treeMultimap = new TreeMultimap([], { iterationType: IterationType.RECURSIVE }); expect(treeMultimap instanceof TreeMultimap); treeMultimap.add(11, 11); diff --git a/test/unit/unrestricted-interconversion.test.ts b/test/unit/unrestricted-interconversion.test.ts index c970212..81c3af7 100644 --- a/test/unit/unrestricted-interconversion.test.ts +++ b/test/unit/unrestricted-interconversion.test.ts @@ -1,4 +1,7 @@ import { + AVLTree, + BinaryTree, + BST, Deque, DoublyLinkedList, MaxHeap, @@ -6,54 +9,92 @@ import { MinHeap, MinPriorityQueue, Queue, + RedBlackTree, SinglyLinkedList, - Stack + Stack, + TreeMultimap } from '../../src'; +import { isDebugTest } from "../config"; +const isDebug = isDebugTest; const orgArr: number[] = [6, 1, 2, 7, 5, 3, 4, 9, 8]; +const entries: [number, number][] = [[6, 6], [1, 1], [2, 2], [7, 7], [5, 5], [3, 3], [4, 4], [9, 9], [8, 8]]; + describe('conversions', () => { it('Array to Queue', () => { const q = new Queue(orgArr); - q.print(); + isDebug && q.print(); }) it('Array to Deque', () => { const dq = new Deque(orgArr); - dq.print(); + isDebug && dq.print(); }) it('Array to SinglyLinkedList', () => { const sl = new SinglyLinkedList(orgArr); - sl.print(); + isDebug && sl.print(); }) it('Array to DoublyLinkedList', () => { const dl = new DoublyLinkedList(orgArr); - dl.print(); + isDebug && dl.print(); }) it('Array to Stack', () => { const stack = new Stack(orgArr); - stack.print(); + isDebug && stack.print(); }) it('Array to MinHeap', () => { const minHeap = new MinHeap(orgArr); - minHeap.print(); + isDebug && minHeap.print(); }) it('Array to MaxHeap', () => { const maxHeap = new MaxHeap(orgArr); - maxHeap.print(); + isDebug && maxHeap.print(); }) it('Array to MinPriorityQueue', () => { const minPQ = new MinPriorityQueue(orgArr); - minPQ.print(); + isDebug && minPQ.print(); }) it('Array to MaxPriorityQueue', () => { const maxPQ = new MaxPriorityQueue(orgArr); - maxPQ.print(); + isDebug && maxPQ.print(); }) -}) \ No newline at end of file + + it('Entry Array to BinaryTree', () => { + const biTree = new BinaryTree(entries); + isDebug && biTree.print(); + }) + + it('Entry Array to BST', () => { + const bst = new BST(orgArr); + expect(bst.size).toBe(9) + isDebug && bst.print(); + }) + + it('Entry Array to RedBlackTree', () => { + const rbTree = new RedBlackTree(orgArr); + expect(rbTree.size).toBe(9) + isDebug && rbTree.print(); + }) + + it('Entry Array to AVLTree', () => { + const avl = new AVLTree(orgArr); + expect(avl.size).toBe(9) + isDebug && avl.print(); + }) + + it('Entry Array to TreeMultimap', () => { + const treeMulti = new TreeMultimap(orgArr); + expect(treeMulti.size).toBe(9) + isDebug && treeMulti.print(); + }) +}) + + +