"AbstractBinaryTree" has been extracted from "BinaryTree." TreeMultiSet has been optimized.

This commit is contained in:
Revone 2023-08-23 13:15:30 +08:00
parent 849e3c6bca
commit 860d18d222
14 changed files with 132 additions and 1606 deletions

View file

@ -8,22 +8,23 @@
import {trampoline} from '../../utils';
import type {
BinaryTreeDeleted,
AbstractRecursiveBinaryTreeNode,
AbstractResultByProperty,
AbstractResultsByProperty,
BinaryTreeDeletedResult,
BinaryTreeNodeId,
BinaryTreeNodePropertyName,
DFSOrderPattern,
KeyValObject,
NodeOrPropertyName,
ResultByProperty,
ResultsByProperty
NodeOrPropertyName
} from '../types';
import {BinaryTreeOptions, FamilyPosition, LoopType, RecursiveAbstractBinaryTreeNode} from '../types';
import {AbstractBinaryTreeOptions, FamilyPosition, LoopType} from '../types';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTreeNode<T, FAMILY> = RecursiveAbstractBinaryTreeNode<T>> implements IBinaryTreeNode<T, FAMILY> {
export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTreeNode<T, FAMILY> = AbstractRecursiveBinaryTreeNode<T>> implements IBinaryTreeNode<T, FAMILY> {
protected constructor(id: BinaryTreeNodeId, val: T, count?: number) {
constructor(id: BinaryTreeNodeId, val: T, count?: number) {
this._id = id;
this._val = val;
this._count = count ?? 1;
@ -58,7 +59,7 @@ export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTre
set left(v: FAMILY | null | undefined) {
if (v) {
v.parent = this as unknown as FAMILY;
v.familyPosition = FamilyPosition.left;
v.familyPosition = FamilyPosition.LEFT;
}
this._left = v;
}
@ -72,7 +73,7 @@ export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTre
set right(v: FAMILY | null | undefined) {
if (v) {
v.parent = this as unknown as FAMILY;
v.familyPosition = FamilyPosition.right;
v.familyPosition = FamilyPosition.RIGHT;
}
this._right = v;
}
@ -87,7 +88,7 @@ export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTre
this._parent = v;
}
private _familyPosition: FamilyPosition = FamilyPosition.root;
private _familyPosition: FamilyPosition = FamilyPosition.ROOT;
get familyPosition(): FamilyPosition {
return this._familyPosition;
@ -147,15 +148,16 @@ export abstract class AbstractBinaryTreeNode<T, FAMILY extends AbstractBinaryTre
export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'], N> = AbstractBinaryTreeNode<number>> implements IBinaryTree<N> {
/**
* The constructor function accepts an optional options object and sets the values of loopType, autoIncrementId, and
* isDuplicatedVal based on the provided options.
* @param [options] - An optional object that can contain the following properties:
* The protected constructor initializes the options for an abstract binary tree.
* @param {AbstractBinaryTreeOptions} [options] - An optional object that contains configuration options for the binary
* tree.
*/
protected constructor(options?: BinaryTreeOptions) {
protected constructor(options?: AbstractBinaryTreeOptions) {
if (options !== undefined) {
const {
loopType = LoopType.iterative,
loopType = LoopType.ITERATIVE,
autoIncrementId = false,
isDuplicatedVal = false
} = options;
@ -165,7 +167,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
}
}
private _loopType: LoopType = LoopType.iterative;
private _loopType: LoopType = LoopType.ITERATIVE;
get loopType(): LoopType {
return this._loopType;
@ -236,17 +238,6 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
return this._count;
}
/**
* The function creates a new binary tree node with the given id, value, and count if the value is not null, otherwise
* it returns null.
* @param {BinaryTreeNodeId} id - The `id` parameter is the identifier for the binary tree node. It is of type
* `BinaryTreeNodeId`.
* @param {N | null} val - The `val` parameter represents the value of the node. It can be of type `N` (generic type)
* or `null`.
* @param {number} [count] - The `count` parameter is an optional parameter of type `number`. It represents the number
* of occurrences of the value in the binary tree node. If not provided, the default value is `undefined`.
* @returns a BinaryTreeNode object if the value is not null, otherwise it returns null.
*/
abstract _createNode(id: BinaryTreeNodeId, val: N['val'] | null, count?: number): N | null ;
/**
@ -333,7 +324,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
if (parent.left === undefined) {
if (newNode) {
newNode.parent = parent;
newNode.familyPosition = FamilyPosition.left;
newNode.familyPosition = FamilyPosition.LEFT;
}
parent.left = newNode;
if (newNode !== null) {
@ -345,7 +336,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
} else if (parent.right === undefined) {
if (newNode) {
newNode.parent = parent;
newNode.familyPosition = FamilyPosition.right;
newNode.familyPosition = FamilyPosition.RIGHT;
}
parent.right = newNode;
if (newNode !== null) {
@ -399,7 +390,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
if (map.has(item)) {
let newId: number;
if (!this._autoIncrementId) {
if ((item as KeyValObject).hasOwnProperty('id')) {
if (Object.keys(item).includes('id')) {
newId = (item as KeyValObject).id;
} else {
console.warn('Object value must has an id property when the autoIncrementId is false');
@ -445,7 +436,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* "needBalanced". The "deleted" property contains the deleted node or undefined if no node was deleted. The
* "needBalanced" property is always null.
*/
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeleted<N>[] {
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[] {
const nodes = this.getNodes(id, 'id', true);
let node: N | null | undefined = nodes[0];
@ -508,7 +499,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
beginRoot = beginRoot ?? this.root;
if (!beginRoot) return -1;
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const _getMaxHeight = (cur: N | null | undefined): number => {
if (!cur) return -1;
const leftHeight = _getMaxHeight(cur.left);
@ -557,7 +548,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
beginRoot = beginRoot || this.root;
if (!beginRoot) return -1;
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const _getMinHeight = (cur: N | null | undefined): number => {
if (!cur) return 0;
if (!cur.left && !cur.right) return 0;
@ -623,7 +614,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
const result: (N | null | undefined)[] = [];
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return;
if (!cur.left && !cur.right) return;
@ -707,7 +698,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
node = node ?? this.root;
if (!node) return node;
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N): N => {
if (!cur.left) return cur;
@ -742,7 +733,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
node = node ?? this.root;
if (!node) return node;
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N): N => {
if (!cur.right) return cur;
return _traverse(cur.right);
@ -772,7 +763,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
node = node ?? this.root;
if (!node) return true;
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const dfs = (cur: N | null | undefined, min: BinaryTreeNodeId, max: BinaryTreeNodeId): boolean => {
if (!cur) return true;
if (cur.id <= min || cur.id >= max) return false;
@ -809,7 +800,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
const res: [number, number] = [0, 0];
if (!subTreeRoot) return res;
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
res[0]++;
res[1] += cur.count;
@ -871,7 +862,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
return needSum;
}
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N): void => {
sum += _sumByProperty(cur);
cur.left && _traverse(cur.left);
@ -921,7 +912,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
}
}
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
_addByProperty(cur);
cur.left && _traverse(cur.left);
@ -960,9 +951,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* represents either a node or a property name. If a node is provided, the breadth-first search algorithm will be
* performed starting from that node. If a property name is provided, the breadth-first search algorithm will be
* performed starting from the root node
* @returns an object of type `ResultsByProperty<N>`.
* @returns an object of type `AbstractResultsByProperty<N>`.
*/
BFS(nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<N> {
BFS(nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
this._resetResults();
const queue: Array<N | null | undefined> = [this.root];
@ -999,9 +990,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* either the name of a property in the `BinaryTreeNode` object or the value of the `id` property in the
* `BinaryTreeNode` object. This parameter is used to accumulate the results based on the specified property name. If
* no value
* @returns an object of type `ResultsByProperty<N>`.
* @returns an object of type `AbstractResultsByProperty<N>`.
*/
DFS(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<N> {
DFS(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
pattern = pattern ?? 'in';
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
this._resetResults();
@ -1046,7 +1037,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @param nodeOrPropertyName
* @constructor
*/
DFSIterative(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<N> {
DFSIterative(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
pattern = pattern || 'in';
nodeOrPropertyName = nodeOrPropertyName || 'id';
this._resetResults();
@ -1108,9 +1099,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* can be either a `BinaryTreeNode` property name or the string `'id'`. If a property name is provided, the function
* will accumulate results based on that property. If no property name is provided, the function will default to
* accumulating results
* @returns The function `levelIterative` returns an object of type `ResultsByProperty<N>`.
* @returns The function `levelIterative` returns an object of type `AbstractResultsByProperty<N>`.
*/
levelIterative(node: N | null, nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<N> {
levelIterative(node: N | null, nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
nodeOrPropertyName = nodeOrPropertyName || 'id';
node = node || this.root;
if (!node) return [];
@ -1151,14 +1142,14 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @param {NodeOrPropertyName} [nodeOrPropertyName] - The `nodeOrPropertyName` parameter is an optional parameter that
* specifies the property of the `BinaryTreeNode` object to collect at each level. It can be one of the following
* values:
* @returns The function `listLevels` returns a 2D array of `ResultByProperty<N>` objects.
* @returns The function `listLevels` returns a 2D array of `AbstractResultByProperty<N>` objects.
*/
listLevels(node: N | null, nodeOrPropertyName?: NodeOrPropertyName): ResultByProperty<N>[][] {
listLevels(node: N | null, nodeOrPropertyName?: NodeOrPropertyName): AbstractResultByProperty<N>[][] {
nodeOrPropertyName = nodeOrPropertyName || 'id';
node = node || this.root;
if (!node) return [];
const levelsNodes: ResultByProperty<N>[][] = [];
const levelsNodes: AbstractResultByProperty<N>[][] = [];
const collectByProperty = (node: N, level: number) => {
switch (nodeOrPropertyName) {
@ -1180,7 +1171,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
}
}
if (this._loopType === LoopType.recursive) {
if (this._loopType === LoopType.RECURSIVE) {
const _recursive = (node: N, level: number) => {
if (!levelsNodes[level]) levelsNodes[level] = [];
collectByProperty(node, level);
@ -1245,9 +1236,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @param {NodeOrPropertyName} [nodeOrPropertyName] - The `nodeOrPropertyName` parameter is used to specify the
* property of the nodes that you want to retrieve in the results. It can be either the node itself or the name of the
* property. If not provided, it defaults to `'id'`.
* @returns The function `morris` returns an object of type `ResultsByProperty<N>`.
* @returns The function `morris` returns an object of type `AbstractResultsByProperty<N>`.
*/
morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): ResultsByProperty<N> {
morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractResultsByProperty<N> {
if (this.root === null) return [];
pattern = pattern || 'in';
@ -1372,7 +1363,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
protected _setRoot(v: N | null) {
if (v) {
v.parent = null;
v.familyPosition = FamilyPosition.root;
v.familyPosition = FamilyPosition.ROOT;
}
this._root = v;
}
@ -1476,9 +1467,9 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* to 'id'.
* @param {NodeOrPropertyName} [nodeOrPropertyName] - The parameter `nodeOrPropertyName` is an optional parameter that
* can accept a value of type `NodeOrPropertyName`.
* @returns The method returns an object of type `ResultsByProperty<T>`.
* @returns The method returns an object of type `AbstractResultsByProperty<T>`.
*/
protected _getResultByPropertyName(nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<N> {
protected _getResultByPropertyName(nodeOrPropertyName ?: NodeOrPropertyName): AbstractResultsByProperty<N> {
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
switch (nodeOrPropertyName) {

View file

@ -6,10 +6,9 @@
* @license MIT License
*/
import {BST, BSTNode} from './bst';
import type {AVLTreeDeleted, AVLTreeOptions, BinaryTreeNodeId, RecursiveAVLTreeNode} from '../types';
import type {AVLTreeOptions, BinaryTreeDeletedResult, BinaryTreeNodeId, RecursiveAVLTreeNode} from '../types';
import {IBinaryTreeNode} from '../interfaces';
export class AVLTreeNode<T, FAMILY extends AVLTreeNode<T, FAMILY> = RecursiveAVLTreeNode<T>> extends BSTNode<T, FAMILY> implements IBinaryTreeNode<T, FAMILY> {
}
@ -52,7 +51,7 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode<number>> e
* `isUpdateAllLeftSum` is set to `true`, the left sum of all nodes will be recalculated.
* @returns The method is returning an array of `AVLTreeDeleted<N>` objects.
*/
override remove(id: BinaryTreeNodeId, isUpdateAllLeftSum?: boolean): AVLTreeDeleted<N>[] {
override remove(id: BinaryTreeNodeId, isUpdateAllLeftSum?: boolean): BinaryTreeDeletedResult<N>[] {
const deletedResults = super.remove(id, isUpdateAllLeftSum);
for (const {needBalanced} of deletedResults) {
if (needBalanced) {

File diff suppressed because it is too large Load diff

View file

@ -5,14 +5,8 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type {
BinaryTreeNodeId,
BinaryTreeNodePropertyName,
BSTComparator,
BSTDeletedResult,
RecursiveBSTNode
} from '../types';
import {BSTOptions, CP, FamilyPosition, LoopType} from '../types';
import type {BinaryTreeNodeId, BinaryTreeNodePropertyName, BSTComparator, RecursiveBSTNode} from '../types';
import {BinaryTreeDeletedResult, BSTOptions, CP, FamilyPosition, LoopType} from '../types';
import {BinaryTree, BinaryTreeNode} from './binary-tree';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
@ -79,7 +73,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
if (cur.left === undefined) {
if (newNode) {
newNode.parent = cur;
newNode.familyPosition = FamilyPosition.left;
newNode.familyPosition = FamilyPosition.LEFT;
}
//Add to the left of the current node
cur.left = newNode;
@ -96,7 +90,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
if (cur.right === undefined) {
if (newNode) {
newNode.parent = cur;
newNode.familyPosition = FamilyPosition.right;
newNode.familyPosition = FamilyPosition.RIGHT;
}
//Add to the right of the current node
cur.right = newNode;
@ -155,8 +149,8 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
* set to false or not provided, the count of the node will be taken into account and the
* @returns an array of `BSTDeletedResult<N>` objects.
*/
override remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BSTDeletedResult<N>[] {
const bstDeletedResult: BSTDeletedResult<N>[] = [];
override remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[] {
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
if (!this.root) return bstDeletedResult;
const curr: N | null = this.get(id);
@ -174,10 +168,10 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
if (curr.right !== undefined) this._setRoot(curr.right);
} else {
switch (curr.familyPosition) {
case FamilyPosition.left:
case FamilyPosition.LEFT:
parent.left = curr.right;
break;
case FamilyPosition.right:
case FamilyPosition.RIGHT:
parent.right = curr.right;
break;
}
@ -221,7 +215,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
if (!this.root) return [];
const result: N[] = [];
if (this.loopType === LoopType.recursive) {
if (this.loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return;
@ -289,7 +283,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
let sum = 0;
if (this.loopType === LoopType.recursive) {
if (this.loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N): void => {
const compared = this._compare(cur.id, id);
if (compared === CP.eq) {
@ -362,7 +356,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
}
}
if (this.loopType === LoopType.recursive) {
if (this.loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
const compared = this._compare(cur.id, node.id);
_sumByPropertyName(cur);
@ -400,7 +394,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
this.clear();
if (sorted.length < 1) return false;
if (this.loopType === LoopType.recursive) {
if (this.loopType === LoopType.RECURSIVE) {
const buildBalanceBST = (l: number, r: number) => {
if (l > r) return;
const m = l + Math.floor((r - l) / 2);
@ -441,7 +435,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode<number>> extends Binar
let balanced = true;
if (this.loopType === LoopType.recursive) {
if (this.loopType === LoopType.RECURSIVE) {
const _height = (cur: N | null | undefined): number => {
if (!cur) return 0;
const leftHeight = _height(cur.left), rightHeight = _height(cur.right);

View file

@ -1,4 +1,4 @@
// export * from './abstract-binary-tree';
export * from './abstract-binary-tree';
export * from './binary-tree';
export * from './bst';
export * from './binary-indexed-tree';

View file

@ -1,8 +1,7 @@
import {BinaryTree, BinaryTreeNode} from './binary-tree';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
import {LoopType} from '../types';
import {RBColor, RBTreeOptions} from '../types';
enum RBColor { Red, Black }
class RBNode<T, FAMILY extends RBNode<T, FAMILY>> extends BinaryTreeNode<T, FAMILY> implements IBinaryTreeNode<T, FAMILY> {
// override createNode(id: BinaryTreeNodeId, val: T | null, count?: number): RBNode<T> | null {
@ -13,7 +12,7 @@ class RBNode<T, FAMILY extends RBNode<T, FAMILY>> extends BinaryTreeNode<T, FAMI
super(id, val, count);
}
private _color: RBColor = RBColor.Red;
private _color: RBColor = RBColor.RED;
get color(): RBColor {
return this._color;
@ -39,7 +38,7 @@ class RBNode<T, FAMILY extends RBNode<T, FAMILY>> extends BinaryTreeNode<T, FAMI
// override set left(v: RBNode<T> | null | undefined) {
// if (v) {
// v.parent = this;
// v.familyPosition = FamilyPosition.left;
// v.familyPosition = FamilyPosition.LEFT;
// }
// this._left = v;
// }
@ -53,18 +52,14 @@ class RBNode<T, FAMILY extends RBNode<T, FAMILY>> extends BinaryTreeNode<T, FAMI
// override set right(v: RBNode<T> | null | undefined) {
// if (v) {
// v.parent = this;
// v.familyPosition = FamilyPosition.right;
// v.familyPosition = FamilyPosition.RIGHT;
// }
// this._right = v;
// }
}
class RBTree<N extends RBNode<N['val'], N>> extends BinaryTree<N> implements IBinaryTree<N> {
constructor(options?: {
loopType?: LoopType,
autoIncrementId?: boolean,
isDuplicatedVal?: boolean
}) {
constructor(options?: RBTreeOptions) {
super(options);
}

View file

@ -6,10 +6,21 @@
* @license MIT License
*/
import {BST, BSTNode} from './bst';
import type {BinaryTreeNodeId, TreeMultiSetDeletedResult} from '../types';
import {IBinaryTree} from '../interfaces';
import type {BinaryTreeNodeId, RecursiveTreeMultiSetNode, TreeMultiSetOptions} from '../types';
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
export class TreeMultiSetNode<T, FAMILY extends TreeMultiSetNode<T, FAMILY> = RecursiveTreeMultiSetNode<T>> extends BSTNode<T, FAMILY> implements IBinaryTreeNode<T, FAMILY> {
}
/**
* The only distinction between a TreeMultiSet and a BST lies in the ability of the former to store duplicate nodes through the utilization of counters.
*/
export class TreeMultiSet<N extends BSTNode<N['val'], N> = BSTNode<number>> extends BST<N> implements IBinaryTree<N> {
constructor(options?: TreeMultiSetOptions) {
super({...options, isDuplicatedVal: true});
}
/**
* The function creates a new BSTNode with the given id, value, and count.
* @param {BinaryTreeNodeId} id - The id parameter is the unique identifier for the binary tree node. It is used to
@ -20,36 +31,7 @@ export class TreeMultiSet<N extends BSTNode<N['val'], N> = BSTNode<number>> exte
* @returns A new instance of the BSTNode class with the specified id, value, and count (if provided).
*/
override _createNode(id: BinaryTreeNodeId, val: N['val'], count?: number): N {
const node = new BSTNode<N['val'], N>(id, val, count);
const node = new TreeMultiSetNode<N['val'], N>(id, val, count);
return node as N;
}
/**
* The function overrides the add method of the BinarySearchTree class in TypeScript.
* @param {BinaryTreeNodeId} id - The `id` parameter is the identifier of the binary tree node that you want to add.
* @param {N | null} val - The `val` parameter represents the value that you want to add to the binary search tree. It
* can be of type `N` (the generic type) or `null`.
* @param {number} [count] - The `count` parameter is an optional parameter of type `number`. It represents the number
* of times the value should be added to the binary search tree. If not provided, the default value is `undefined`.
* @returns The `add` method is returning a `BSTNode<N>` object or `null`.
*/
override add(id: BinaryTreeNodeId, val: N | null, count?: number): N | null {
return super.add(id, val, count);
}
/**
* The function overrides the remove method of the superclass and returns the result of calling the superclass's remove
* method.
* @param {BinaryTreeNodeId} id - The `id` parameter represents the identifier of the binary tree node that needs to be
* removed from the tree.
* @param {boolean} [isUpdateAllLeftSum] - The `isUpdateAllLeftSum` parameter is an optional boolean value that
* determines whether to update the left sum of all nodes in the tree after removing a node. If `isUpdateAllLeftSum` is
* set to `true`, the left sum of all nodes will be recalculated. If it
* @returns The method is returning an array of TreeMultiSetDeletedResult objects.
*/
override remove(id: BinaryTreeNodeId, isUpdateAllLeftSum?: boolean): TreeMultiSetDeletedResult<N>[] {
return super.remove(id, isUpdateAllLeftSum);
}
}

View file

@ -1,4 +1,4 @@
import {AbstractBinaryTreeNode} from '../binary-tree/abstract-binary-tree';
import {AbstractBinaryTreeNode} from '../binary-tree';
/**
* Enum representing different loop types.
@ -6,9 +6,26 @@ import {AbstractBinaryTreeNode} from '../binary-tree/abstract-binary-tree';
* - `iterative`: Indicates the iterative loop type (with loops that use iterations).
* - `recursive`: Indicates the recursive loop type (with loops that call themselves).
*/
export enum LoopType { iterative = 1, recursive = 2}
export enum LoopType { ITERATIVE = 'ITERATIVE', RECURSIVE = 'RECURSIVE'}
/* This enumeration defines the position of a node within a family tree composed of three associated nodes, where 'root' represents the root node of the family tree, 'left' represents the left child node, and 'right' represents the right child node. */
export enum FamilyPosition {root, left, right}
export enum FamilyPosition {ROOT, LEFT, RIGHT}
export type RecursiveAbstractBinaryTreeNode<T> = AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type BinaryTreeNodePropertyName = 'id' | 'val' | 'count';
export type NodeOrPropertyName = 'node' | BinaryTreeNodePropertyName;
export type DFSOrderPattern = 'in' | 'pre' | 'post';
export type BinaryTreeNodeId = number;
export type BinaryTreeDeletedResult<N> = { deleted: N | null | undefined, needBalanced: N | null };
export type AbstractResultByProperty<N extends AbstractBinaryTreeNode<N['val'], N>> =
N['val']
| N
| number
| BinaryTreeNodeId;
export type AbstractResultsByProperty<N extends AbstractBinaryTreeNode<N['val'], N>> = AbstractResultByProperty<N>[];
export type AbstractRecursiveBinaryTreeNode<T> = AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type AbstractBinaryTreeOptions = {
loopType?: LoopType,
autoIncrementId?: boolean,
isDuplicatedVal?: boolean
}

View file

@ -1,10 +1,5 @@
import {AVLTreeNode} from '../binary-tree';
import {BSTOptions} from './bst';
export type AVLTreeDeleted<N> = {
deleted: N | null;
needBalanced: N | null;
}
export type RecursiveAVLTreeNode<T> = AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type AVLTreeOptions = BSTOptions & {};

View file

@ -1,16 +1,9 @@
import {BinaryTreeNode} from '../binary-tree';
import {LoopType} from './abstract-binary-tree';
import {AbstractBinaryTreeOptions} from './abstract-binary-tree';
export type BinaryTreeNodePropertyName = 'id' | 'val' | 'count';
export type NodeOrPropertyName = 'node' | BinaryTreeNodePropertyName;
export type DFSOrderPattern = 'in' | 'pre' | 'post';
export type BinaryTreeNodeId = number;
export type BinaryTreeDeleted<N> = { deleted: N | null | undefined, needBalanced: N | null };
export type ResultByProperty<N extends BinaryTreeNode<N['val'], N>> = N['val'] | N | number | BinaryTreeNodeId;
export type ResultsByProperty<N extends BinaryTreeNode<N['val'], N>> = ResultByProperty<N>[];
// export type BinaryTreeDeleted<N> = { deleted: N | null | undefined, needBalanced: N | null };
// export type ResultByProperty<N extends BinaryTreeNode<N['val'], N>> = N['val'] | N | number | BinaryTreeNodeId;
// export type ResultsByProperty<N extends BinaryTreeNode<N['val'], N>> = ResultByProperty<N>[];
export type RecursiveBinaryTreeNode<T> = BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type BinaryTreeOptions = {
loopType?: LoopType,
autoIncrementId?: boolean,
isDuplicatedVal?: boolean
}
export type BinaryTreeOptions = AbstractBinaryTreeOptions & {}

View file

@ -1,8 +1,9 @@
import {BSTNode} from '../binary-tree';
import type {BinaryTreeNodeId, BinaryTreeOptions} from './binary-tree';
import type {BinaryTreeOptions} from './binary-tree';
import {BinaryTreeNodeId} from './abstract-binary-tree';
export type BSTComparator = (a: BinaryTreeNodeId, b: BinaryTreeNodeId) => number;
export type BSTDeletedResult<N extends BSTNode<N['val'], N>> = { deleted: N | null, needBalanced: N | null };
export type RecursiveBSTNode<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, BSTNode<T, BSTNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type BSTOptions = BinaryTreeOptions & {
comparator?: BSTComparator,

View file

@ -5,6 +5,7 @@ export * from './segment-tree';
export * from './tree-multiset';
export * from './abstract-graph';
export * from './abstract-binary-tree';
export * from './rb-tree';
export * from './directed-graph';
export * from './priority-queue';
export * from './heap';

View file

@ -0,0 +1,5 @@
import {BinaryTreeOptions} from './binary-tree';
export enum RBColor { RED = 'RED', BLACK = 'BLACK'}
export type RBTreeOptions = BinaryTreeOptions & {}

View file

@ -1 +1,8 @@
export type TreeMultiSetDeletedResult<N> = { deleted: N | null, needBalanced: N | null };
import {BSTOptions} from './bst';
import {TreeMultiSetNode} from '../binary-tree';
export type RecursiveTreeMultiSetNode<T> = TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, TreeMultiSetNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type TreeMultiSetOptions = Omit<BSTOptions, 'isDuplicatedVal'> & {
isDuplicatedVal: true,
}