mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-09 23:54:04 +00:00
Standardize methods for all BinaryTrees, enabling support for both TreeNode parameters and TreeNodeId as arguments.
This commit is contained in:
parent
d29ff07f40
commit
8ac4e0e7c4
|
@ -461,21 +461,19 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
}
|
||||
|
||||
/**
|
||||
* The function removes a node from a binary tree and returns information about the deleted node.
|
||||
* @param {BinaryTreeNodeId} id - The `id` parameter is the identifier of the binary tree node that you want to remove.
|
||||
* It is of type `BinaryTreeNodeId`.
|
||||
* The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent
|
||||
* node that needs to be balanced.
|
||||
* @param {N | BinaryTreeNodeId | null} nodeOrId - The `nodeOrId` parameter can be one of the following:
|
||||
* @param {boolean} [ignoreCount] - The `ignoreCount` parameter is an optional boolean parameter that determines
|
||||
* whether to ignore the count of the node being removed. If `ignoreCount` is set to `true`, the count of the node will
|
||||
* not be decremented and the overall count of the binary tree will not be updated. If `
|
||||
* @returns An array of objects is being returned. Each object in the array has two properties: "deleted" and
|
||||
* "needBalanced". The "deleted" property contains the deleted node or undefined if no node was deleted. The
|
||||
* "needBalanced" property is always null.
|
||||
* not be taken into account when removing it. If `ignoreCount` is set to `false
|
||||
* @returns The function `remove` returns an array of `BinaryTreeDeletedResult<N>` objects.
|
||||
*/
|
||||
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[] {
|
||||
remove(nodeOrId: N | BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[] {
|
||||
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
|
||||
if (!this.root) return bstDeletedResult;
|
||||
|
||||
const curr: N | null = this.get(id);
|
||||
const curr: N | null = (typeof nodeOrId === 'number') ? this.get(nodeOrId) : nodeOrId;
|
||||
if (!curr) return bstDeletedResult;
|
||||
|
||||
const parent: N | null = curr?.parent ? curr.parent : null;
|
||||
|
@ -518,16 +516,17 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
}
|
||||
|
||||
/**
|
||||
* The function calculates the depth of a binary tree node by traversing its parent nodes.
|
||||
* @param node - N - This is the node for which we want to calculate the depth. It is a generic type,
|
||||
* meaning it can represent any type of data that we want to store in the node.
|
||||
* @returns The depth of the given binary tree node.
|
||||
* The function calculates the depth of a node in a binary tree.
|
||||
* @param {N | BinaryTreeNodeId | null} beginRoot - The `beginRoot` parameter can be one of the following:
|
||||
* @returns the depth of the given node or binary tree.
|
||||
*/
|
||||
getDepth(node: N): number {
|
||||
getDepth(beginRoot: N | BinaryTreeNodeId | null): number {
|
||||
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot, 'id');
|
||||
|
||||
let depth = 0;
|
||||
while (node.parent) {
|
||||
while (beginRoot?.parent) {
|
||||
depth++;
|
||||
node = node.parent;
|
||||
beginRoot = beginRoot.parent;
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
|
@ -540,8 +539,10 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
* If no value is provided for `beginRoot`, the function will use the `root` property of the class instance as
|
||||
* @returns the height of the binary tree.
|
||||
*/
|
||||
getHeight(beginRoot?: N | null): number {
|
||||
getHeight(beginRoot?: N | BinaryTreeNodeId | null): number {
|
||||
beginRoot = beginRoot ?? this.root;
|
||||
|
||||
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot, 'id');
|
||||
if (!beginRoot) return -1;
|
||||
|
||||
if (this._loopType === LoopType.RECURSIVE) {
|
||||
|
@ -731,17 +732,22 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
|
||||
getLeftMost(node: N): N;
|
||||
|
||||
|
||||
/**
|
||||
* The `getLeftMost` function returns the leftmost node in a binary tree, either recursively or iteratively using tail
|
||||
* recursion optimization.
|
||||
* @param {N | null} [node] - The `node` parameter is an optional parameter of type `N
|
||||
* | null`. It represents the starting node from which to find the leftmost node in a binary tree. If no node is
|
||||
* provided, the function will use the root node of the binary tree.
|
||||
* @returns The `getLeftMost` function returns the leftmost node in a binary tree.
|
||||
* The `getLeftMost` function returns the leftmost node in a binary tree, starting from a specified node or the root if
|
||||
* no node is specified.
|
||||
* @param {N | BinaryTreeNodeId | null} [beginRoot] - The `beginRoot` parameter is optional and can be of type `N` (a
|
||||
* generic type representing a node in a binary tree), `BinaryTreeNodeId` (a type representing the ID of a binary tree
|
||||
* node), or `null`.
|
||||
* @returns The function `getLeftMost` returns the leftmost node in a binary tree. If the `beginRoot` parameter is
|
||||
* provided, it starts the traversal from that node. If `beginRoot` is not provided or is `null`, it starts the
|
||||
* traversal from the root of the binary tree. If there are no nodes in the binary tree, it returns `null`.
|
||||
*/
|
||||
getLeftMost(node?: N | null): N | null {
|
||||
node = node ?? this.root;
|
||||
if (!node) return node;
|
||||
getLeftMost(beginRoot?: N | BinaryTreeNodeId | null): N | null {
|
||||
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot, 'id');
|
||||
|
||||
beginRoot = beginRoot ?? this.root;
|
||||
if (!beginRoot) return beginRoot;
|
||||
|
||||
if (this._loopType === LoopType.RECURSIVE) {
|
||||
|
||||
|
@ -750,7 +756,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
return _traverse(cur.left);
|
||||
}
|
||||
|
||||
return _traverse(node);
|
||||
return _traverse(beginRoot);
|
||||
} else {
|
||||
// Indirect implementation of iteration using tail recursion optimization
|
||||
const _traverse = trampoline((cur: N) => {
|
||||
|
@ -758,7 +764,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
return _traverse.cont(cur.left);
|
||||
});
|
||||
|
||||
return _traverse(node);
|
||||
return _traverse(beginRoot);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -890,8 +896,10 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
* provided, it defaults to `'val'`.
|
||||
* @returns a number, which is the sum of the values of the nodes in the subtree rooted at `subTreeRoot`.
|
||||
*/
|
||||
subTreeSum(subTreeRoot: N, propertyName ?: BinaryTreeNodePropertyName): number {
|
||||
subTreeSum(subTreeRoot: N | BinaryTreeNodeId | null, propertyName ?: BinaryTreeNodePropertyName): number {
|
||||
propertyName = propertyName ?? 'id';
|
||||
if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'id');
|
||||
|
||||
if (!subTreeRoot) return 0;
|
||||
|
||||
let sum = 0;
|
||||
|
@ -937,17 +945,22 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
|
|||
return sum;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The function `subTreeAdd` adds a specified delta value to a property of each node in a binary tree.
|
||||
* @param subTreeRoot - The `subTreeRoot` parameter is the root node of the subtree where the values will be modified.
|
||||
* The function `subTreeAdd` adds a delta value to a specified property of each node in a subtree.
|
||||
* @param {N | BinaryTreeNodeId | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
|
||||
* tree or the ID of a binary tree node. It can also be `null` if there is no subtree root.
|
||||
* @param {number} delta - The `delta` parameter is a number that represents the amount by which the property value of
|
||||
* each node in the subtree should be increased or decreased.
|
||||
* each node in the subtree should be incremented or decremented.
|
||||
* @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
|
||||
* specifies the property of the `BinaryTreeNode` that should be modified. It defaults to `'id'` if not provided.
|
||||
* @returns a boolean value, which is `true`.
|
||||
* specifies the property of the binary tree node that should be modified. It can be either 'id' or 'count'. If no
|
||||
* value is provided for `propertyName`, it defaults to 'id'.
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
subTreeAdd(subTreeRoot: N, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean {
|
||||
subTreeAdd(subTreeRoot: N | BinaryTreeNodeId | null, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean {
|
||||
propertyName = propertyName ?? 'id';
|
||||
if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'id');
|
||||
|
||||
if (!subTreeRoot) return false;
|
||||
|
||||
const _addByProperty = (cur: N) => {
|
||||
|
|
|
@ -213,19 +213,20 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|||
|
||||
// --- start additional functions
|
||||
/**
|
||||
* The `lesserSum` function calculates the sum of a specified property in all nodes with an ID less than a given ID in
|
||||
* a binary search tree.
|
||||
* @param {BinaryTreeNodeId} id - The `id` parameter is the identifier of the binary tree node for which you want to
|
||||
* calculate the lesser sum.
|
||||
* The `lesserSum` function calculates the sum of property values in a binary tree for nodes that have a lesser value
|
||||
* than a given node.
|
||||
* @param {N | BinaryTreeNodeId | null} beginNode - The `beginNode` parameter can be one of the following:
|
||||
* @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
|
||||
* specifies the property of the binary tree node to use for calculating the sum. If not provided, it defaults to 'id'.
|
||||
* @returns The function `lesserSum` returns a number, which represents the sum of the values of the nodes in the
|
||||
* binary search tree that have a property value lesser than the given `id`.
|
||||
* specifies the property name to use for calculating the sum. If not provided, it defaults to `'id'`.
|
||||
* @returns The function `lesserSum` returns a number, which represents the sum of the values of the nodes in a binary
|
||||
* tree that have a lesser value than the specified `beginNode` based on the specified `propertyName`.
|
||||
*/
|
||||
lesserSum(id: BinaryTreeNodeId, propertyName ?: BinaryTreeNodePropertyName): number {
|
||||
lesserSum(beginNode: N | BinaryTreeNodeId | null, propertyName ?: BinaryTreeNodePropertyName): number {
|
||||
propertyName = propertyName ?? 'id';
|
||||
if (typeof beginNode === 'number') beginNode = this.get(beginNode, 'id');
|
||||
if (!beginNode) return 0;
|
||||
if (!this.root) return 0;
|
||||
|
||||
const id = beginNode.id;
|
||||
const getSumByPropertyName = (cur: N) => {
|
||||
let needSum: number;
|
||||
switch (propertyName) {
|
||||
|
@ -299,8 +300,11 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|||
* defaults to 'id'.
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
allGreaterNodesAdd(node: N, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean {
|
||||
allGreaterNodesAdd(node: N | BinaryTreeNodeId | null, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean {
|
||||
propertyName = propertyName ?? 'id';
|
||||
if (typeof node === 'number') node = this.get(node, 'id');
|
||||
if (!node) return false;
|
||||
const id = node.id;
|
||||
if (!this.root) return false;
|
||||
|
||||
const _sumByPropertyName = (cur: N) => {
|
||||
|
@ -319,7 +323,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|||
|
||||
if (this.loopType === LoopType.RECURSIVE) {
|
||||
const _traverse = (cur: N) => {
|
||||
const compared = this._compare(cur.id, node.id);
|
||||
const compared = this._compare(cur.id, id);
|
||||
_sumByPropertyName(cur);
|
||||
|
||||
if (!cur.left && !cur.right) return;
|
||||
|
|
|
@ -4,7 +4,8 @@ import {
|
|||
BinaryTreeDeletedResult,
|
||||
BinaryTreeNodeId,
|
||||
BinaryTreeNodePropertyName,
|
||||
DFSOrderPattern, FamilyPosition,
|
||||
DFSOrderPattern,
|
||||
FamilyPosition,
|
||||
LoopType,
|
||||
NodeOrPropertyName
|
||||
} from '../types';
|
||||
|
|
|
@ -16,10 +16,10 @@ describe('BST operations test', () => {
|
|||
expect(bst.has(6)).toBe(true);
|
||||
|
||||
const node6 = bst.get(6);
|
||||
expect(node6 && bst.getHeight(node6)).toBe(2);
|
||||
expect(node6 && bst.getDepth(node6)).toBe(3);
|
||||
expect(node6 && bst.getHeight(6)).toBe(2);
|
||||
expect(node6 && bst.getDepth(6)).toBe(3);
|
||||
|
||||
const nodeId10 = bst.get(10, 'id');
|
||||
const nodeId10 = bst.get(10);
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
|
||||
const nodeVal9 = bst.get(9, 'val');
|
||||
|
@ -35,7 +35,7 @@ describe('BST operations test', () => {
|
|||
const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && bst.subTreeSum(node15);
|
||||
const subTreeSum = node15 && bst.subTreeSum(15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = bst.lesserSum(10);
|
||||
|
@ -43,14 +43,14 @@ describe('BST operations test', () => {
|
|||
|
||||
expect(node15).toBeInstanceOf(BSTNode);
|
||||
if (node15 instanceof BSTNode) {
|
||||
const subTreeAdd = bst.subTreeAdd(node15, 1, 'count');
|
||||
const subTreeAdd = bst.subTreeAdd(15, 1, 'count');
|
||||
expect(subTreeAdd).toBeDefined();
|
||||
}
|
||||
|
||||
const node11 = bst.get(11);
|
||||
expect(node11).toBeInstanceOf(BSTNode);
|
||||
if (node11 instanceof BSTNode) {
|
||||
const allGreaterNodesAdded = bst.allGreaterNodesAdd(node11, 2, 'count');
|
||||
const allGreaterNodesAdded = bst.allGreaterNodesAdd(11, 2, 'count');
|
||||
expect(allGreaterNodesAdded).toBeDefined();
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ describe('BST operations test', () => {
|
|||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(node15 && bst.getHeight(node15)).toBe(2);
|
||||
expect(bst.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = bst.remove(1, true);
|
||||
expect(removed1).toBeInstanceOf(Array);
|
||||
|
@ -189,7 +189,7 @@ describe('BST operations test', () => {
|
|||
expect(bfsNodes[0].id).toBe(2);
|
||||
expect(bfsNodes[1].id).toBe(12);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
|
||||
expect(bst.count).toBe(5);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const orderReducedBy = 2; // reduction of magnitude's order compared to the baseline magnitude
|
||||
const orderReducedBy = 3; // reduction of magnitude's order compared to the baseline magnitude
|
||||
|
||||
export const magnitude = {
|
||||
CONSTANT: Math.floor(Number.MAX_SAFE_INTEGER / Math.pow(10, orderReducedBy)),
|
||||
|
|
Loading…
Reference in a new issue