diff --git a/src/data-structures/binary-tree/avl-tree.ts b/src/data-structures/binary-tree/avl-tree.ts index 9413f47..caafbd1 100644 --- a/src/data-structures/binary-tree/avl-tree.ts +++ b/src/data-structures/binary-tree/avl-tree.ts @@ -14,7 +14,7 @@ import type { BSTNodeKeyOrNode, BTNodeExemplar } from '../../types'; -import { BTNCallback } from '../../types'; +import { BTNCallback, BTNodeKeyOrNode } from '../../types'; import { IBinaryTree } from '../../interfaces'; export class AVLTreeNode = AVLTreeNodeNested> extends BSTNode { @@ -90,6 +90,16 @@ export class AVLTree = AVLTreeN return exemplar instanceof AVLTreeNode; } + /** + * The function "isNotNodeInstance" checks if a potential key is a K. + * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any + * data type. + * @returns a boolean value indicating whether the potentialKey is of type number or not. + */ + override isNotNodeInstance(potentialKey: BTNodeKeyOrNode): potentialKey is K { + return !(potentialKey instanceof AVLTreeNode) + } + /** * 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. diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index 00a0f93..421da3c 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -1236,8 +1236,8 @@ export class BinaryTree = Bi * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type. * @returns a boolean value. */ - isRealNode(node: any): node is N { - return node instanceof BinaryTreeNode && node.key.toString() !== 'NaN'; + isRealNode(node: BTNodeExemplar): node is N { + return node instanceof BinaryTreeNode && String(node.key) !== 'NaN'; } /** @@ -1245,8 +1245,8 @@ export class BinaryTree = Bi * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type. * @returns a boolean value. */ - isNIL(node: any) { - return node instanceof BinaryTreeNode && node.key.toString() === 'NaN'; + isNIL(node: BTNodeExemplar) { + return node instanceof BinaryTreeNode && String(node.key) === 'NaN'; } /** @@ -1254,12 +1254,12 @@ export class BinaryTree = Bi * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type. * @returns a boolean value. */ - isNodeOrNull(node: any): node is N | null { + isNodeOrNull(node: BTNodeExemplar): node is N | null { return this.isRealNode(node) || node === null; } /** - * The function "isNotNodeInstance" checks if a potential key is a number. + * The function "isNotNodeInstance" checks if a potential key is a K. * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any * data type. * @returns a boolean value indicating whether the potentialKey is of type number or not. @@ -1606,26 +1606,24 @@ export class BinaryTree = Bi } /** - * Time complexity: O(n) - * Space complexity: O(n) + * Time Complexity: O(log n) + * Space Complexity: O(1) */ - getPredecessor(node: N): N; - /** - * The function `getPredecessor` returns the predecessor node of a given node in a binary tree. - * @param {K | N | null | undefined} node - The `node` parameter can be of type `K`, `N`, - * `null`, or `undefined`. - * @returns The function `getPredecessor` returns a value of type `N | undefined`. + * Time Complexity: O(log n) + * Space Complexity: O(1) + * + * The function returns the predecessor of a given node in a tree. + * @param {N} node - The parameter `node` is of type `RedBlackTreeNode`, which represents a node in a + * tree. + * @returns the predecessor of the given 'node'. */ - getPredecessor(node: BTNodeKeyOrNode): N | undefined { - node = this.ensureNode(node); - if (!this.isRealNode(node)) return undefined; - - if (node.left) { + getPredecessor(node: N): N { + if (this.isRealNode(node.left)) { let predecessor: N | null | undefined = node.left; while (!this.isRealNode(predecessor) || (this.isRealNode(predecessor.right) && predecessor.right !== node)) { - if (predecessor) { + if (this.isRealNode(predecessor)) { predecessor = predecessor.right; } } @@ -1642,15 +1640,16 @@ export class BinaryTree = Bi * after the given node in the inorder traversal of the binary tree. */ getSuccessor(x?: K | N | null): N | null | undefined { - x = this.ensureNode(x); - if (!x) return undefined; - if (x.right) { + x = this.ensureNode(x); + if (!this.isRealNode(x)) return undefined; + + if (this.isRealNode(x.right)) { return this.getLeftMost(x.right); } let y: N | null | undefined = x.parent; - while (y && y && x === y.right) { + while (this.isRealNode(y) && x === y.right) { x = y; y = y.parent; } diff --git a/src/data-structures/binary-tree/bst.ts b/src/data-structures/binary-tree/bst.ts index 6d2ebd2..1347e0c 100644 --- a/src/data-structures/binary-tree/bst.ts +++ b/src/data-structures/binary-tree/bst.ts @@ -14,7 +14,7 @@ import type { BTNodeExemplar, BTNodePureExemplar } from '../../types'; -import { BSTVariant, CP, IterationType } from '../../types'; +import { BSTVariant, BTNodeKeyOrNode, CP, IterationType } from '../../types'; import { BinaryTree, BinaryTreeNode } from './binary-tree'; import { IBinaryTree } from '../../interfaces'; import { Queue } from '../queue'; @@ -442,6 +442,16 @@ export class BST = BSTNode): potentialKey is K { + return !(potentialKey instanceof 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. diff --git a/src/data-structures/binary-tree/rb-tree.ts b/src/data-structures/binary-tree/rb-tree.ts index fec27e7..cad7928 100644 --- a/src/data-structures/binary-tree/rb-tree.ts +++ b/src/data-structures/binary-tree/rb-tree.ts @@ -11,6 +11,7 @@ import { BSTNodeKeyOrNode, BTNCallback, BTNodeExemplar, + BTNodeKeyOrNode, IterationType, RBTNColor, RBTreeOptions, @@ -115,6 +116,16 @@ export class RedBlackTree return exemplar instanceof RedBlackTreeNode; } + /** + * The function "isNotNodeInstance" checks if a potential key is a K. + * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any + * data type. + * @returns a boolean value indicating whether the potentialKey is of type number or not. + */ + override isNotNodeInstance(potentialKey: BTNodeKeyOrNode): potentialKey is K { + return !(potentialKey instanceof RedBlackTreeNode) + } + /** * The function `exemplarToNode` takes an exemplar and converts it into a node object if possible. * @param exemplar - The `exemplar` parameter is of type `BTNodeExemplar`, where: @@ -300,7 +311,8 @@ export class RedBlackTree */ override isRealNode(node: N | undefined): node is N { - return node !== this.Sentinel && node !== undefined; + if (node === this.Sentinel || node === undefined) return false; + return node instanceof RedBlackTreeNode; } getNode>( @@ -362,38 +374,12 @@ export class RedBlackTree } /** - * Time Complexity: O(log n) on average (where n is the number of nodes in the tree) + * Time Complexity: O(log n) * 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) - * - * The function returns the successor of a given node in a red-black tree. - * @param {RedBlackTreeNode} x - RedBlackTreeNode - The node for which we want to find the successor. - * @returns the successor of the given RedBlackTreeNode. - */ - override getSuccessor(x: N): N | undefined { - if (x.right !== this.Sentinel) { - return this.getLeftMost(x.right) ?? undefined; - } - - let y: N | undefined = x.parent; - while (y !== this.Sentinel && y !== undefined && x === y.right) { - x = y; - y = y.parent; - } - return y; - } - - /** - * 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) + * Time Complexity: O(log n) * Space Complexity: O(1) * * The function returns the predecessor of a given node in a red-black tree. @@ -402,12 +388,12 @@ export class RedBlackTree * @returns the predecessor of the given RedBlackTreeNode 'x'. */ override getPredecessor(x: N): N { - if (x.left !== this.Sentinel) { - return this.getRightMost(x.left!)!; + if (this.isRealNode(x.left)) { + return this.getRightMost(x.left)!; } let y: N | undefined = x.parent; - while (y !== this.Sentinel && x === y!.left) { + while (this.isRealNode(y) && x === y.left) { x = y!; y = y!.parent; } diff --git a/src/data-structures/binary-tree/tree-multimap.ts b/src/data-structures/binary-tree/tree-multimap.ts index 79fb5a8..70fd770 100644 --- a/src/data-structures/binary-tree/tree-multimap.ts +++ b/src/data-structures/binary-tree/tree-multimap.ts @@ -6,7 +6,14 @@ * @license MIT License */ import type { BSTNodeKeyOrNode, BTNodeExemplar, TreeMultimapNodeNested, TreeMultimapOptions } from '../../types'; -import { BiTreeDeleteResult, BTNCallback, FamilyPosition, IterationType, TreeMultimapNested } from '../../types'; +import { + BiTreeDeleteResult, + BTNCallback, + BTNodeKeyOrNode, + FamilyPosition, + IterationType, + TreeMultimapNested +} from '../../types'; import { IBinaryTree } from '../../interfaces'; import { AVLTree, AVLTreeNode } from './avl-tree'; @@ -85,6 +92,15 @@ export class TreeMultimap return exemplar instanceof TreeMultimapNode; } + /** + * The function "isNotNodeInstance" checks if a potential key is a K. + * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any + * data type. + * @returns a boolean value indicating whether the potentialKey is of type number or not. + */ + override isNotNodeInstance(potentialKey: BTNodeKeyOrNode): potentialKey is K { + return !(potentialKey instanceof TreeMultimapNode) + } /** * The function `exemplarToNode` converts an exemplar object into a node object.