mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
refactor: Add an isNotNodeInstance method to every binary tree data structure to prevent node type errors. The getSuccessor method of Red-Black trees uniformly utilizes the getSuccessor method from BinaryTree.
This commit is contained in:
parent
26208e9157
commit
1fc47918d2
|
@ -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<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNodeNested<K, V>> extends BSTNode<K, V, N> {
|
||||
|
@ -90,6 +90,16 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = 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<K, N>): 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.
|
||||
|
|
|
@ -1236,8 +1236,8 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = 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<K, V, N>): node is N {
|
||||
return node instanceof BinaryTreeNode && String(node.key) !== 'NaN';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1245,8 +1245,8 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = 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<K, V, N>) {
|
||||
return node instanceof BinaryTreeNode && String(node.key) === 'NaN';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1254,12 +1254,12 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = 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<K, V, N>): 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<K = any, V = any, N extends BinaryTreeNode<K, V, N> = 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<K, N>): 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<K = any, V = any, N extends BinaryTreeNode<K, V, N> = 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;
|
||||
}
|
||||
|
|
|
@ -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<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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<K, N>): 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.
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
BSTNodeKeyOrNode,
|
||||
BTNCallback,
|
||||
BTNodeExemplar,
|
||||
BTNodeKeyOrNode,
|
||||
IterationType,
|
||||
RBTNColor,
|
||||
RBTreeOptions,
|
||||
|
@ -115,6 +116,16 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
|
|||
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<K, N>): 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<K, V, N>`, where:
|
||||
|
@ -300,7 +311,8 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
|
|||
*/
|
||||
|
||||
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<C extends BTNCallback<N, K>>(
|
||||
|
@ -362,38 +374,12 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
|
|||
}
|
||||
|
||||
/**
|
||||
* 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<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
|
|||
* @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;
|
||||
}
|
||||
|
|
|
@ -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<K = any, V = any, N extends TreeMultimapNode<K, V, N>
|
|||
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<K, N>): potentialKey is K {
|
||||
return !(potentialKey instanceof TreeMultimapNode)
|
||||
}
|
||||
|
||||
/**
|
||||
* The function `exemplarToNode` converts an exemplar object into a node object.
|
||||
|
|
Loading…
Reference in a new issue