[binary-tree] Add an 'iterationType' parameter to all methods compatible with both recursion and iteration, allowing for specifying a particular iteration method in each method.

This commit is contained in:
Revone 2023-10-24 00:03:48 +08:00
parent 3983ab089c
commit 6c9578368c
4 changed files with 110 additions and 81 deletions

View file

@ -15,7 +15,7 @@ import type {
MapCallback,
MapCallbackReturn
} from '../../types';
import {BinaryTreeDeletedResult, DFSOrderPattern, FamilyPosition, LoopType} from '../../types';
import {BinaryTreeDeletedResult, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
import {IBinaryTree} from '../../interfaces';
import {trampoline} from '../../utils';
import {Queue} from '../queue';
@ -106,8 +106,8 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
*/
constructor(options?: BinaryTreeOptions) {
if (options !== undefined) {
const {loopType = LoopType.ITERATIVE} = options;
this._loopType = loopType;
const {iterationType = IterationType.ITERATIVE} = options;
this._loopType = iterationType;
}
}
@ -136,13 +136,13 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
return this._size;
}
private _loopType: LoopType = LoopType.ITERATIVE;
private _loopType: IterationType = IterationType.ITERATIVE;
get loopType(): LoopType {
get iterationType(): IterationType {
return this._loopType;
}
set loopType(v: LoopType) {
set iterationType(v: IterationType) {
this._loopType = v;
}
@ -367,13 +367,14 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* @param {N | BinaryTreeNodeKey | null} [beginRoot] - The `beginRoot` parameter is optional and can be of type `N` (a
* generic type representing a node in a binary tree), `BinaryTreeNodeKey` (a type representing the ID of a binary tree
* node), or `null`.
* @param iterationType - The `iterationType` parameter is an optional parameter of type `IterationType`. It represents the type of
* @returns the height of the binary tree.
*/
getHeight(beginRoot: N | BinaryTreeNodeKey | null = this.root): number {
getHeight(beginRoot: N | BinaryTreeNodeKey | null = this.root, iterationType = this.iterationType): number {
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
if (!beginRoot) return -1;
if (this._loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _getMaxHeight = (cur: N | null | undefined): number => {
if (!cur) return -1;
const leftHeight = _getMaxHeight(cur.left);
@ -416,12 +417,13 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* @param {N | null} [beginRoot] - The `beginRoot` parameter is an optional parameter of type `N` or `null`. It
* represents the starting node from which to calculate the minimum height of a binary tree. If no value is provided
* for `beginRoot`, the `this.root` property is used as the default value.
* @param iterationType - The `iterationType` parameter is an optional parameter of type `IterationType`. It represents the type of loop
* @returns The function `getMinHeight` returns the minimum height of the binary tree.
*/
getMinHeight(beginRoot: N | null = this.root): number {
getMinHeight(beginRoot: N | null = this.root, iterationType = this.iterationType): number {
if (!beginRoot) return -1;
if (this._loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _getMinHeight = (cur: N | null | undefined): number => {
if (!cur) return 0;
if (!cur.left && !cur.right) return 0;
@ -481,19 +483,21 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* return only one node that matches the given `nodeProperty` or `propertyName`. If `onlyOne` is set to `true`, the
* function will stop traversing the tree and return the first matching node. If `only
* @param beginRoot
* @param iterationType - The `iterationType` parameter is an optional parameter of type `IterationType`. It represents the type of loop
* @returns an array of nodes (type N).
*/
getNodes(
nodeProperty: BinaryTreeNodeKey | N,
callback: MapCallback<N> = this._defaultCallbackByKey,
onlyOne = false,
beginRoot: N | null = this.root
beginRoot: N | null = this.root,
iterationType = this.iterationType
): N[] {
if (!beginRoot) return [];
const ans: N[] = [];
if (this.loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N) => {
if (callback(cur) === nodeProperty) {
ans.push(cur);
@ -529,11 +533,18 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or `N`.
* It represents the property of the binary tree node that you want to check.
* specifies the name of the property to be checked in the nodes. If not provided, it defaults to 'key'.
* @param beginRoot - The `beginRoot` parameter is an optional parameter of type `N` or `null`. It represents the root node of a tree or null if the tree is empty.
* @param iterationType - The `iterationType` parameter is an optional parameter of type `IterationType`. It represents the type of loop
* @returns a boolean value.
*/
has(nodeProperty: BinaryTreeNodeKey | N, callback: MapCallback<N> = this._defaultCallbackByKey): boolean {
has(
nodeProperty: BinaryTreeNodeKey | N,
callback: MapCallback<N> = this._defaultCallbackByKey,
beginRoot = this.root,
iterationType = this.iterationType
): boolean {
// TODO may support finding node by value equal
return this.getNodes(nodeProperty, callback, true).length > 0;
return this.getNodes(nodeProperty, callback, true, beginRoot, iterationType).length > 0;
}
/**
@ -544,12 +555,19 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* It represents the property of the binary tree node that you want to search for.
* specifies the property name to be used for searching the binary tree nodes. If this parameter is not provided, the
* default value is set to `'key'`.
* @param beginRoot - The `beginRoot` parameter is an optional parameter of type `N` or `null`. It represents the root node of a tree or null if the tree is empty.
* @param iterationType - The `iterationType` parameter is an optional parameter of type `IterationType`. It represents the type of loop used to traverse the binary tree.
* @returns either the value of the specified property of the node, or the node itself if no property name is provided.
* If no matching node is found, it returns null.
*/
get(nodeProperty: BinaryTreeNodeKey | N, callback: MapCallback<N> = this._defaultCallbackByKey): N | null {
get(
nodeProperty: BinaryTreeNodeKey | N,
callback: MapCallback<N> = this._defaultCallbackByKey,
beginRoot = this.root,
iterationType = this.iterationType
): N | null {
// TODO may support finding node by value equal
return this.getNodes(nodeProperty, callback, true)[0] ?? null;
return this.getNodes(nodeProperty, callback, true, beginRoot, iterationType)[0] ?? null;
}
/**
@ -581,17 +599,18 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* @param {N | BinaryTreeNodeKey | null} [beginRoot] - The `beginRoot` parameter is optional and can be of type `N` (a
* generic type representing a node in a binary tree), `BinaryTreeNodeKey` (a type representing the ID of a binary tree
* node), or `null`.
* @param iterationType - The `iterationType` parameter is an optional parameter of type `IterationType`. It represents the type of loop used to traverse the binary tree.
* @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. The function returns the leftmost node found during the traversal. If no leftmost
* node is found (
*/
getLeftMost(beginRoot: N | BinaryTreeNodeKey | null = this.root): N | null {
getLeftMost(beginRoot: N | BinaryTreeNodeKey | null = this.root, iterationType = this.iterationType): N | null {
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
if (!beginRoot) return beginRoot;
if (this._loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N): N => {
if (!cur.left) return cur;
return _traverse(cur.left);
@ -615,15 +634,16 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* @param {N | null} [beginRoot] - The `node` parameter is an optional parameter of type `N` or `null`. It represents the
* starting node from which we want to find the rightmost node. If no node is provided, the function will default to
* using the root node of the data structure.
* @param iterationType - The `iterationType` parameter is an optional parameter of type `IterationType`. It represents the type of loop
* @returns The `getRightMost` function returns the rightmost node in a binary tree. If the `node` parameter is provided,
* it returns the rightmost node starting from that node. If the `node` parameter is not provided, it returns the
* rightmost node starting from the root of the binary tree.
*/
getRightMost(beginRoot: N | null = this.root): N | null {
getRightMost(beginRoot: N | null = this.root, iterationType = this.iterationType): N | null {
// TODO support get right most by passing key in
if (!beginRoot) return beginRoot;
if (this._loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N): N => {
if (!cur.right) return cur;
return _traverse(cur.right);
@ -643,25 +663,26 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
/**
* The function checks if a binary search tree is valid by traversing it either recursively or iteratively.
* @param {N | null} subTreeRoot - The `node` parameter represents the root node of a binary search tree (BST).
* @param {N | null} beginRoot - The `node` parameter represents the root node of a binary search tree (BST).
* @param iterationType - The `iterationType` parameter is an optional parameter of type `IterationType`. It represents the type of loop
* @returns a boolean value.
*/
isSubtreeBST(subTreeRoot: N): boolean {
isSubtreeBST(beginRoot: N, iterationType = this.iterationType): boolean {
// TODO there is a bug
if (!subTreeRoot) return true;
if (!beginRoot) return true;
if (this._loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const dfs = (cur: N | null | undefined, min: BinaryTreeNodeKey, max: BinaryTreeNodeKey): boolean => {
if (!cur) return true;
if (cur.key <= min || cur.key >= max) return false;
return dfs(cur.left, min, cur.key) && dfs(cur.right, cur.key, max);
};
return dfs(subTreeRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
return dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
} else {
const stack = [];
let prev = Number.MIN_SAFE_INTEGER,
curr: N | null | undefined = subTreeRoot;
curr: N | null | undefined = beginRoot;
while (curr || stack.length > 0) {
while (curr) {
stack.push(curr);
@ -680,38 +701,40 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* The function isBST checks if the binary tree is valid binary search tree.
* @returns The `isBST()` function is returning a boolean value.
*/
isBST(): boolean {
isBST(iterationType = this.iterationType): boolean {
if (this.root === null) return true;
return this.isSubtreeBST(this.root);
return this.isSubtreeBST(this.root, iterationType);
}
/**
* The function `subTreeTraverse` adds a delta value to a specified property of each node in a subtree.
* @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a binary
* @param {N | BinaryTreeNodeKey | null} beginRoot - The `beginRoot` parameter represents the root node of a binary
* tree or the ID of a node in the binary tree. It can also be `null` if there is no subtree to add to.
* @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a value.
* specifies the property of the binary tree node that should be modified. If not provided, it defaults to 'key'.
* @param iterationType - The `iterationType` parameter is an optional parameter of type `IterationType`. It represents the type of loop
* @returns a boolean value.
*/
subTreeTraverse(
callback: MapCallback<N> = this._defaultCallbackByKey,
subTreeRoot: N | BinaryTreeNodeKey | null = this.root
beginRoot: N | BinaryTreeNodeKey | null = this.root,
iterationType = this.iterationType
): MapCallbackReturn<N>[] {
if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot);
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
const ans: MapCallbackReturn<N>[] = [];
if (!subTreeRoot) return ans;
if (!beginRoot) return ans;
if (this._loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N) => {
ans.push(callback(cur));
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
};
_traverse(subTreeRoot);
_traverse(beginRoot);
} else {
const stack: N[] = [subTreeRoot];
const stack: N[] = [beginRoot];
while (stack.length > 0) {
const cur = stack.pop()!;
@ -730,18 +753,18 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* @param callback
* @param beginRoot - The `beginRoot` parameter is an optional parameter of type `N` or `null`. It represents the
* @param {'in' | 'pre' | 'post'} [pattern] - The traversal pattern: 'in' (in-order), 'pre' (pre-order), or 'post' (post-order).
* @param loopType - The type of loop to use for the depth-first search traversal. The default value is `LoopType.ITERATIVE`.
* @param iterationType - The type of loop to use for the depth-first search traversal. The default value is `IterationType.ITERATIVE`.
* @returns an instance of the BinaryTreeNodeProperties class, which contains the accumulated properties of the binary tree nodes based on the specified pattern and node or property name.
*/
dfs(
callback: MapCallback<N> = this._defaultCallbackByKey,
pattern: DFSOrderPattern = 'in',
beginRoot: N | null = this.root,
loopType: LoopType = LoopType.ITERATIVE
iterationType: IterationType = IterationType.ITERATIVE
): MapCallbackReturn<N>[] {
if (!beginRoot) return [];
const ans: MapCallbackReturn<N>[] = [];
if (loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _traverse = (node: N) => {
switch (pattern) {
case 'in':
@ -808,30 +831,31 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
/**
* The `listLevels` function collects nodes from a binary tree by a specified property and organizes them into levels.
* @param {N | null} node - The `node` parameter is a BinaryTreeNode object or null. It represents the root node of a binary tree. If it is null, the function will use the root node of the current binary tree instance.
* @param callback - The `callback` parameter is a function that takes a node and a level as parameters and returns a value.
* @param withLevel - The `withLevel` parameter is a boolean flag that determines whether to include the level of each node in the result. If `withLevel` is set to `true`, the function will include the level of each node in the result. If `withLevel` is set to `false` or not provided, the function will not include the level of each node in the result.
* @param beginRoot - The `beginRoot` parameter is an optional parameter of type `N` or `null`. It represents the root node of a tree or null if the tree is empty.
* @param iterationType
*/
bfs(
callback: BFSCallback<N> = this._defaultCallbackByKey,
withLevel: boolean = false,
node: N | null = this.root
beginRoot: N | null = this.root,
iterationType = this.iterationType
): BFSCallbackReturn<N>[] {
if (!node) node = this.root;
if (!node) return [];
if (!beginRoot) return [];
const ans: BFSCallbackReturn<N>[] = [];
if (this.loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _recursive = (node: N, level: number) => {
callback && ans.push(callback(node, withLevel ? level : undefined));
if (node.left) _recursive(node.left, level + 1);
if (node.right) _recursive(node.right, level + 1);
};
_recursive(node, 0);
_recursive(beginRoot, 0);
} else {
const stack: [N, number][] = [[node, 0]];
const stack: [N, number][] = [[beginRoot, 0]];
while (stack.length > 0) {
const head = stack.pop()!;

View file

@ -13,7 +13,7 @@ import type {
MapCallback,
MapCallbackReturn
} from '../../types';
import {CP, LoopType} from '../../types';
import {CP, IterationType} from '../../types';
import {BinaryTree, BinaryTreeNode} from './binary-tree';
import {IBinaryTree} from '../../interfaces';
import {Queue} from '../queue';
@ -134,12 +134,14 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* to the binary search tree.
* @param {N['val'][]} 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 is an optional parameter that specifies whether to use a
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
override addMany(
keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[],
data?: N['val'][],
isBalanceAdd = true
isBalanceAdd = true,
iterationType = this.iterationType
): (N | null | undefined)[] {
// TODO this addMany function is inefficient, it should be optimized
function hasNoNull(arr: (BinaryTreeNodeKey | null)[] | (N | null)[]): arr is BinaryTreeNodeKey[] | N[] {
@ -199,7 +201,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
}
}
};
if (this.loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
recursive(sortedKeysOrNodes, sortedData);
} else {
iterative();
@ -221,16 +223,15 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
}
/**
* The function returns the key of the rightmost node if the comparison between two values is less than, the key of the
* leftmost node if the comparison is greater than, and the key of the rightmost node otherwise.
* @returns The method `lastKey()` returns the key of the rightmost node in the binary tree if the comparison between
* the values at index 0 and 1 is less than, otherwise it returns the key of the leftmost node. If the comparison is
* equal, it returns the key of the rightmost node. If there are no nodes in the tree, it returns 0.
* lastKey returns the last key in a binary tree. If the binary tree is empty, it returns 0.
* @param beginRoot - The `beginRoot` parameter is an optional parameter that specifies the root node from which to begin
* the search for the last key.
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies whether to use a recursive or iterative approach to search for the last key.
*/
lastKey(beginRoot: N | null = this.root): BinaryTreeNodeKey {
if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot)?.key ?? 0;
else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot)?.key ?? 0;
else return this.getRightMost(beginRoot)?.key ?? 0;
lastKey(beginRoot: N | null = this.root, iterationType = this.iterationType): BinaryTreeNodeKey {
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;
}
/**
@ -243,18 +244,20 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* return only one node that matches the given `nodeProperty` or all nodes that match the `nodeProperty`. If `onlyOne`
* is set to `true`, the function will return an array with only one node (if
* @param beginRoot - The `beginRoot` parameter is an optional parameter that specifies the root node from which to
* @param iterationType
* @returns an array of nodes (type N).
*/
override getNodes(
nodeProperty: BinaryTreeNodeKey | N,
callback: MapCallback<N> = this._defaultCallbackByKey,
onlyOne = false,
beginRoot: N | null = this.root
beginRoot: N | null = this.root,
iterationType = this.iterationType
): N[] {
if (!beginRoot) return [];
const ans: N[] = [];
if (this.loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N) => {
const callbackResult = callback(cur);
if (callbackResult === nodeProperty) {
@ -305,29 +308,31 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* The `lesserOrGreaterTraverse` function adds a delta value to the specified property of all nodes in a binary tree that
* have a greater value than a given node.
* @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a value.
* @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be either of type `N` (a generic type), `BinaryTreeNodeKey`, or `null`. It
* represents the node in the binary tree to which the delta value will be added.
* @param lesserOrGreater - The `lesserOrGreater` parameter is an optional parameter that specifies whether the delta
* @param targetNode - The `targetNode` parameter is an optional parameter that specifies the node in the binary tree
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies whether to use a
*/
lesserOrGreaterTraverse(
callback: MapCallback<N> = this._defaultCallbackByKey,
lesserOrGreater: CP = CP.lt,
node: N | BinaryTreeNodeKey | null = this.root
targetNode: N | BinaryTreeNodeKey | null = this.root,
iterationType = this.iterationType
): MapCallbackReturn<N> {
if (typeof node === 'number') node = this.get(node);
if (typeof targetNode === 'number') targetNode = this.get(targetNode);
const ans: MapCallbackReturn<N>[] = [];
if (!node) return ans;
const key = node.key;
if (!targetNode) return ans;
const targetKey = targetNode.key;
if (!this.root) return ans;
if (this.loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _traverse = (cur: N) => {
const compared = this._compare(cur.key, key);
const compared = this._compare(cur.key, targetKey);
if (compared === lesserOrGreater) ans.push(callback(cur));
if (!cur.left && !cur.right) return;
if (cur.left && this._compare(cur.left.key, key) === lesserOrGreater) _traverse(cur.left);
if (cur.right && this._compare(cur.right.key, key) === lesserOrGreater) _traverse(cur.right);
if (cur.left && this._compare(cur.left.key, targetKey) === lesserOrGreater) _traverse(cur.left);
if (cur.right && this._compare(cur.right.key, targetKey) === lesserOrGreater) _traverse(cur.right);
};
_traverse(this.root);
@ -337,11 +342,11 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
while (queue.size > 0) {
const cur = queue.shift();
if (cur) {
const compared = this._compare(cur.key, key);
const compared = this._compare(cur.key, targetKey);
if (compared === lesserOrGreater) ans.push(callback(cur));
if (cur.left && this._compare(cur.left.key, key) === lesserOrGreater) queue.push(cur.left);
if (cur.right && this._compare(cur.right.key, key) === lesserOrGreater) queue.push(cur.right);
if (cur.left && this._compare(cur.left.key, targetKey) === lesserOrGreater) queue.push(cur.left);
if (cur.right && this._compare(cur.right.key, targetKey) === lesserOrGreater) queue.push(cur.right);
}
}
return ans;
@ -363,13 +368,13 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* constructs a balanced binary search tree using either a recursive or iterative approach.
* @returns The function `perfectlyBalance()` returns a boolean value.
*/
perfectlyBalance(): boolean {
perfectlyBalance(iterationType = this.iterationType): boolean {
const sorted = this.dfs(node => node, 'in'),
n = sorted.length;
this.clear();
if (sorted.length < 1) return false;
if (this.loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const buildBalanceBST = (l: number, r: number) => {
if (l > r) return;
const m = l + Math.floor((r - l) / 2);
@ -404,12 +409,12 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* The function `isAVLBalanced` checks if a binary tree is balanced according to the AVL tree property.
* @returns a boolean value.
*/
isAVLBalanced(): boolean {
isAVLBalanced(iterationType = this.iterationType): boolean {
if (!this.root) return true;
let balanced = true;
if (this.loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const _height = (cur: N | null | undefined): number => {
if (!cur) return 0;
const leftHeight = _height(cur.left),

View file

@ -6,7 +6,7 @@
* @license MIT License
*/
import type {BinaryTreeNodeKey, TreeMultisetNodeNested, TreeMultisetOptions} from '../../types';
import {BinaryTreeDeletedResult, CP, FamilyPosition, LoopType} from '../../types';
import {BinaryTreeDeletedResult, CP, FamilyPosition, IterationType} from '../../types';
import {IBinaryTree} from '../../interfaces';
import {AVLTree, AVLTreeNode} from './avl-tree';
@ -246,14 +246,14 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
* constructs a balanced binary search tree using either a recursive or iterative approach.
* @returns The function `perfectlyBalance()` returns a boolean value.
*/
override perfectlyBalance(): boolean {
override perfectlyBalance(iterationType = this.iterationType): boolean {
const sorted = this.dfs(node => node, 'in'),
n = sorted.length;
if (sorted.length < 1) return false;
this.clear();
if (this.loopType === LoopType.RECURSIVE) {
if (iterationType === IterationType.RECURSIVE) {
const buildBalanceBST = (l: number, r: number) => {
if (l > r) return;
const m = l + Math.floor((r - l) / 2);
@ -293,7 +293,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
* not be taken into account when removing it. If `ignoreCount` is set to `false
* @returns The function `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
*/
override delete(nodeOrKey: N | BinaryTreeNodeKey, ignoreCount = false): BinaryTreeDeletedResult<N>[]{
override delete(nodeOrKey: N | BinaryTreeNodeKey, ignoreCount = false): BinaryTreeDeletedResult<N>[] {
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
if (!this.root) return bstDeletedResult;

View file

@ -7,7 +7,7 @@ import {BinaryTreeNode} from '../../data-structures/binary-tree';
* - `recursive`: Indicates the recursive loop type (with loops that call themselves).
*/
export enum LoopType {
export enum IterationType {
ITERATIVE = 'ITERATIVE',
RECURSIVE = 'RECURSIVE'
}
@ -44,4 +44,4 @@ export type BinaryTreeNodeProperties<N extends BinaryTreeNode<N['val'], N>> =
export type BinaryTreeNodeNested<T> = BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type BinaryTreeOptions = { loopType?: LoopType }
export type BinaryTreeOptions = { iterationType?: IterationType }