chore: Add comments for the time and space complexity of all methods for the BinaryTree.

This commit is contained in:
Revone 2023-11-10 11:01:49 +08:00
parent d682a609f9
commit cef8b04a9f
6 changed files with 463 additions and 211 deletions

View file

@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
- [`auto-changelog`](https://github.com/CookPete/auto-changelog)
## [v1.42.7](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
## [v1.42.8](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
### Changes

View file

@ -153,10 +153,23 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* Add a node with the given key and value to the binary tree.
* @param {BTNKey | N | null} keyOrNode - The key or node to add to the binary tree.
* @param {V} value - The value for the new node (optional).
* @returns {N | null | undefined} - The inserted node, or null if nothing was inserted, or undefined if the operation failed.
* 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)
*
* The `add` function adds a new node with a key and value to a binary tree, or updates the value of
* an existing node with the same key.
* @param {BTNKey | N | null | undefined} keyOrNode - The `keyOrNode` parameter can be one of the
* following types:
* @param {V} [value] - The value to be associated with the key or node being added to the binary
* tree.
* @returns The function `add` returns a node (`N`) if it was successfully inserted into the binary
* tree, or `null` or `undefined` if the insertion was not successful.
*/
add(keyOrNode: BTNKey | N | null | undefined, value?: V): N | null | undefined {
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
@ -204,13 +217,22 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* The `addMany` function takes an array of binary tree node IDs or nodes, and optionally an array of corresponding data
* values, and adds them to the binary tree.
* @param {(BTNKey | null)[] | (N | null)[]} keysOrNodes - An array of BTNKey or BinaryTreeNode
* objects, or null values.
* @param {V[]} [values] - The `values` parameter is an optional array of values (`V[]`) that corresponds to
* the nodes or node IDs being added. It is used to set the value of each node being added. If `values` is not provided,
* the value of the nodes will be `undefined`.
* Time Complexity: O(n^2)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(n^2)
* Space Complexity: O(1)
*
* The `addMany` function takes an array of keys or nodes and an optional array of values, and adds
* each key-value pair to a data structure.
* @param {(BTNKey | N |null | undefined)[]} keysOrNodes - An array of keys or nodes to be added to
* the binary search tree. Each element can be of type `BTNKey` (a key value), `N` (a node), `null`,
* or `undefined`.
* @param {(V | undefined)[]} [values] - The `values` parameter is an optional array of values that
* correspond to the keys or nodes being added. If provided, the values will be associated with the
* keys or nodes during the add operation.
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
addMany(keysOrNodes: (BTNKey | N |null | undefined)[], values?: (V | undefined)[]): (N | null | undefined)[] {
@ -230,6 +252,14 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* Time Complexity: O(n^2)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(n^2)
* Space Complexity: O(1)
*
* The `refill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data.
* @param {(BTNKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
* `BTNKey` or `N` values.
@ -250,18 +280,24 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
delete<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C): BiTreeDeleteResult<N>[];
/**
* The `delete` function removes a node from a binary search tree and returns the deleted node along
* with the parent node that needs to be balanced.
* a key (`BTNKey`). If it is a key, the function will find the corresponding node in the
* binary tree.
* @returns an array of `BiTreeDeleteResult<N>` objects.
* @param {ReturnType<C>} identifier - The `identifier` parameter is either a
* `BTNKey` or a generic type `N`. It represents the property of the node that we are
* searching for. It can be a specific key value or any other property of the node.
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
* value. This value is compared with the `identifier` parameter to determine if the node should be
* included in the result. The `callback` parameter has a default value of
* `this._defaultOneParamCallback`, which
* Time Complexity: O(n)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
*
* The function deletes a node from a binary tree and returns an array of the deleted nodes along
* with the nodes that need to be balanced.
* @param {ReturnType<C> | null | undefined} identifier - The identifier parameter is the value or
* object that you want to delete from the binary tree. It can be of any type that is compatible with
* the callback function's return type. It can also be null or undefined if you want to delete a
* specific node based on its value or object.
* @param {C} callback - The `callback` parameter is a function that is used to determine the
* identifier of the node to be deleted. It is optional and has a default value of
* `this._defaultOneParamCallback`. The `callback` function should return the identifier of the node.
* @returns an array of `BiTreeDeleteResult<N>`.
*/
delete<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null | undefined,
@ -311,15 +347,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* The function `getDepth` calculates the depth of a given node in a binary tree relative to a
* specified root node.
* @param {BTNKey | N | null | undefined} distNode - The `distNode` parameter represents the node
* whose depth we want to find in the binary tree. It can be either a node object (`N`), a key value
* of the node (`BTNKey`), or `null`.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
* starting node from which we want to calculate the depth. It can be either a node object or the key
* of a node in the binary tree. If no value is provided for `beginRoot`, it defaults to the root
* node of the binary tree.
* Time Complexity: O(n)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
*
* The function calculates the depth of a given node in a binary tree.
* @param {BTNKey | N | null | undefined} distNode - The `distNode` parameter represents the node in
* the binary tree whose depth we want to find. It can be of type `BTNKey`, `N`, `null`, or
* `undefined`.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
* from which we want to calculate the depth. It can be either a `BTNKey` (binary tree node key) or
* `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot
* @returns the depth of the `distNode` relative to the `beginRoot`.
*/
getDepth(distNode: BTNKey | N | null | undefined, beginRoot: BTNKey | N | null | undefined = this.root): number {
@ -337,15 +379,24 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* The `getHeight` function calculates the maximum height of a binary tree using either recursive or
* iterative approach.
* 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)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(log n)
*
* The function `getHeight` calculates the maximum height of a binary tree using either recursive or
* iterative traversal.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
* starting node from which the height of the binary tree is calculated. It can be either a node
* object (`N`), a key value of a node in the tree (`BTNKey`), or `null` if no starting
* node is specified. If `
* starting node of the binary tree from which we want to calculate the height. It can be of type
* `BTNKey`, `N`, `null`, or `undefined`. If not provided, it defaults to `this.root`.
* @param iterationType - The `iterationType` parameter is used to determine whether to calculate the
* height of the binary tree using a recursive approach or an iterative approach. It can have two
* possible values:
* height of the tree using a recursive approach or an iterative approach. It can have two possible
* values:
* @returns the height of the binary tree.
*/
getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number {
@ -383,11 +434,20 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = 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)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(log n)
*
* The `getMinHeight` function calculates the minimum height of a binary tree using either a
* recursive or iterative approach.
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node from which we want to
* calculate the minimum height of the tree. It is optional and defaults to the root of the tree if
* not provided.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
* starting node of the binary tree from which we want to calculate the minimum height. It can be of
* type `BTNKey`, `N`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.
* @param iterationType - The `iterationType` parameter is used to determine the method of iteration
* 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.
@ -436,11 +496,20 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* Time Complexity: O(n)
* Space Complexity: O(log n)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(log n)
*
* The function checks if a binary tree is perfectly balanced by comparing the minimum height and the
* height of the tree.
* @param {N | null | undefined} beginRoot - The parameter `beginRoot` is of type `N | null | undefined`, which means it can
* either be of type `N` (representing a node in a tree) or `null` (representing an empty tree).
* @returns The method is returning a boolean value.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
* for calculating the height and minimum height of a binary tree. It can be either a `BTNKey` (a key
* value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If
* @returns a boolean value.
*/
isPerfectlyBalanced(beginRoot: BTNKey | N | null | undefined = this.root): boolean {
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
@ -471,25 +540,35 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
): N[];
/**
* The function `getNodes` returns an array of nodes that match a given node property, using either
* recursive or iterative traversal.
* @param {ReturnType<C>} identifier - The `identifier` parameter is either a
* `BTNKey` or a generic type `N`. It represents the property of the node that we are
* searching for. It can be a specific key value or any other property of the node.
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
* value. This value is compared with the `identifier` parameter to determine if the node should be
* included in the result. The `callback` parameter has a default value of
* `this._defaultOneParamCallback`, which
* @param [onlyOne=false] - A boolean value indicating whether to stop searching after finding the
* first node that matches the identifier. If set to true, the function will return an array with
* only one element (or an empty array if no matching node is found). If set to false (default), the
* function will continue searching for all
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node from which the
* traversal of the binary tree will begin. It is optional and defaults to the root of the binary
* tree.
* Time Complexity: O(n)
* Space Complexity: O(log n).
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(log n).
*
* The function `getNodes` retrieves nodes from a binary tree based on a given identifier and
* callback function.
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
* that you want to search for in the binary tree. It can be of any type that is returned by the
* callback function `C`. It can also be `null` or `undefined` if you don't want to search for a
* specific value.
* @param {C} callback - The `callback` parameter is a function that takes a node of type `N` as
* input and returns a value of type `C`. It is used to determine if a node matches the given
* identifier. If no callback is provided, the `_defaultOneParamCallback` function is used as the
* default
* @param [onlyOne=false] - A boolean value indicating whether to only return the first node that
* matches the identifier. If set to true, the function will stop iterating once it finds a matching
* node and return that node. If set to false (default), the function will continue iterating and
* return all nodes that match the identifier.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
* starting node for the traversal. It can be either a key, a node object, or `null`/`undefined`. If
* it is `null` or `undefined`, an empty array will be returned.
* @param iterationType - The `iterationType` parameter determines the type of iteration used to
* traverse the binary tree. It can have two possible values:
* @returns The function `getNodes` returns an array of nodes (`N[]`).
* @returns an array of nodes of type `N`.
*/
getNodes<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null | undefined,
@ -557,20 +636,28 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
): boolean;
/**
* The function checks if a binary tree has a node with a given property or key.
* @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
* the node that you want to find in the binary tree. It can be either a `BTNKey` or a
* generic type `N`.
* @param callback - The `callback` parameter is a function that is used to determine whether a node
* matches the desired criteria. It takes a node as input and returns a boolean value indicating
* whether the node matches the criteria or not. The default callback function
* `this._defaultOneParamCallback` is used if no callback function is
* @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
* the node from which the search should begin. By default, it is set to `this.root`, which means the
* search will start from the root node of the binary tree. However, you can provide a different node
* as
* @param iterationType - The `iterationType` parameter specifies the type of iteration to be
* performed when searching for nodes in the binary tree. It can have one of the following values:
* Time Complexity: O(n)
* Space Complexity: O(log n).
*/
/**
* Time Complexity: O(n)
*
* The function checks if a Binary Tree Node with a specific identifier exists in the tree.
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
* that you want to search for in the binary tree. It can be of any type that is returned by the
* callback function `C`. It can also be `null` or `undefined` if you don't want to specify a
* specific identifier.
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
* the binary tree. It is used to filter the nodes based on certain conditions. The `callback`
* function should return a boolean value indicating whether the node should be included in the
* result or not.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
* for the search in the binary tree. It can be specified as a `BTNKey` (a unique identifier for a
* node in the binary tree), a node object (`N`), or `null`/`undefined` to start the search from
* @param iterationType - The `iterationType` parameter is a variable that determines the type of
* iteration to be performed on the binary tree. It is used to specify whether the iteration should
* be performed in a pre-order, in-order, or post-order manner.
* @returns a boolean value.
*/
has<C extends BTNCallback<N>>(
@ -606,19 +693,30 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
): N | null | undefined;
/**
* The function `get` returns the first node in a binary tree that matches the given property or key.
* @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
* the node that you want to find in the binary tree. It can be either a `BTNKey` or `N`
* type.
* @param callback - The `callback` parameter is a function that is used to determine whether a node
* matches the desired criteria. It takes a node as input and returns a boolean value indicating
* whether the node matches the criteria or not. The default callback function
* (`this._defaultOneParamCallback`) is used if no callback function is
* @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
* the root node from which the search should begin.
* @param iterationType - The `iterationType` parameter specifies the type of iteration to be
* performed when searching for a node in the binary tree. It can have one of the following values:
* @returns either the found node (of type N) or null if no node is found.
* Time Complexity: O(n)
* Space Complexity: O(log n)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(log n)
*
* The function `getNode` returns the first node that matches the given identifier and callback
* function.
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
* used to identify the node you want to retrieve. It can be of any type that is returned by the
* callback function `C`. It can also be `null` or `undefined` if you don't have a specific
* identifier.
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
* the binary tree. It is used to determine if a node matches the given identifier. The `callback`
* function should take a single parameter of type `N` (the type of the nodes in the binary tree) and
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
* for searching the binary tree. It can be either a key value, a node object, or `null`/`undefined`.
* If `null` or `undefined` is passed, the search will start from the root of the binary tree.
* @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
* be performed when searching for nodes in the binary tree. It determines the order in which the
* nodes are visited during the search.
* @returns a value of type `N | null | undefined`.
*/
getNode<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null | undefined,
@ -632,6 +730,14 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* Time Complexity: O(n)
* Space Complexity: O(log n)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(log n)
*
* The function `getNodeByKey` searches for a node in a binary tree by its key, using either
* recursive or iterative iteration.
* @param {BTNKey} key - The `key` parameter is the key value that we are searching for in the tree.
@ -666,7 +772,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
}
}
/**
* The function `ensureNotKey` returns the node corresponding to the given key if it is a valid node
* key, otherwise it returns the key itself.
@ -704,19 +810,31 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
): V | undefined;
/**
* The function `get` returns the first node value in a binary tree that matches the given property or key.
* @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
* the node that you want to find in the binary tree. It can be either a `BTNKey` or `N`
* type.
* @param callback - The `callback` parameter is a function that is used to determine whether a node
* matches the desired criteria. It takes a node as input and returns a boolean value indicating
* whether the node matches the criteria or not. The default callback function
* (`this._defaultOneParamCallback`) is used if no callback function is
* @param beginRoot - The `beginRoot` parameter is the starting point for the search. It specifies
* the root node from which the search should begin.
* @param iterationType - The `iterationType` parameter specifies the type of iteration to be
* performed when searching for a node in the binary tree. It can have one of the following values:
* @returns either the found value (of type V) or undefined if no node value is found.
* Time Complexity: O(n)
* Space Complexity: O(log n)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(log n)
*
* The function `get` retrieves the value of a node in a binary tree based on the provided identifier
* and callback function.
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
* used to identify the node in the binary tree. It can be of any type that is the return type of the
* callback function `C`. It can also be `null` or `undefined` if no identifier is provided.
* @param {C} callback - The `callback` parameter is a function that will be called with each node in
* the binary tree. It is used to determine whether a node matches the given identifier. The callback
* function should return a value that can be compared to the identifier to determine if it is a
* match.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
* for the search in the binary tree. It can be specified as a `BTNKey` (a unique identifier for a
* node), a node object of type `N`, or `null`/`undefined` to start the search from the root of
* @param iterationType - The `iterationType` parameter is used to specify the type of iteration to
* be performed when searching for a node in the binary tree. It is an optional parameter with a
* default value specified by `this.iterationType`.
* @returns The value of the node with the given identifier is being returned. If the node is not
* found, `undefined` is returned.
*/
get<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null | undefined,
@ -744,16 +862,25 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
isEmpty(): boolean {
return this.size === 0;
}
/**
* The function `getPathToRoot` returns an array of nodes starting from a given node and traversing
* up to the root node, with the option to reverse the order of the nodes.
* @param {N} beginRoot - The `beginRoot` parameter represents the starting node from which you want
* to find the path to the root node.
* Time Complexity: O(log n)
* Space Complexity: O(log n)
*/
/**
* Time Complexity: O(log n)
* Space Complexity: O(log n)
*
* The function `getPathToRoot` returns an array of nodes from a given node to the root of a tree
* structure, with the option to reverse the order of the nodes.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
* starting node from which you want to find the path to the root. It can be of type `BTNKey`, `N`,
* `null`, or `undefined`.
* @param [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the
* resulting path should be reversed or not. If `isReverse` is set to `true`, the path will be
* reversed before returning it. If `isReverse` is set to `false` or not provided, the path will
* @returns The function `getPathToRoot` returns an array of type `N[]`.
* reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is
* @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
*/
getPathToRoot(beginRoot: BTNKey | N | null | undefined, isReverse = true): N[] {
// TODO to support get path through passing key
@ -773,15 +900,23 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* The function `getLeftMost` returns the leftmost node in a binary tree, either using recursive or
* iterative traversal.
* Time Complexity: O(log n)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(log n)
* Space Complexity: O(1)
*
* The function `getLeftMost` returns the leftmost node in a binary tree, either recursively or
* iteratively.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
* for finding the leftmost node in a binary tree. It can be either a node object (`N`), a key value
* of a node (`BTNKey`), or `null` if the tree is empty.
* for finding the leftmost node in a binary tree. It can be either a `BTNKey` (a key value), `N` (a
* node), `null`, or `undefined`. If not provided, it defaults to `this.root`,
* @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
* be performed when finding the leftmost node in a binary tree. It can have two possible values:
* @returns The function `getLeftMost` returns the leftmost node (`N`) in a binary tree. If there is
* no leftmost node, it returns `null`.
* @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
* is no leftmost node, it returns `null` or `undefined` depending on the input.
*/
getLeftMost(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): N | null | undefined {
beginRoot = this.ensureNotKey(beginRoot);
@ -807,15 +942,24 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* Time Complexity: O(log n)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(log n)
* Space Complexity: O(1)
*
* The function `getRightMost` returns the rightmost node in a binary tree, either recursively or
* iteratively.
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node from which we want to
* find the rightmost node. It is of type `N | null | undefined`, which means it can either be a node of type `N`
* or `null`. If it is `null`, it means there is no starting node
* @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
* be performed when finding the rightmost node in a binary tree. It can have two possible values:
* @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If the
* `beginRoot` parameter is `null`, it returns `null`.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
* starting node from which we want to find the rightmost node. It can be of type `BTNKey`, `N`,
* `null`, or `undefined`. If not provided, it defaults to `this.root`, which is a property of the
* current object.
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
* type of iteration to use when finding the rightmost node. It can have one of two values:
* @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
* is no rightmost node, it returns `null` or `undefined`, depending on the input.
*/
getRightMost(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): N | null | undefined {
// TODO support get right most by passing key in
@ -841,13 +985,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
*
* The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.
* @param {N} beginRoot - The `beginRoot` parameter is the root node of the binary tree that you want
* to check if it is a binary search tree (BST) subtree.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the root
* node of the binary search tree (BST) that you want to check if it is a subtree of another BST.
* @param iterationType - The `iterationType` parameter is an optional parameter that specifies the
* type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two
* possible values:
* @returns The function `isSubtreeBST` returns a boolean value.
* @returns a boolean value.
*/
isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType = this.iterationType): boolean {
// TODO there is a bug
@ -881,11 +1033,19 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
*
* The function checks if a binary tree is a binary search tree.
* @param iterationType - The parameter "iterationType" is used to specify the type of iteration to
* be used when checking if the binary tree is a binary search tree (BST). It is an optional
* parameter with a default value of "this.iterationType". The value of "this.iterationType" is not
* provided in
* parameter with a default value of "this.iterationType". The value of "this.iterationType" is
* expected to be
* @returns a boolean value.
*/
isBST(iterationType = this.iterationType): boolean {
@ -914,20 +1074,32 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
includeNull?: true
): ReturnType<C>[];
/**
* Time complexity: O(n)
* Space complexity: O(log n)
*/
/**
* Time complexity: O(n)
* Space complexity: O(log n)
*
* The function `subTreeTraverse` traverses a binary tree and applies a callback function to each
* node, either recursively or iteratively.
* @param callback - The `callback` parameter is a function that will be called on each node in the
* subtree traversal. It takes a single argument, which is the current node being traversed, and
* returns a value. The return values from each callback invocation will be collected and returned as
* an array.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point
* for traversing the subtree. It can be either a node object, a key value of a node, or `null` to
* start from the root of the tree.
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
* the subtree traversal. It takes a single parameter, which is the current node being traversed, and
* returns a value of any type.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
* starting node or key from which the subtree traversal should begin. It can be of type `BTNKey`,
* `N`, `null`, or `undefined`. If not provided, the `root` property of the current object is used as
* the default value.
* @param iterationType - The `iterationType` parameter determines the type of traversal to be
* performed on the binary tree. It can have two possible values:
* @param includeNull - The choice to output null values during binary tree traversal should be provided.
* @returns The function `subTreeTraverse` returns an array of `ReturnType<BTNCallback<N>>`.
* performed on the subtree. It can have two possible values:
* @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
* whether or not to include null values in the traversal. If `includeNull` is set to `true`, the
* traversal will include null values, otherwise it will skip them.
* @returns The function `subTreeTraverse` returns an array of values that are the result of invoking
* the `callback` function on each node in the subtree. The type of the array elements is determined
* by the return type of the `callback` function.
*/
subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
callback: C = this._defaultOneParamCallback as C,
@ -1038,20 +1210,32 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
): ReturnType<C>[];
/**
* The `dfs` function performs a depth-first search traversal on a binary tree, executing a callback
* function on each node according to a specified order pattern.
* @param callback - The `callback` parameter is a function that will be called on each node during
* the depth-first search traversal. It takes a node as input and returns a value. The default value
* is `this._defaultOneParamCallback`, which is a callback function defined elsewhere in the code.
* Time complexity: O(n)
* Space complexity: O(n)
*/
/**
* Time complexity: O(n)
* Space complexity: O(n)
*
* The `dfs` function performs a depth-first search traversal on a binary tree or graph, based on the
* specified pattern and iteration type, and returns an array of values obtained from applying a
* callback function to each visited node.
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
* the tree during the depth-first search. It takes a single parameter, which can be of type `N`,
* `null`, or `undefined`, and returns a value of any type. The default value for this parameter is
* @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the
* nodes are visited during the depth-first search. There are three possible values for `pattern`:
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the depth-first
* search. It determines where the search will begin in the tree or graph structure. If `beginRoot`
* is `null`, an empty array will be returned.
* nodes are traversed during the depth-first search. It can have one of the following values:
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
* for the depth-first search traversal. It can be specified as a key, a node object, or
* `null`/`undefined`. If not provided, the `beginRoot` will default to the root node of the tree.
* @param {IterationType} iterationType - The `iterationType` parameter determines the type of
* iteration used in the depth-first search algorithm. It can have two possible values:
* @param includeNull - The choice to output null values during binary tree traversal should be provided.
* @returns The function `dfs` returns an array of `ReturnType<BTNCallback<N>>` values.
* iteration to use when traversing the tree. It can have one of the following values:
* @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
* whether null or undefined nodes should be included in the traversal. If `includeNull` is set to
* `true`, null or undefined nodes will be included in the traversal. If `includeNull` is set to
* `false`, null or undefined
* @returns an array of values that are the return values of the callback function.
*/
dfs<C extends BTNCallback<N | null | undefined>>(
callback: C = this._defaultOneParamCallback as C,
@ -1171,18 +1355,30 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
): ReturnType<C>[];
/**
* The bfs function performs a breadth-first search traversal on a binary tree, executing a callback
* function on each node.
* @param callback - The `callback` parameter is a function that will be called for each node in the
* breadth-first search. It takes a node of type `N` as its argument and returns a value of type
* `ReturnType<BTNCallback<N>>`. The default value for this parameter is `this._defaultOneParamCallback
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
* search. It determines from which node the search will begin. If `beginRoot` is `null`, the search
* will not be performed and an empty array will be returned.
* @param iterationType - The `iterationType` parameter determines the type of iteration to be used
* in the breadth-first search (BFS) algorithm. It can have two possible values:
* @param includeNull - The choice to output null values during binary tree traversal should be provided.
* @returns The function `bfs` returns an array of `ReturnType<BTNCallback<N>>[]`.
* Time complexity: O(n)
* Space complexity: O(n)
*/
/**
* Time complexity: O(n)
* Space complexity: O(n)
*
* The `bfs` function performs a breadth-first search traversal on a binary tree, executing a
* callback function on each node.
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
* the breadth-first search traversal. It takes a single parameter, which is the current node being
* visited, and returns a value of any type.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
* starting node for the breadth-first search traversal. It can be specified as a key, a node object,
* or `null`/`undefined` to indicate the root of the tree. If not provided, the `root` property of
* the class is used as
* @param iterationType - The `iterationType` parameter determines the type of iteration to be
* performed during the breadth-first search (BFS). It can have two possible values:
* @param [includeNull=false] - The `includeNull` parameter is a boolean flag that determines whether
* or not to include null values in the breadth-first search traversal. If `includeNull` is set to
* `true`, null values will be included in the traversal, otherwise they will be skipped.
* @returns an array of values that are the result of invoking the callback function on each node in
* the breadth-first traversal of a binary tree.
*/
bfs<C extends BTNCallback<N | null | undefined>>(
callback: C = this._defaultOneParamCallback as C,
@ -1260,20 +1456,31 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
): ReturnType<C>[][];
/**
* The `listLevels` function takes a binary tree node and a callback function, and returns an array
* of arrays representing the levels of the tree.
* @param {C} callback - The `callback` parameter is a function that will be called on each node in
* the tree. It takes a node as input and returns a value. The return type of the callback function
* is determined by the generic type `C`.
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter represents the starting node of the binary tree
* traversal. It can be any node in the binary tree. If no node is provided, the traversal will start
* from the root node of the binary tree.
* @param iterationType - The `iterationType` parameter determines whether the tree traversal is done
* recursively or iteratively. It can have two possible values:
* @param includeNull - The choice to output null values during binary tree traversal should be provided.
* @returns The function `listLevels` returns an array of arrays, where each inner array represents a
* level in a binary tree. Each inner array contains the return type of the provided callback
* function `C` applied to the nodes at that level.
* Time complexity: O(n)
* Space complexity: O(n)
*/
/**
* Time complexity: O(n)
* Space complexity: O(n)
*
* The `listLevels` function returns an array of arrays, where each inner array represents a level in
* a binary tree and contains the values returned by a callback function applied to the nodes at that
* level.
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
* the tree. It takes a single parameter, which can be of type `N`, `null`, or `undefined`, and
* returns a value of any type.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter represents the
* starting node for traversing the tree. It can be either a node object (`N`), a key value
* (`BTNKey`), `null`, or `undefined`. If not provided, it defaults to the root node of the tree.
* @param iterationType - The `iterationType` parameter determines the type of iteration to be
* performed on the tree. It can have two possible values:
* @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
* whether or not to include null values in the resulting levels. If `includeNull` is set to `true`,
* null values will be included in the levels. If `includeNull` is set to `false`, null values will
* be excluded
* @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.
*/
listLevels<C extends BTNCallback<N | null | undefined>>(
callback: C = this._defaultOneParamCallback as C,
@ -1324,10 +1531,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
getPredecessor(node: N ): N
/**
* The function returns the predecessor node of a given node in a binary tree.
* @param {N} node - The parameter "node" represents a node in a binary tree.
* @returns The function `getPredecessor` returns the predecessor node of the given node `node`.
* The function `getPredecessor` returns the predecessor node of a given node in a binary tree.
* @param {BTNKey | N | null | undefined} node - The `node` parameter can be of type `BTNKey`, `N`,
* `null`, or `undefined`.
* @returns The function `getPredecessor` returns a value of type `N | undefined`.
*/
getPredecessor(node: BTNKey | N | null | undefined): N | undefined{
node = this.ensureNotKey(node);
@ -1346,12 +1555,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
}
/**
* The function `getSuccessor` returns the next node in a binary tree given a node `x`, or `null` if
* `x` is the last node.
* @param {N} x - N - a node in a binary tree
* @returns The function `getSuccessor` returns a value of type `N` (the successor node), or `null`
* if there is no successor, or `undefined` if the input `x` is `undefined`.
* The function `getSuccessor` returns the next node in a binary tree given a current node.
* @param {BTNKey | N | null} [x] - The parameter `x` can be of type `BTNKey`, `N`, or `null`.
* @returns the successor of the given node or key. The successor is the node that comes immediately
* after the given node in the inorder traversal of the binary tree.
*/
getSuccessor(x?: BTNKey | N | null): N | null | undefined {
x = this.ensureNotKey(x);
@ -1370,18 +1579,27 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
/**
* The `morris` function performs a depth-first traversal of a binary tree using the Morris traversal
* algorithm and returns an array of values obtained by applying a callback function to each node.
* @param callback - The `callback` parameter is a function that will be called on each node in the
* tree. It takes a node of type `N` as input and returns a value of type `ReturnType<BTNCallback<N>>`. The
* default value for this parameter is `this._defaultOneParamCallback`.
* Time complexity: O(n)
* Space complexity: O(1)
*/
/**
* Time complexity: O(n)
* Space complexity: O(1)
* The `morris` function performs a depth-first traversal on a binary tree using the Morris traversal
* algorithm.
* @param {C} callback - The `callback` parameter is a function that will be called for each node in
* the tree. It takes a single parameter of type `N` (the type of the nodes in the tree) and returns
* a value of any type.
* @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
* determines the order in which the nodes of a binary tree are traversed. It can have one of the
* following values:
* @param {N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node for the Morris
* traversal. It specifies the root node of the tree from which the traversal should begin. If
* `beginRoot` is `null`, an empty array will be returned.
* @returns The `morris` function returns an array of `ReturnType<BTNCallback<N>>` values.
* @param {BTNKey | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node
* for the traversal. It can be specified as a key, a node object, or `null`/`undefined` to indicate
* the root of the tree. If no value is provided, the default value is the root of the tree.
* @returns The function `morris` returns an array of values that are the result of invoking the
* `callback` function on each node in the binary tree. The type of the array elements is determined
* by the return type of the `callback` function.
*/
morris<C extends BTNCallback<N>>(
callback: C = this._defaultOneParamCallback as C,
@ -1469,7 +1687,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
return ans;
}
// --- start additional methods ---
/**
* The above function is an iterator for a binary tree that can be used to traverse the tree in
@ -1502,12 +1719,10 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
}
} else {
if (node.left) {
// @ts-ignore
yield* this[Symbol.iterator](node.left);
}
yield node.key;
if (node.right) {
// @ts-ignore
yield* this[Symbol.iterator](node.right);
}
}
@ -1593,11 +1808,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
this._root = v;
}
/**
* The `print` function is used to display a binary tree structure in a visually appealing way.
* @param {N | null | undefined} root - The `root` parameter in the `print` function represents the
* root node of a binary tree. It can have one of the following types: `BTNKey`, `N`, `null`, or
* `undefined`. The default value is `this.root`, which suggests that `this.root` is the
* @param {N | null | undefined} root - The `root` parameter is of type `BTNKey | N | null |
* undefined`. It represents the root node of a binary tree. The root node can have one of the
* following types:
*/
print(beginRoot: BTNKey | N | null | undefined = this.root): void {
beginRoot = this.ensureNotKey(beginRoot);
@ -1611,11 +1827,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
};
const _displayAux = (node: N | null | undefined): [string[], number, number, number] => {
if (node === undefined || node === null) {
if (!this.isRealNode(node)) {
return [[], 0, 0, 0];
}
if (node && node.right === undefined && node.left === undefined) {
if (this.isRealNode(node) && !this.isRealNode(node.right) && !this.isRealNode(node.left)) {
const line = `${node.key}`;
const width = line.length;
const height = 1;
@ -1623,7 +1839,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
return [[line], width, height, middle];
}
if (node && node.right === undefined) {
if (this.isRealNode(node) && !this.isRealNode(node.right)) {
const [lines, n, p, x] = _displayAux(node.left);
const s = `${node.key}`;
const u = s.length;
@ -1633,7 +1849,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
return [[first_line, second_line, ...shifted_lines], n + u, p + 2, n + Math.floor(u / 2)];
}
if (node && node.left === undefined) {
if (this.isRealNode(node) && !this.isRealNode(node.left)) {
const [lines, n, p, u] = _displayAux(node.right);
const s = `${node.key}`;
const x = s.length;
@ -1660,5 +1876,4 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
display(beginRoot);
}
// --- end additional methods ---
}

View file

@ -28,13 +28,13 @@
const queue = new Queue();
for (let i = 0; i < 1000000; i++) {
for (let i = 0; i < 100000; i++) {
queue.enqueue(i);
}
let last = 0;
const startTime = performance.now();
for (let i = 0; i < 1000000; i++) {
for (let i = 0; i < 100000; i++) {
last = queue.dequeue();
}
@ -44,6 +44,28 @@
console.error(e);
}
try {
const {BinaryTree} = dataStructureTyped;
const tree = new BinaryTree();
tree.add(3);
tree.add(12);
tree.addMany([1, 6, 9, 8,5,2,3,4,7])
tree.add(10);
console.log(tree.isPerfectlyBalanced());
tree.print();
const node3 = tree.getNode(3);
if (node3) node3.right = tree.createNode(1);
console.log(tree.isPerfectlyBalanced());
tree.print();
tree.clear();
tree.addMany([1, null, 2, null, 3, null, 4, null, 5, null, 6, null]);
console.log(tree.isPerfectlyBalanced());
tree.print();
} catch (e) {
console.error(e);
}
</script>
</body>

View file

@ -1,4 +1,5 @@
import {BinaryTree, BinaryTreeNode, IterationType} from '../../../../src';
import {getRandomIntArray} from "../../../utils";
// import {isDebugTest} from '../../../config';
// const isDebug = isDebugTest;
@ -112,6 +113,24 @@ describe('BinaryTree', () => {
expect(tree.has('3', node => node.value?.toString())).toBe(true);
});
it('should be a balance tree after malicious manipulation', () => {
tree.add(3);
tree.add(12);
tree.addMany(getRandomIntArray(100, 1, 100))
tree.add(10);
expect(tree.isPerfectlyBalanced()).toBe(true);
const node3 = tree.getNode(3);
if (node3) node3.right = tree.createNode(1);
expect(tree.isPerfectlyBalanced()).toBe(false);
tree.clear();
tree.addMany([1, null, 2, null, 3, null, 4, null, 5, null, 6, null]);
expect(tree.isPerfectlyBalanced()).toBe(false);
});
it('should getDepth return correct depth', () => {
tree.add(1);
expect(tree.getDepth(1)).toBe(0);
@ -480,10 +499,8 @@ describe('BinaryTree', () => {
tree.add(7, 'C');
tree.iterationType = IterationType.ITERATIVE;
// @ts-ignore
expect([...tree]).toEqual([3, 5, 7]);
tree.iterationType = IterationType.RECURSIVE;
// @ts-ignore
expect([...tree]).toEqual([3, 5, 7]);
tree.iterationType = IterationType.ITERATIVE;

View file

@ -54,7 +54,6 @@ describe('DoublyLinkedList Operation Test', () => {
});
it('should insertAfter tail', () => {
// @ts-ignore
expect([...list]).toEqual([1, 2, 3, 4, 5]);
});
});

View file

@ -441,7 +441,6 @@ describe('SinglyLinkedList', () => {
list.push(3);
const array = list.toArray();
expect(array).toEqual([1, 2, 3]);
// @ts-ignore
expect([...list]).toEqual([1, 2, 3]);
});