mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
feat: Add an 'elements' parameter to the constructors of all binary tree data structures to accept Iterable types.
This commit is contained in:
parent
8f9eb82bfd
commit
4930f87bcd
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
import { BST, BSTNode } from './bst';
|
||||
import type { AVLTreeNested, AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey } from '../../types';
|
||||
import { BTNCallback, IterationType } from '../../types';
|
||||
import { BTNCallback, IterableEntriesOrKeys } from '../../types';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
|
||||
export class AVLTreeNode<V = any, N extends AVLTreeNode<V, N> = AVLTreeNodeNested<V>> extends BSTNode<V, N> {
|
||||
|
@ -23,21 +23,15 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
extends BST<V, N, TREE>
|
||||
implements IBinaryTree<V, N, TREE> {
|
||||
|
||||
override options: AVLTreeOptions;
|
||||
|
||||
/**
|
||||
* This is a constructor function for an AVL tree data structure in TypeScript.
|
||||
* @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the
|
||||
* constructor of the AVLTree class. It allows you to customize the behavior of the AVL tree by providing different
|
||||
* options.
|
||||
*/
|
||||
constructor(options?: AVLTreeOptions) {
|
||||
super(options);
|
||||
if (options) {
|
||||
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options }
|
||||
} else {
|
||||
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b };
|
||||
}
|
||||
constructor(elements?: IterableEntriesOrKeys<V>, options?: Partial<AVLTreeOptions>) {
|
||||
super([], options);
|
||||
if (elements) this.init(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,14 +48,12 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
}
|
||||
|
||||
override createTree(options?: AVLTreeOptions): TREE {
|
||||
return new AVLTree<V, N, TREE>({ ...this.options, ...options }) as TREE;
|
||||
return new AVLTree<V, N, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
comparator: this.comparator, ...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
|
@ -82,7 +74,7 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The delete method of the superclass (BST) has logarithmic time complexity.
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
*/
|
||||
|
||||
|
@ -115,6 +107,24 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
return deletedResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The delete method of the superclass (BST) has logarithmic time complexity.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
*/
|
||||
|
||||
init(elements: IterableEntriesOrKeys<V>): void {
|
||||
if (elements) {
|
||||
for (const entryOrKey of elements) {
|
||||
if (Array.isArray(entryOrKey)) {
|
||||
const [key, value] = entryOrKey;
|
||||
this.add(key, value);
|
||||
} else {
|
||||
this.add(entryOrKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `_swap` function swaps the key, value, and height properties between two nodes in a binary
|
||||
* tree.
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
BiTreeDeleteResult,
|
||||
DFSOrderPattern,
|
||||
FamilyPosition,
|
||||
IterableEntriesOrKeys,
|
||||
IterationType,
|
||||
NodeDisplayLayout
|
||||
} from '../../types';
|
||||
|
@ -118,20 +119,24 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
|
|||
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>, TREE extends BinaryTree<V, N, TREE> = BinaryTree<V, N, BinaryTreeNested<V, N>>>
|
||||
implements IBinaryTree<V, N, TREE> {
|
||||
|
||||
options: BinaryTreeOptions;
|
||||
iterationType = IterationType.ITERATIVE
|
||||
|
||||
/**
|
||||
* Creates a new instance of BinaryTree.
|
||||
* @param {BinaryTreeOptions} [options] - The options for the binary tree.
|
||||
*/
|
||||
constructor(options?: BinaryTreeOptions) {
|
||||
constructor(elements?: IterableEntriesOrKeys<V>, options?: Partial<BinaryTreeOptions>) {
|
||||
|
||||
if (options) {
|
||||
this.options = { iterationType: IterationType.ITERATIVE, ...options }
|
||||
} else {
|
||||
this.options = { iterationType: IterationType.ITERATIVE };
|
||||
const { iterationType } = options;
|
||||
if (iterationType) {
|
||||
this.iterationType = iterationType;
|
||||
}
|
||||
}
|
||||
|
||||
this._size = 0;
|
||||
|
||||
if (elements) this.init(elements);
|
||||
}
|
||||
|
||||
protected _root?: N | null;
|
||||
|
@ -162,16 +167,10 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return new BinaryTreeNode<V, N>(key, value) as N;
|
||||
}
|
||||
|
||||
createTree(options?: BinaryTreeOptions): TREE {
|
||||
return new BinaryTree<V, N, TREE>({ ...this.options, ...options }) as TREE;
|
||||
createTree(options?: Partial<BinaryTreeOptions>): TREE {
|
||||
return new BinaryTree<V, N, TREE>([], { iterationType: this.iterationType, ...options }) as TREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
@ -228,8 +227,9 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -284,17 +284,17 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return keysOrNodes.length === this.addMany(keysOrNodes, values).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
delete<C extends BTNCallback<N, BTNKey>>(identifier: BTNKey, callback?: C): BiTreeDeleteResult<N>[];
|
||||
|
||||
delete<C extends BTNCallback<N, N>>(identifier: N | null | undefined, callback?: C): BiTreeDeleteResult<N>[];
|
||||
|
||||
delete<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C): BiTreeDeleteResult<N>[];
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(1)
|
||||
|
@ -394,8 +394,7 @@ 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)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -412,7 +411,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* values:
|
||||
* @returns the height of the binary tree.
|
||||
*/
|
||||
getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.options.iterationType): number {
|
||||
getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number {
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
if (!beginRoot) return -1;
|
||||
|
||||
|
@ -461,7 +460,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* 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.
|
||||
*/
|
||||
getMinHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.options.iterationType): number {
|
||||
getMinHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number {
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
if (!beginRoot) return -1;
|
||||
|
||||
|
@ -507,6 +506,7 @@ 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -524,6 +524,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n)
|
||||
*/
|
||||
|
||||
getNodes<C extends BTNCallback<N, BTNKey>>(
|
||||
identifier: BTNKey,
|
||||
callback?: C,
|
||||
|
@ -548,11 +553,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
iterationType?: IterationType
|
||||
): N[];
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n).
|
||||
|
@ -583,7 +583,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
callback: C = this._defaultOneParamCallback as C,
|
||||
onlyOne = false,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): N[] {
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
||||
callback = (node => node) as C;
|
||||
|
@ -622,6 +622,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n).
|
||||
*/
|
||||
|
||||
has<C extends BTNCallback<N, BTNKey>>(
|
||||
identifier: BTNKey,
|
||||
callback?: C,
|
||||
|
@ -643,11 +648,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
iterationType?: IterationType
|
||||
): boolean;
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
*
|
||||
|
@ -672,7 +672,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
identifier: ReturnType<C> | null | undefined,
|
||||
callback: C = this._defaultOneParamCallback as C,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): boolean {
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
||||
callback = (node => node) as C;
|
||||
|
@ -680,6 +680,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n).
|
||||
*/
|
||||
|
||||
getNode<C extends BTNCallback<N, BTNKey>>(
|
||||
identifier: BTNKey,
|
||||
callback?: C,
|
||||
|
@ -701,11 +706,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
iterationType?: IterationType
|
||||
): N | null | undefined;
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n)
|
||||
|
@ -731,7 +731,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
identifier: ReturnType<C> | null | undefined,
|
||||
callback: C = this._defaultOneParamCallback as C,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): N | null | undefined {
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
||||
callback = (node => node) as C;
|
||||
|
@ -783,6 +783,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function `ensureNotKey` returns the node corresponding to the given key if it is a valid node
|
||||
* key, otherwise it returns the key itself.
|
||||
|
@ -819,11 +824,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
iterationType?: IterationType
|
||||
): V | undefined;
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n)
|
||||
|
@ -850,7 +850,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
identifier: ReturnType<C> | null | undefined,
|
||||
callback: C = this._defaultOneParamCallback as C,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): V | undefined {
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
||||
callback = (node => node) as C;
|
||||
|
@ -858,6 +858,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Clear the binary tree, removing all nodes.
|
||||
*/
|
||||
|
@ -874,11 +879,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return this.size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(log n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(log n)
|
||||
|
@ -912,7 +912,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
|
||||
/**
|
||||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(1)
|
||||
* Space Complexity: O(log n)
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -931,7 +931,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
*/
|
||||
getLeftMost(
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): N | null | undefined {
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
|
||||
|
@ -977,7 +977,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
*/
|
||||
getRightMost(
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): N | null | undefined {
|
||||
// TODO support get right most by passing key in
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
|
@ -1002,7 +1002,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
|
@ -1018,7 +1018,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* possible values:
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType = this.options.iterationType): boolean {
|
||||
isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType = this.iterationType): boolean {
|
||||
// TODO there is a bug
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
if (!beginRoot) return true;
|
||||
|
@ -1065,11 +1065,16 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* expected to be
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
isBST(iterationType = this.options.iterationType): boolean {
|
||||
isBST(iterationType = this.iterationType): boolean {
|
||||
if (this.root === null) return true;
|
||||
return this.isSubtreeBST(this.root, iterationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
subTreeTraverse<C extends BTNCallback<N>>(
|
||||
callback?: C,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
|
@ -1091,11 +1096,6 @@ 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)
|
||||
|
@ -1121,7 +1121,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
|
||||
callback: C = this._defaultOneParamCallback as C,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.options.iterationType,
|
||||
iterationType = this.iterationType,
|
||||
includeNull = false
|
||||
): ReturnType<C>[] {
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
|
@ -1164,6 +1164,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(log n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function checks if a given node is a real node by verifying if it is an instance of
|
||||
* BinaryTreeNode and its key is not NaN.
|
||||
|
@ -1226,11 +1231,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
includeNull?: true
|
||||
): ReturnType<C>[];
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
|
@ -1349,6 +1349,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
*/
|
||||
|
||||
bfs<C extends BTNCallback<N>>(
|
||||
callback?: C,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
|
@ -1370,11 +1375,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
includeNull?: true
|
||||
): ReturnType<C>[];
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
|
@ -1399,7 +1399,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
bfs<C extends BTNCallback<N | null | undefined>>(
|
||||
callback: C = this._defaultOneParamCallback as C,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.options.iterationType,
|
||||
iterationType = this.iterationType,
|
||||
includeNull = false
|
||||
): ReturnType<C>[] {
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
|
@ -1450,6 +1450,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
*/
|
||||
|
||||
listLevels<C extends BTNCallback<N>>(
|
||||
callback?: C,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
|
@ -1471,11 +1476,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
includeNull?: true
|
||||
): ReturnType<C>[][];
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
|
@ -1500,7 +1500,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
listLevels<C extends BTNCallback<N | null | undefined>>(
|
||||
callback: C = this._defaultOneParamCallback as C,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.options.iterationType,
|
||||
iterationType = this.iterationType,
|
||||
includeNull = false
|
||||
): ReturnType<C>[][] {
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
|
@ -1544,6 +1544,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return levelsNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
*/
|
||||
|
||||
getPredecessor(node: N): N;
|
||||
|
||||
/**
|
||||
|
@ -1591,11 +1596,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(1)
|
||||
|
@ -1700,6 +1700,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* The `forEach` function iterates over each entry in a tree and calls a callback function with the
|
||||
* entry and the tree as arguments.
|
||||
|
@ -1730,15 +1735,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return newTree;
|
||||
}
|
||||
|
||||
// TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
|
||||
// map<NV>(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) {
|
||||
// const newTree = this.createTree();
|
||||
// for (const [key, value] of this) {
|
||||
// newTree.add(key, callback([key, value], this));
|
||||
// }
|
||||
// return newTree;
|
||||
// }
|
||||
|
||||
/**
|
||||
* The `map` function creates a new tree by applying a callback function to each entry in the current
|
||||
* tree.
|
||||
|
@ -1753,6 +1749,15 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return newTree;
|
||||
}
|
||||
|
||||
// TODO Type error, need to return a TREE<NV> that is a value type only for callback function.
|
||||
// map<NV>(callback: (entry: [BTNKey, V | undefined], tree: this) => NV) {
|
||||
// const newTree = this.createTree();
|
||||
// for (const [key, value] of this) {
|
||||
// newTree.add(key, callback([key, value], this));
|
||||
// }
|
||||
// return newTree;
|
||||
// }
|
||||
|
||||
/**
|
||||
* The `reduce` function iterates over the entries of a tree and applies a callback function to each
|
||||
* entry, accumulating a single value.
|
||||
|
@ -1773,7 +1778,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return accumulator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The above function is an iterator for a binary tree that can be used to traverse the tree in
|
||||
* either an iterative or recursive manner.
|
||||
|
@ -1786,7 +1790,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* [Symbol.iterator](node = this.root): Generator<[BTNKey, V | undefined], void, undefined> {
|
||||
if (!node) return;
|
||||
|
||||
if (this.options.iterationType === IterationType.ITERATIVE) {
|
||||
if (this.iterationType === IterationType.ITERATIVE) {
|
||||
const stack: (N | null | undefined)[] = [];
|
||||
let current: N | null | undefined = node;
|
||||
|
||||
|
@ -1843,6 +1847,19 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
display(beginRoot);
|
||||
}
|
||||
|
||||
init(elements: IterableEntriesOrKeys<V>): void {
|
||||
if (elements) {
|
||||
for (const entryOrKey of elements) {
|
||||
if (Array.isArray(entryOrKey)) {
|
||||
const [key, value] = entryOrKey;
|
||||
this.add(key, value);
|
||||
} else {
|
||||
this.add(entryOrKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected _displayAux(node: N | null | undefined, options: BinaryTreePrintOptions): NodeDisplayLayout {
|
||||
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
||||
const emptyDisplayLayout = <NodeDisplayLayout>[['─'], 1, 0, 0];
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { BSTNested, BSTNodeNested, BSTOptions, BTNCallback, BTNKey } from '../../types';
|
||||
import { CP, IterationType } from '../../types';
|
||||
import type { BSTNested, BSTNodeNested, BSTOptions, BTNCallback, BTNKey, Comparator } from '../../types';
|
||||
import { CP, IterableEntriesOrKeys, IterationType } from '../../types';
|
||||
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { Queue } from '../queue';
|
||||
|
@ -66,21 +66,23 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
extends BinaryTree<V, N, TREE>
|
||||
implements IBinaryTree<V, N, TREE> {
|
||||
|
||||
override options: BSTOptions;
|
||||
|
||||
/**
|
||||
* The constructor function initializes a binary search tree with an optional comparator function.
|
||||
* @param {BSTOptions} [options] - An optional object that contains additional configuration options
|
||||
* for the binary search tree.
|
||||
*/
|
||||
constructor(options?: BSTOptions) {
|
||||
super(options);
|
||||
constructor(elements?: IterableEntriesOrKeys<V>, options?: Partial<BSTOptions>) {
|
||||
super([], options);
|
||||
|
||||
if (options) {
|
||||
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options }
|
||||
} else {
|
||||
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b };
|
||||
const { comparator } = options;
|
||||
if (comparator) {
|
||||
this.comparator = comparator;
|
||||
}
|
||||
}
|
||||
|
||||
this._root = undefined;
|
||||
if (elements) this.init(elements);
|
||||
}
|
||||
|
||||
protected override _root?: N;
|
||||
|
@ -92,6 +94,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
return this._root;
|
||||
}
|
||||
|
||||
comparator: Comparator<BTNKey> = (a, b) => a - b
|
||||
|
||||
/**
|
||||
* The function creates a new binary search tree node with the given key and value.
|
||||
* @param {BTNKey} key - The key parameter is the key value that will be associated with
|
||||
|
@ -104,15 +108,13 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
return new BSTNode<V, N>(key, value) as N;
|
||||
}
|
||||
|
||||
override createTree(options?: BSTOptions): TREE {
|
||||
return new BST<V, N, TREE>({ ...this.options, ...options }) as TREE;
|
||||
override createTree(options?: Partial<BSTOptions>): TREE {
|
||||
return new BST<V, N, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
comparator: this.comparator, ...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).
|
||||
* Space Complexity: O(1) - Constant space is used.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).
|
||||
* Space Complexity: O(1) - Constant space is used.
|
||||
|
@ -193,8 +195,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
|
||||
* Space Complexity: O(n) - Additional space is required for the sorted array.
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).
|
||||
* Space Complexity: O(1) - Constant space is used.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -221,7 +223,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
keysOrNodes: (BTNKey | N | undefined)[],
|
||||
data?: (V | undefined)[],
|
||||
isBalanceAdd = true,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): (N | undefined)[] {
|
||||
// TODO this addMany function is inefficient, it should be optimized
|
||||
function hasNoUndefined(arr: (BTNKey | N | undefined)[]): arr is (BTNKey | N)[] {
|
||||
|
@ -297,8 +299,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree.
|
||||
* Space Complexity: O(1) - Constant space is used.
|
||||
* Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
|
||||
* Space Complexity: O(n) - Additional space is required for the sorted array.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -316,7 +318,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
* the key of the leftmost node if the comparison result is greater than, and the key of the
|
||||
* rightmost node otherwise. If no node is found, it returns 0.
|
||||
*/
|
||||
lastKey(beginRoot: BTNKey | N | undefined = this.root, iterationType = this.options.iterationType): BTNKey {
|
||||
lastKey(beginRoot: BTNKey | N | undefined = this.root, iterationType = this.iterationType): BTNKey {
|
||||
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;
|
||||
|
@ -324,7 +326,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
|
||||
/**
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree.
|
||||
* Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
|
||||
* Space Complexity: O(1) - Constant space is used.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -366,6 +368,11 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree.
|
||||
* Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function `ensureNotKey` returns the node corresponding to the given key if it is a node key,
|
||||
* otherwise it returns the key itself.
|
||||
|
@ -379,11 +386,6 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.
|
||||
* Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.
|
||||
* Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
|
||||
|
@ -412,7 +414,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
callback: C = this._defaultOneParamCallback as C,
|
||||
onlyOne = false,
|
||||
beginRoot: BTNKey | N | undefined = this.root,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): N[] {
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
|
@ -493,7 +495,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
callback: C = this._defaultOneParamCallback as C,
|
||||
lesserOrGreater: CP = CP.lt,
|
||||
targetNode: BTNKey | N | undefined = this.root,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): ReturnType<C>[] {
|
||||
targetNode = this.ensureNotKey(targetNode);
|
||||
const ans: ReturnType<BTNCallback<N>>[] = [];
|
||||
|
@ -531,18 +533,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
}
|
||||
|
||||
/**
|
||||
* Balancing Adjustment:
|
||||
* Perfectly Balanced Binary Tree: Since the balance of a perfectly balanced binary tree is already fixed, no additional balancing adjustment is needed. Any insertion or deletion operation will disrupt the perfect balance, often requiring a complete reconstruction of the tree.
|
||||
* AVL Tree: After insertion or deletion operations, an AVL tree performs rotation adjustments based on the balance factor of nodes to restore the tree's balance. These rotations can be left rotations, right rotations, left-right rotations, or right-left rotations, performed as needed.
|
||||
*
|
||||
* Use Cases and Efficiency:
|
||||
* Perfectly Balanced Binary Tree: Perfectly balanced binary trees are typically used in specific scenarios such as complete binary heaps in heap sort or certain types of Huffman trees. However, they are not suitable for dynamic operations requiring frequent insertions and deletions, as these operations often necessitate full tree reconstruction.
|
||||
* AVL Tree: AVL trees are well-suited for scenarios involving frequent searching, insertion, and deletion operations. Through rotation adjustments, AVL trees maintain their balance, ensuring average and worst-case time complexity of O(log n).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n) - Building a balanced tree from a sorted array.
|
||||
* Space Complexity: O(n) - Additional space is required for the sorted array.
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.
|
||||
* Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -556,7 +548,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
* values:
|
||||
* @returns The function `perfectlyBalance` returns a boolean value.
|
||||
*/
|
||||
perfectlyBalance(iterationType = this.options.iterationType): boolean {
|
||||
perfectlyBalance(iterationType = this.iterationType): boolean {
|
||||
const sorted = this.dfs(node => node, 'in'),
|
||||
n = sorted.length;
|
||||
this.clear();
|
||||
|
@ -595,8 +587,18 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n) - Visiting each node once.
|
||||
* Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
|
||||
* Balancing Adjustment:
|
||||
* Perfectly Balanced Binary Tree: Since the balance of a perfectly balanced binary tree is already fixed, no additional balancing adjustment is needed. Any insertion or deletion operation will disrupt the perfect balance, often requiring a complete reconstruction of the tree.
|
||||
* AVL Tree: After insertion or deletion operations, an AVL tree performs rotation adjustments based on the balance factor of nodes to restore the tree's balance. These rotations can be left rotations, right rotations, left-right rotations, or right-left rotations, performed as needed.
|
||||
*
|
||||
* Use Cases and Efficiency:
|
||||
* Perfectly Balanced Binary Tree: Perfectly balanced binary trees are typically used in specific scenarios such as complete binary heaps in heap sort or certain types of Huffman trees. However, they are not suitable for dynamic operations requiring frequent insertions and deletions, as these operations often necessitate full tree reconstruction.
|
||||
* AVL Tree: AVL trees are well-suited for scenarios involving frequent searching, insertion, and deletion operations. Through rotation adjustments, AVL trees maintain their balance, ensuring average and worst-case time complexity of O(log n).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n) - Building a balanced tree from a sorted array.
|
||||
* Space Complexity: O(n) - Additional space is required for the sorted array.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -608,7 +610,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
* to check if the AVL tree is balanced. It can have two possible values:
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
isAVLBalanced(iterationType = this.options.iterationType): boolean {
|
||||
isAVLBalanced(iterationType = this.iterationType): boolean {
|
||||
if (!this.root) return true;
|
||||
|
||||
let balanced = true;
|
||||
|
@ -652,6 +654,24 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
return balanced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n) - Visiting each node once.
|
||||
* Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
|
||||
*/
|
||||
|
||||
init(elements: IterableEntriesOrKeys<V>): void {
|
||||
if (elements) {
|
||||
for (const entryOrKey of elements) {
|
||||
if (Array.isArray(entryOrKey)) {
|
||||
const [key, value] = entryOrKey;
|
||||
this.add(key, value);
|
||||
} else {
|
||||
this.add(entryOrKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected _setRoot(v: N | undefined) {
|
||||
if (v) {
|
||||
v.parent = undefined;
|
||||
|
@ -668,7 +688,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
* than), CP.lt (less than), or CP.eq (equal).
|
||||
*/
|
||||
protected _compare(a: BTNKey, b: BTNKey): CP {
|
||||
const compared = this.options.comparator!(a, b);
|
||||
const compared = this.comparator(a, b);
|
||||
if (compared > 0) return CP.gt;
|
||||
else if (compared < 0) return CP.lt;
|
||||
else return CP.eq;
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
BiTreeDeleteResult,
|
||||
BTNCallback,
|
||||
BTNKey,
|
||||
IterableEntriesOrKeys,
|
||||
IterationType,
|
||||
RBTNColor,
|
||||
RBTreeOptions,
|
||||
|
@ -43,21 +44,18 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|||
extends BST<V, N, TREE>
|
||||
implements IBinaryTree<V, N, TREE> {
|
||||
Sentinel: N = new RedBlackTreeNode<V>(NaN) as unknown as N;
|
||||
override options: RBTreeOptions;
|
||||
|
||||
|
||||
/**
|
||||
* The constructor function initializes a Red-Black Tree with an optional set of options.
|
||||
* @param {RBTreeOptions} [options] - The `options` parameter is an optional object that can be
|
||||
* passed to the constructor. It is used to configure the RBTree object with specific options.
|
||||
*/
|
||||
constructor(options?: RBTreeOptions) {
|
||||
super(options);
|
||||
if (options) {
|
||||
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options }
|
||||
} else {
|
||||
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b };
|
||||
}
|
||||
constructor(elements?: IterableEntriesOrKeys<V>, options?: Partial<RBTreeOptions>) {
|
||||
super([], options);
|
||||
|
||||
this._root = this.Sentinel;
|
||||
if (elements) this.init(elements);
|
||||
}
|
||||
|
||||
protected _root: N;
|
||||
|
@ -77,14 +75,12 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|||
}
|
||||
|
||||
override createTree(options?: RBTreeOptions): TREE {
|
||||
return new RedBlackTree<V, N, TREE>({ ...this.options, ...options }) as TREE;
|
||||
return new RedBlackTree<V, N, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
comparator: this.comparator, ...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) on average (where n is the number of nodes in the tree)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) on average (where n is the number of nodes in the tree)
|
||||
* Space Complexity: O(1)
|
||||
|
@ -235,6 +231,11 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) on average (where n is the number of nodes in the tree)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
override isRealNode(node: N | undefined): node is N {
|
||||
return node !== this.Sentinel && node !== undefined;
|
||||
}
|
||||
|
@ -260,11 +261,6 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|||
iterationType?: IterationType
|
||||
): N | undefined;
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) on average (where n is the number of nodes in the tree)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) on average (where n is the number of nodes in the tree)
|
||||
* Space Complexity: O(1)
|
||||
|
@ -290,7 +286,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|||
identifier: ReturnType<C> | undefined,
|
||||
callback: C = this._defaultOneParamCallback as C,
|
||||
beginRoot: BTNKey | N | undefined = this.root,
|
||||
iterationType = this.options.iterationType
|
||||
iterationType = this.iterationType
|
||||
): N | null | undefined {
|
||||
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
|
@ -351,11 +347,29 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
|
|||
return y!;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) on average (where n is the number of nodes in the tree)
|
||||
* Space Complexity: O(1)
|
||||
*/
|
||||
|
||||
override clear() {
|
||||
this._root = this.Sentinel;
|
||||
this._size = 0;
|
||||
}
|
||||
|
||||
init(elements: IterableEntriesOrKeys<V>): void {
|
||||
if (elements) {
|
||||
for (const entryOrKey of elements) {
|
||||
if (Array.isArray(entryOrKey)) {
|
||||
const [key, value] = entryOrKey;
|
||||
this.add(key, value);
|
||||
} else {
|
||||
this.add(entryOrKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override _setRoot(v: N) {
|
||||
if (v) {
|
||||
v.parent = undefined;
|
||||
|
|
|
@ -6,7 +6,15 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
import type { BTNKey, TreeMultimapNodeNested, TreeMultimapOptions } from '../../types';
|
||||
import { BiTreeDeleteResult, BTNCallback, CP, FamilyPosition, IterationType, TreeMultimapNested } from '../../types';
|
||||
import {
|
||||
BiTreeDeleteResult,
|
||||
BTNCallback,
|
||||
CP,
|
||||
FamilyPosition,
|
||||
IterableEntriesOrKeys,
|
||||
IterationType,
|
||||
TreeMultimapNested
|
||||
} from '../../types';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { AVLTree, AVLTreeNode } from './avl-tree';
|
||||
|
||||
|
@ -40,21 +48,15 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
extends AVLTree<V, N, TREE>
|
||||
implements IBinaryTree<V, N, TREE> {
|
||||
|
||||
override options: TreeMultimapOptions;
|
||||
|
||||
/**
|
||||
* The constructor function for a TreeMultimap class in TypeScript, which extends another class and sets an option to
|
||||
* merge duplicated values.
|
||||
* @param {TreeMultimapOptions} [options] - An optional object that contains additional configuration options for the
|
||||
* TreeMultimap.
|
||||
*/
|
||||
constructor(options: TreeMultimapOptions = { iterationType: IterationType.ITERATIVE }) {
|
||||
super(options);
|
||||
if (options) {
|
||||
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b, ...options }
|
||||
} else {
|
||||
this.options = { iterationType: IterationType.ITERATIVE, comparator: (a, b) => a - b };
|
||||
}
|
||||
constructor(elements?: IterableEntriesOrKeys<V>, options?: Partial<TreeMultimapOptions>) {
|
||||
super([], options);
|
||||
if (elements) this.init(elements);
|
||||
}
|
||||
|
||||
private _count = 0;
|
||||
|
@ -77,14 +79,12 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
}
|
||||
|
||||
override createTree(options?: TreeMultimapOptions): TREE {
|
||||
return new TreeMultimap<V, N, TREE>({ ...this.options, ...options }) as TREE;
|
||||
return new TreeMultimap<V, N, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
comparator: this.comparator, ...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
|
@ -169,8 +169,8 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time, as it performs basic pointer assignments.
|
||||
* Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -208,8 +208,8 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(k log n) - logarithmic time for each insertion, where "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted. This is because the method iterates through the keys and calls the add method for each.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
* Time Complexity: O(1) - constant time, as it performs basic pointer assignments.
|
||||
* Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -223,7 +223,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
* values:
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
override perfectlyBalance(iterationType = this.options.iterationType): boolean {
|
||||
override perfectlyBalance(iterationType = this.iterationType): boolean {
|
||||
const sorted = this.dfs(node => node, 'in'),
|
||||
n = sorted.length;
|
||||
if (sorted.length < 1) return false;
|
||||
|
@ -262,8 +262,8 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n log n) - logarithmic time for each insertion, where "n" is the number of nodes in the tree. This is because the method calls the add method for each node.
|
||||
* Space Complexity: O(n) - linear space, as it creates an array to store the sorted nodes.
|
||||
* Time Complexity: O(k log n) - logarithmic time for each insertion, where "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted. This is because the method iterates through the keys and calls the add method for each.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -346,8 +346,8 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The delete method of the superclass (AVLTree) has logarithmic time complexity.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
* Time Complexity: O(n log n) - logarithmic time for each insertion, where "n" is the number of nodes in the tree. This is because the method calls the add method for each node.
|
||||
* Space Complexity: O(n) - linear space, as it creates an array to store the sorted nodes.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -358,6 +358,24 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
this._count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The delete method of the superclass (AVLTree) has logarithmic time complexity.
|
||||
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
|
||||
*/
|
||||
|
||||
init(elements: IterableEntriesOrKeys<V>): void {
|
||||
if (elements) {
|
||||
for (const entryOrKey of elements) {
|
||||
if (Array.isArray(entryOrKey)) {
|
||||
const [key, value] = entryOrKey;
|
||||
this.add(key, value);
|
||||
} else {
|
||||
this.add(entryOrKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1) - constant time, as it performs basic pointer assignments.
|
||||
* Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
import { BinaryTree, BinaryTreeNode } from '../data-structures';
|
||||
import { BinaryTreeNested, BinaryTreeNodeNested, BiTreeDeleteResult, BTNCallback, BTNKey } from '../types';
|
||||
import {
|
||||
BinaryTreeNested,
|
||||
BinaryTreeNodeNested,
|
||||
BinaryTreeOptions,
|
||||
BiTreeDeleteResult,
|
||||
BTNCallback,
|
||||
BTNKey,
|
||||
IterableEntriesOrKeys
|
||||
} from '../types';
|
||||
|
||||
export interface IBinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNodeNested<V>, TREE extends BinaryTree<V, N, TREE> = BinaryTreeNested<V, N>> {
|
||||
createNode(key: BTNKey, value?: N['value']): N;
|
||||
|
||||
createTree(options?: Partial<BinaryTreeOptions>): TREE;
|
||||
|
||||
init(elements: IterableEntriesOrKeys<V>): void;
|
||||
|
||||
add(keyOrNode: BTNKey | N | null, value?: N['value']): N | null | undefined;
|
||||
|
||||
delete<C extends BTNCallback<N>>(identifier: ReturnType<C> | null, callback: C): BiTreeDeleteResult<N>[];
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { BTNKey } from "./data-structures";
|
||||
|
||||
export type Comparator<T> = (a: T, b: T) => number;
|
||||
|
||||
export type DFSOrderPattern = 'pre' | 'in' | 'post';
|
||||
|
@ -20,4 +22,6 @@ export interface IterableWithLength<T> extends Iterable<T> {
|
|||
|
||||
export type IterableWithSizeOrLength<T> = IterableWithSize<T> | IterableWithLength<T>
|
||||
|
||||
export type BinaryTreePrintOptions = { isShowUndefined?: boolean, isShowNull?: boolean, isShowRedBlackNIL?: boolean }
|
||||
export type BinaryTreePrintOptions = { isShowUndefined?: boolean, isShowNull?: boolean, isShowRedBlackNIL?: boolean }
|
||||
|
||||
export type IterableEntriesOrKeys<T> = Iterable<[BTNKey, T | undefined] | BTNKey>
|
|
@ -30,6 +30,6 @@ export type BinaryTreeNodeNested<T> = BinaryTreeNode<T, BinaryTreeNode<T, Binary
|
|||
|
||||
export type BinaryTreeNested<T, N extends BinaryTreeNode<T, N>> = BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, BinaryTree<T, N, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
export type BinaryTreeOptions = { iterationType?: IterationType }
|
||||
export type BinaryTreeOptions = { iterationType: IterationType }
|
||||
|
||||
export type NodeDisplayLayout = [string[], number, number, number];
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { BST, BSTNode } from '../../../data-structures';
|
||||
import type { BinaryTreeOptions, BTNKey } from './binary-tree';
|
||||
|
||||
export type BSTComparator = (a: BTNKey, b: BTNKey) => number;
|
||||
import { Comparator } from "../../common";
|
||||
|
||||
// prettier-ignore
|
||||
export type BSTNodeNested<T> = BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
@ -9,5 +8,5 @@ export type BSTNodeNested<T> = BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNo
|
|||
export type BSTNested<T, N extends BSTNode<T, N>> = BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, BST<T, N, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
export type BSTOptions = BinaryTreeOptions & {
|
||||
comparator?: BSTComparator,
|
||||
comparator: Comparator<BTNKey>
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ const arrHundredThousand = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSA
|
|||
suite
|
||||
.add(`SRC PQ ${TEN_THOUSAND.toLocaleString()} add`, () => {
|
||||
|
||||
const pq = new SRCPriorityQueue<number>({ comparator: (a, b) => b - a });
|
||||
const pq = new SRCPriorityQueue<number>([], { comparator: (a, b) => b - a });
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
|
||||
})
|
||||
.add(`CJS PQ ${TEN_THOUSAND.toLocaleString()} add`, () => {
|
||||
|
@ -47,7 +47,7 @@ if (isCompetitor) {
|
|||
|
||||
suite
|
||||
.add(`SRC PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
|
||||
const pq = new SRCPriorityQueue<number>({ comparator: (a, b) => b - a });
|
||||
const pq = new SRCPriorityQueue<number>([], { comparator: (a, b) => b - a });
|
||||
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
|
||||
|
|
|
@ -7,7 +7,7 @@ const { HUNDRED_THOUSAND, TEN_THOUSAND } = magnitude;
|
|||
|
||||
suite
|
||||
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => {
|
||||
const heap = new Heap<number>({ comparator: (a, b) => b - a });
|
||||
const heap = new Heap<number>([], { comparator: (a, b) => b - a });
|
||||
|
||||
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
|
||||
heap.add(i);
|
||||
|
@ -18,7 +18,7 @@ suite
|
|||
}
|
||||
})
|
||||
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & dfs`, () => {
|
||||
const heap = new Heap<number>({ comparator: (a, b) => b - a });
|
||||
const heap = new Heap<number>([], { comparator: (a, b) => b - a });
|
||||
|
||||
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
|
||||
heap.add(i);
|
||||
|
|
|
@ -8,7 +8,7 @@ const suite = new Benchmark.Suite();
|
|||
const { HUNDRED_THOUSAND } = magnitude;
|
||||
|
||||
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => {
|
||||
const pq = new PriorityQueue<number>({ comparator: (a, b) => b - a });
|
||||
const pq = new PriorityQueue<number>([], { comparator: (a, b) => b - a });
|
||||
|
||||
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
|
||||
pq.add(i);
|
||||
|
|
|
@ -112,7 +112,7 @@ describe('AVL Tree Test', () => {
|
|||
describe('AVL Tree Test recursively', () => {
|
||||
it('should perform various operations on a AVL Tree', () => {
|
||||
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
const tree = new AVLTree<number>({ iterationType: IterationType.RECURSIVE });
|
||||
const tree = new AVLTree<number>([], { iterationType: IterationType.RECURSIVE });
|
||||
|
||||
for (const i of arr) tree.add(i, i);
|
||||
|
||||
|
|
|
@ -189,9 +189,9 @@ describe('BinaryTree', () => {
|
|||
tree.add(4);
|
||||
tree.add(2);
|
||||
expect(tree.getHeight()).toBe(1);
|
||||
tree.options.iterationType = IterationType.RECURSIVE;
|
||||
tree.iterationType = IterationType.RECURSIVE;
|
||||
expect(tree.getHeight()).toBe(1);
|
||||
tree.options.iterationType = IterationType.ITERATIVE;
|
||||
tree.iterationType = IterationType.ITERATIVE;
|
||||
|
||||
tree.add(6);
|
||||
tree.add(1);
|
||||
|
@ -381,7 +381,7 @@ describe('BinaryTree', () => {
|
|||
let tree: BinaryTree<string>;
|
||||
|
||||
beforeEach(() => {
|
||||
tree = new BinaryTree<string>({ iterationType: IterationType.RECURSIVE });
|
||||
tree = new BinaryTree<string>([], { iterationType: IterationType.RECURSIVE });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -541,11 +541,11 @@ describe('BinaryTree', () => {
|
|||
tree.add(3, 'B');
|
||||
tree.add(7, 'C');
|
||||
|
||||
tree.options.iterationType = IterationType.ITERATIVE;
|
||||
tree.iterationType = IterationType.ITERATIVE;
|
||||
expect([...tree]).toEqual([[3, "B"], [5, "A"], [7, "C"]]);
|
||||
tree.options.iterationType = IterationType.RECURSIVE;
|
||||
tree.iterationType = IterationType.RECURSIVE;
|
||||
expect([...tree]).toEqual([[3, "B"], [5, "A"], [7, "C"]]);
|
||||
tree.options.iterationType = IterationType.ITERATIVE;
|
||||
tree.iterationType = IterationType.ITERATIVE;
|
||||
|
||||
const result = tree.morris();
|
||||
expect(result).toEqual([3, 5, 7]);
|
||||
|
|
|
@ -395,7 +395,7 @@ describe('BST operations test', () => {
|
|||
|
||||
describe('BST operations test recursively', () => {
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const bst = new BST({ iterationType: IterationType.RECURSIVE });
|
||||
const bst = new BST([], { iterationType: IterationType.RECURSIVE });
|
||||
expect(bst).toBeInstanceOf(BST);
|
||||
bst.add(11, 11);
|
||||
bst.add(3, 3);
|
||||
|
|
|
@ -245,7 +245,7 @@ describe('TreeMultimap operations test', () => {
|
|||
|
||||
describe('TreeMultimap operations test recursively', () => {
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const treeMultimap = new TreeMultimap({ iterationType: IterationType.RECURSIVE });
|
||||
const treeMultimap = new TreeMultimap([], { iterationType: IterationType.RECURSIVE });
|
||||
|
||||
expect(treeMultimap instanceof TreeMultimap);
|
||||
treeMultimap.add(11, 11);
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import {
|
||||
AVLTree,
|
||||
BinaryTree,
|
||||
BST,
|
||||
Deque,
|
||||
DoublyLinkedList,
|
||||
MaxHeap,
|
||||
|
@ -6,54 +9,92 @@ import {
|
|||
MinHeap,
|
||||
MinPriorityQueue,
|
||||
Queue,
|
||||
RedBlackTree,
|
||||
SinglyLinkedList,
|
||||
Stack
|
||||
Stack,
|
||||
TreeMultimap
|
||||
} from '../../src';
|
||||
import { isDebugTest } from "../config";
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
const orgArr: number[] = [6, 1, 2, 7, 5, 3, 4, 9, 8];
|
||||
const entries: [number, number][] = [[6, 6], [1, 1], [2, 2], [7, 7], [5, 5], [3, 3], [4, 4], [9, 9], [8, 8]];
|
||||
|
||||
describe('conversions', () => {
|
||||
it('Array to Queue', () => {
|
||||
const q = new Queue<number>(orgArr);
|
||||
q.print();
|
||||
isDebug && q.print();
|
||||
})
|
||||
|
||||
it('Array to Deque', () => {
|
||||
const dq = new Deque<number>(orgArr);
|
||||
dq.print();
|
||||
isDebug && dq.print();
|
||||
})
|
||||
|
||||
it('Array to SinglyLinkedList', () => {
|
||||
const sl = new SinglyLinkedList<number>(orgArr);
|
||||
sl.print();
|
||||
isDebug && sl.print();
|
||||
})
|
||||
|
||||
it('Array to DoublyLinkedList', () => {
|
||||
const dl = new DoublyLinkedList<number>(orgArr);
|
||||
dl.print();
|
||||
isDebug && dl.print();
|
||||
})
|
||||
|
||||
it('Array to Stack', () => {
|
||||
const stack = new Stack<number>(orgArr);
|
||||
stack.print();
|
||||
isDebug && stack.print();
|
||||
})
|
||||
|
||||
it('Array to MinHeap', () => {
|
||||
const minHeap = new MinHeap<number>(orgArr);
|
||||
minHeap.print();
|
||||
isDebug && minHeap.print();
|
||||
})
|
||||
|
||||
it('Array to MaxHeap', () => {
|
||||
const maxHeap = new MaxHeap<number>(orgArr);
|
||||
maxHeap.print();
|
||||
isDebug && maxHeap.print();
|
||||
})
|
||||
|
||||
it('Array to MinPriorityQueue', () => {
|
||||
const minPQ = new MinPriorityQueue<number>(orgArr);
|
||||
minPQ.print();
|
||||
isDebug && minPQ.print();
|
||||
})
|
||||
|
||||
it('Array to MaxPriorityQueue', () => {
|
||||
const maxPQ = new MaxPriorityQueue<number>(orgArr);
|
||||
maxPQ.print();
|
||||
isDebug && maxPQ.print();
|
||||
})
|
||||
})
|
||||
|
||||
it('Entry Array to BinaryTree', () => {
|
||||
const biTree = new BinaryTree<number>(entries);
|
||||
isDebug && biTree.print();
|
||||
})
|
||||
|
||||
it('Entry Array to BST', () => {
|
||||
const bst = new BST<number>(orgArr);
|
||||
expect(bst.size).toBe(9)
|
||||
isDebug && bst.print();
|
||||
})
|
||||
|
||||
it('Entry Array to RedBlackTree', () => {
|
||||
const rbTree = new RedBlackTree<number>(orgArr);
|
||||
expect(rbTree.size).toBe(9)
|
||||
isDebug && rbTree.print();
|
||||
})
|
||||
|
||||
it('Entry Array to AVLTree', () => {
|
||||
const avl = new AVLTree<number>(orgArr);
|
||||
expect(avl.size).toBe(9)
|
||||
isDebug && avl.print();
|
||||
})
|
||||
|
||||
it('Entry Array to TreeMultimap', () => {
|
||||
const treeMulti = new TreeMultimap<number>(orgArr);
|
||||
expect(treeMulti.size).toBe(9)
|
||||
isDebug && treeMulti.print();
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue