This commit is contained in:
Revone 2024-11-25 20:18:20 +13:00
parent 829403dc63
commit 691fb62893
16 changed files with 508 additions and 473 deletions

View file

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

52
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "data-structure-typed",
"version": "1.53.8",
"version": "1.53.9",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "data-structure-typed",
"version": "1.53.8",
"version": "1.53.9",
"license": "MIT",
"devDependencies": {
"@eslint/compat": "^1.2.2",
@ -19,11 +19,11 @@
"@typescript-eslint/eslint-plugin": "^8.12.1",
"@typescript-eslint/parser": "^8.12.1",
"auto-changelog": "^2.5.0",
"avl-tree-typed": "^1.53.7",
"avl-tree-typed": "^1.53.8",
"benchmark": "^2.1.4",
"binary-tree-typed": "^1.53.7",
"bst-typed": "^1.53.7",
"data-structure-typed": "^1.53.7",
"binary-tree-typed": "^1.53.8",
"bst-typed": "^1.53.8",
"data-structure-typed": "^1.53.8",
"dependency-cruiser": "^16.5.0",
"doctoc": "^2.2.1",
"eslint": "^9.13.0",
@ -32,7 +32,7 @@
"eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import": "^2.31.0",
"fast-glob": "^3.3.2",
"heap-typed": "^1.53.7",
"heap-typed": "^1.53.8",
"istanbul-badges-readme": "^1.9.0",
"jest": "^29.7.0",
"js-sdsl": "^4.4.2",
@ -3437,13 +3437,13 @@
}
},
"node_modules/avl-tree-typed": {
"version": "1.53.7",
"resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.53.7.tgz",
"integrity": "sha512-+HyMQY+1FoOQm6ESwSbtJL6LnR9XNYxqJc6IdDEAhBZovRx2m3bwgse5q+3SLyEqQAUwSY9LsGD3A80UQq4fjQ==",
"version": "1.53.8",
"resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.53.8.tgz",
"integrity": "sha512-FJKmj/kYbdK7Du/Bva9NSLHmiSVA4KqV7AEd4yqnKYrwEfXVfvHJ6wggfyQmdwhrygFTET4ByAldshFzGIwBHQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"data-structure-typed": "^1.53.7"
"data-structure-typed": "^1.53.8"
}
},
"node_modules/babel-jest": {
@ -3602,13 +3602,13 @@
}
},
"node_modules/binary-tree-typed": {
"version": "1.53.7",
"resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.53.7.tgz",
"integrity": "sha512-Pd/N1QOFm7qgBhdp4T43lBpUhPUex5hwL/9JuZ7qgfN++qxCQLAwU72tgPAvSjwb4z6njqG8/4hfLdnLUbDWUg==",
"version": "1.53.8",
"resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.53.8.tgz",
"integrity": "sha512-qMTzw2MfEB1Ihn5LBtmgk4bL5rBd0E6x1bJLiZTudbWv/PrDrT+GrtIcVozwKQG6QwjRbbnnkWYDm509l+To3g==",
"dev": true,
"license": "MIT",
"dependencies": {
"data-structure-typed": "^1.53.7"
"data-structure-typed": "^1.53.8"
}
},
"node_modules/brace-expansion": {
@ -3691,13 +3691,13 @@
}
},
"node_modules/bst-typed": {
"version": "1.53.7",
"resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.53.7.tgz",
"integrity": "sha512-Sj2nJb/2SUAqcSg4oXNWMt9OxlF4NcxPQ6o2wMKbqiKp4JCblmLpVEjbaZBVrpRMTKHEZctW/is21QPcxQ9Hnw==",
"version": "1.53.8",
"resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.53.8.tgz",
"integrity": "sha512-BvqI2skHCrPYE3JYhSpSjpsRwGHQKw9/SNE5vC4AzxOQpL3fmg9bSBG5aGIrPk4Uc3BEkL9NUignLbjJMNwXcw==",
"dev": true,
"license": "MIT",
"dependencies": {
"data-structure-typed": "^1.53.7"
"data-structure-typed": "^1.53.8"
}
},
"node_modules/buffer-from": {
@ -4069,9 +4069,9 @@
}
},
"node_modules/data-structure-typed": {
"version": "1.53.7",
"resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.53.7.tgz",
"integrity": "sha512-8higtCbppFIeHaz7JMJL2WdZ/vc4wtO8+Yh6qZtONDAy+shqafASqpTsYnKJaE8gNiPzOkP2YOMiEbVdpKLhhQ==",
"version": "1.53.8",
"resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.53.8.tgz",
"integrity": "sha512-d0kCsb0U1kNMNcsoJI2zX1LkrsiX9FSLXPN4PL9IweyvAsQybcwdV7Y48ZLcUPWnShipuvaaxFLYtznjNcSsqw==",
"dev": true,
"license": "MIT"
},
@ -5946,13 +5946,13 @@
}
},
"node_modules/heap-typed": {
"version": "1.53.7",
"resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.53.7.tgz",
"integrity": "sha512-iXPgPtyCxDY/+e8eCvWUVSsQ2h+7L6upoP1QGJrIm47+tdTovV/EZ0PhCIKWERRzHI4Us/PM9hZbX0Jt8KBeRg==",
"version": "1.53.8",
"resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.53.8.tgz",
"integrity": "sha512-Gmwpyl0JSZka8KMR6q3OMsrfA88XA8BmP3aEdT26UnMsX5HBwlBnj2vJvKqOCl5lPl3AhOD5nAj5zxI84bwrrw==",
"dev": true,
"license": "MIT",
"dependencies": {
"data-structure-typed": "^1.53.7"
"data-structure-typed": "^1.53.8"
}
},
"node_modules/html-escaper": {

View file

@ -70,11 +70,11 @@
"@typescript-eslint/eslint-plugin": "^8.12.1",
"@typescript-eslint/parser": "^8.12.1",
"auto-changelog": "^2.5.0",
"avl-tree-typed": "^1.53.7",
"avl-tree-typed": "^1.53.8",
"benchmark": "^2.1.4",
"binary-tree-typed": "^1.53.7",
"bst-typed": "^1.53.7",
"data-structure-typed": "^1.53.7",
"binary-tree-typed": "^1.53.8",
"bst-typed": "^1.53.8",
"data-structure-typed": "^1.53.8",
"dependency-cruiser": "^16.5.0",
"doctoc": "^2.2.1",
"eslint": "^9.13.0",
@ -83,7 +83,7 @@
"eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import": "^2.31.0",
"fast-glob": "^3.3.2",
"heap-typed": "^1.53.7",
"heap-typed": "^1.53.8",
"istanbul-badges-readme": "^1.9.0",
"jest": "^29.7.0",
"js-sdsl": "^4.4.2",

View file

@ -6,6 +6,7 @@
* @license MIT License
*/
import type {
AVLTreeMultiMapNested,
AVLTreeMultiMapNodeNested,
AVLTreeMultiMapOptions,
BinaryTreeDeleteResult,
@ -36,25 +37,6 @@ export class AVLTreeMultiMapNode<
super(key, value);
this.count = count;
}
protected _count: number = 1;
/**
* The function returns the value of the protected variable _count.
* @returns The count property of the object, which is of type number.
*/
get count(): number {
return this._count;
}
/**
* The above function sets the value of the count property.
* @param {number} value - The value parameter is of type number, which means it can accept any
* numeric value.
*/
set count(value: number) {
this._count = value;
}
}
/**
@ -64,10 +46,23 @@ export class AVLTreeMultiMap<
K = any,
V = any,
R = object,
NODE extends AVLTreeMultiMapNode<K, V, NODE> = AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNodeNested<K, V>>
MK = any,
MV = any,
MR = object,
NODE extends AVLTreeMultiMapNode<K, V, NODE> = AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNodeNested<K, V>>,
TREE extends AVLTreeMultiMap<K, V, R, MK, MV, MR, NODE, TREE> = AVLTreeMultiMap<
K,
V,
R,
MK,
MV,
MR,
NODE,
AVLTreeMultiMapNested<K, V, R, MK, MV, MR, NODE>
>
>
extends AVLTree<K, V, R, NODE>
implements IBinaryTree<K, V, R, NODE>
extends AVLTree<K, V, R, MK, MV, MR, NODE, TREE>
implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
{
/**
* The constructor initializes a new AVLTreeMultiMap object with optional initial elements.
@ -132,16 +127,15 @@ export class AVLTreeMultiMap<
* @returns a new instance of the AVLTreeMultiMap class, with the specified options, as a TREE
* object.
*/
// @ts-ignore
override createTree(options?: AVLTreeMultiMapOptions<K, V, R>) {
return new AVLTreeMultiMap<K, V, R, NODE>([], {
override createTree(options?: AVLTreeMultiMapOptions<K, V, R>): TREE {
return new AVLTreeMultiMap<K, V, R, MK, MV, MR, NODE, TREE>([], {
iterationType: this.iterationType,
isMapMode: this._isMapMode,
specifyComparable: this._specifyComparable,
toEntryFn: this._toEntryFn,
isReverse: this._isReverse,
...options
});
}) as TREE;
}
/**
@ -220,7 +214,7 @@ export class AVLTreeMultiMap<
} else {
if (!curr.left) {
if (!parent) {
if (curr.right !== undefined) this._setRoot(curr.right);
if (curr.right !== undefined && curr.right !== null) this._setRoot(curr.right);
} else {
const { familyPosition: fp } = curr;
if (fp === 'LEFT' || fp === 'ROOT_LEFT') {
@ -330,8 +324,7 @@ export class AVLTreeMultiMap<
* The function overrides the clone method to create a deep copy of a tree object.
* @returns The `clone()` method is returning a cloned instance of the `TREE` object.
*/
// @ts-ignore
override clone() {
override clone(): TREE {
const cloned = this.createTree();
if (this._isMapMode) this.bfs(node => cloned.add(node.key, undefined, node.count));
else this.bfs(node => cloned.add(node.key, node.value, node.count));
@ -357,12 +350,11 @@ export class AVLTreeMultiMap<
* `callback` function along with the index and the original tree itself. The transformed entries are
* then added to the new `AVLTreeMultiMap` instance, which is returned at the end.
*/
// @ts-ignore
override map<MK, MV, MR>(
callback: EntryCallback<K, V | undefined, [MK, MV]>,
options?: AVLTreeMultiMapOptions<MK, MV, MR>,
thisArg?: any
) {
): AVLTreeMultiMap<MK, MV, MR> {
const newTree = new AVLTreeMultiMap<MK, MV, MR>([], options);
let index = 0;
for (const [key, value] of this) {

View file

@ -7,6 +7,7 @@
*/
import { BST, BSTNode } from './bst';
import type {
AVLTreeNested,
AVLTreeNodeNested,
AVLTreeOptions,
BinaryTreeDeleteResult,
@ -31,26 +32,6 @@ export class AVLTreeNode<
*/
constructor(key: K, value?: V) {
super(key, value);
this._height = 0;
}
protected _height: number;
/**
* The function returns the value of the height property.
* @returns The height of the object.
*/
get height(): number {
return this._height;
}
/**
* The above function sets the value of the height property.
* @param {number} value - The value parameter is a number that represents the new height value to be
* set.
*/
set height(value: number) {
this._height = value;
}
}
@ -67,10 +48,23 @@ export class AVLTree<
K = any,
V = any,
R = object,
NODE extends AVLTreeNode<K, V, NODE> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>
MK = any,
MV = any,
MR = object,
NODE extends AVLTreeNode<K, V, NODE> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>,
TREE extends AVLTree<K, V, R, MK, MV, MR, NODE, TREE> = AVLTree<
K,
V,
R,
MK,
MV,
MR,
NODE,
AVLTreeNested<K, V, R, MK, MV, MR, NODE>
>
>
extends BST<K, V, R, NODE>
implements IBinaryTree<K, V, R, NODE>
extends BST<K, V, R, MK, MV, MR, NODE, TREE>
implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
{
/**
* This is a constructor function for an AVLTree class that initializes the tree with keys, nodes,
@ -102,25 +96,21 @@ export class AVLTree<
}
/**
* The function `createTree` in TypeScript overrides the default AVLTree creation with the provided
* options.
* @param [options] - The `options` parameter in the `createTree` function is an object that contains
* configuration options for creating an AVL tree. These options can include properties such as
* `iterationType`, `isMapMode`, `specifyComparable`, `toEntryFn`, and `isReverse`. The function
* creates a
* @returns An AVLTree object is being returned with the specified options and properties inherited
* from the current object.
* The function creates a new AVL tree with the specified options and returns it.
* @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be
* passed to the `createTree` function. It is used to customize the behavior of the AVL tree that is
* being created.
* @returns a new AVLTree object.
*/
// @ts-ignore
override createTree(options?: AVLTreeOptions<K, V, R>) {
return new AVLTree<K, V, R, NODE>([], {
override createTree(options?: AVLTreeOptions<K, V, R>): TREE {
return new AVLTree<K, V, R, MK, MV, MR, NODE, TREE>([], {
iterationType: this.iterationType,
isMapMode: this._isMapMode,
specifyComparable: this._specifyComparable,
toEntryFn: this._toEntryFn,
isReverse: this._isReverse,
...options
});
}) as TREE;
}
/**
@ -177,12 +167,11 @@ export class AVLTree<
return deletedResults;
}
// @ts-ignore
override map<MK, MV, MR>(
override map(
callback: EntryCallback<K, V | undefined, [MK, MV]>,
options?: AVLTreeOptions<MK, MV, MR>,
thisArg?: any
) {
): AVLTree<MK, MV, MR> {
const newTree = new AVLTree<MK, MV, MR>([], options);
let index = 0;
for (const [key, value] of this) {
@ -279,7 +268,7 @@ export class AVLTree<
protected _balanceLL(A: NODE): void {
const parentOfA = A.parent;
const B = A.left;
A.parent = B;
if (B !== null) A.parent = B;
if (B && B.right) {
B.right.parent = A;
}
@ -316,12 +305,12 @@ export class AVLTree<
if (B) {
C = B.right;
}
if (A) A.parent = C;
if (B) B.parent = C;
if (A && C !== null) A.parent = C;
if (B && C !== null) B.parent = C;
if (C) {
if (C.left) {
C.left.parent = B;
if (B !== null) C.left.parent = B;
}
if (C.right) {
C.right.parent = A;
@ -363,7 +352,7 @@ export class AVLTree<
protected _balanceRR(A: NODE): void {
const parentOfA = A.parent;
const B = A.right;
A.parent = B;
if (B !== null) A.parent = B;
if (B) {
if (B.left) {
B.left.parent = A;
@ -406,15 +395,15 @@ export class AVLTree<
C = B.left;
}
A.parent = C;
if (B) B.parent = C;
if (C !== null) A.parent = C;
if (B && C !== null) B.parent = C;
if (C) {
if (C.left) {
C.left.parent = A;
}
if (C.right) {
C.right.parent = B;
if (B !== null) C.right.parent = B;
}
C.parent = parentOfA;
}

View file

@ -8,6 +8,7 @@
import {
BinaryTreeDeleteResult,
BinaryTreeNested,
BinaryTreeNodeNested,
BinaryTreeOptions,
BinaryTreePrintOptions,
@ -22,6 +23,7 @@ import {
NodeDisplayLayout,
NodePredicate,
OptNodeOrNull,
type RBTNColor,
ToEntryFn
} from '../../types';
import { IBinaryTree } from '../../interfaces';
@ -51,7 +53,7 @@ export class BinaryTreeNode<
this.value = value;
}
protected _left?: OptNodeOrNull<NODE>;
_left?: OptNodeOrNull<NODE>;
get left(): OptNodeOrNull<NODE> {
return this._left;
@ -64,7 +66,7 @@ export class BinaryTreeNode<
this._left = v;
}
protected _right?: OptNodeOrNull<NODE>;
_right?: OptNodeOrNull<NODE>;
get right(): OptNodeOrNull<NODE> {
return this._right;
@ -77,6 +79,36 @@ export class BinaryTreeNode<
this._right = v;
}
_height: number = 0;
get height(): number {
return this._height;
}
set height(value: number) {
this._height = value;
}
_color: RBTNColor = 'BLACK';
get color(): RBTNColor {
return this._color;
}
set color(value: RBTNColor) {
this._color = value;
}
_count: number = 1;
get count(): number {
return this._count;
}
set count(value: number) {
this._count = value;
}
get familyPosition(): FamilyPosition {
const that = this as unknown as NODE;
if (!this.parent) {
@ -104,10 +136,23 @@ export class BinaryTree<
K = any,
V = any,
R = object,
NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>
MK = any,
MV = any,
MR = object,
NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>,
TREE extends BinaryTree<K, V, R, MK, MV, MR, NODE, TREE> = BinaryTree<
K,
V,
R,
MK,
MV,
MR,
NODE,
BinaryTreeNested<K, V, R, MK, MV, MR, NODE>
>
>
extends IterableEntryBase<K, V | undefined>
implements IBinaryTree<K, V, R, NODE>
implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
{
iterationType: IterationType = 'ITERATIVE';
@ -186,26 +231,63 @@ export class BinaryTree<
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `createTree` function creates a new binary tree based on the provided options.
* @param [options] - The `options` parameter in the `createTree` method is of type
* `BinaryTreeOptions<K, V, R>`. This type likely contains configuration options for creating a
* binary tree, such as the iteration type, whether the tree is in map mode, and functions for
* converting entries.
* @returns The `createTree` method is returning an instance of the `BinaryTree` class with the
* provided options. The method is creating a new `BinaryTree` object with an empty array as the
* initial data, and then setting various options such as `iterationType`, `isMapMode`, and
* `toEntryFn` based on the current object's properties and the provided `options`. Finally, it
* The function creates a binary tree with the specified options.
* @param [options] - The `options` parameter in the `createTree` function is an optional parameter
* that allows you to provide partial configuration options for creating a binary tree. It is of type
* `Partial<BinaryTreeOptions<K, V, R>>`, which means you can pass in an object containing a subset
* of properties
* @returns A new instance of a binary tree with the specified options is being returned.
*/
createTree(options?: BinaryTreeOptions<K, V, R>): typeof this {
return new BinaryTree<K, V, R>([], {
createTree(options?: BinaryTreeOptions<K, V, R>): TREE {
return new BinaryTree<K, V, R, MK, MV, MR, NODE, TREE>([], {
iterationType: this.iterationType,
isMapMode: this._isMapMode,
toEntryFn: this._toEntryFn,
...options
}) as unknown as typeof this;
}) as TREE;
}
/**
* The function `keyValueNodeEntryRawToNodeAndValue` converts various input types into a node object
* or returns null.
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The
* `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `keyNodeEntryOrRaw`, which
* can be of type `BTNRep<K, V, NODE>` or `R`. This parameter represents either a key, a
* node, an entry
* @param {V} [value] - The `value` parameter in the `keyValueNodeEntryRawToNodeAndValue` function is
* an optional parameter of type `V`. It represents the value associated with the key in the node
* being created. If a `value` is provided, it will be used when creating the node. If
* @returns The `keyValueNodeEntryRawToNodeAndValue` function returns an optional node
* (`OptNodeOrNull<NODE>`) based on the input parameters provided. The function checks the type of the
* input parameter (`keyNodeEntryOrRaw`) and processes it accordingly to return a node or null
* value.
*/
protected _keyValueNodeEntryRawToNodeAndValue(
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
value?: V
): [OptNodeOrNull<NODE>, V | undefined] {
if (keyNodeEntryOrRaw === undefined) return [undefined, undefined];
if (keyNodeEntryOrRaw === null) return [null, undefined];
if (this.isNode(keyNodeEntryOrRaw)) return [keyNodeEntryOrRaw, value];
if (this.isEntry(keyNodeEntryOrRaw)) {
const [key, entryValue] = keyNodeEntryOrRaw;
if (key === undefined) return [undefined, undefined];
else if (key === null) return [null, undefined];
const finalValue = value ?? entryValue;
return [this.createNode(key, finalValue), finalValue];
}
if (this.isRaw(keyNodeEntryOrRaw)) {
const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw);
const finalValue = value ?? entryValue;
if (this.isKey(key)) return [this.createNode(key, finalValue), finalValue];
}
if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value), value];
return [undefined, undefined];
}
/**
@ -490,7 +572,7 @@ export class BinaryTree<
* elements from the other tree.
* @param anotherTree - `BinaryTree<K, V, R, NODE, TREE>`
*/
merge(anotherTree: this) {
merge(anotherTree: BinaryTree<K, V, R, NODE, TREE>) {
this.addMany(anotherTree, []);
}
@ -1599,7 +1681,7 @@ export class BinaryTree<
* original tree using breadth-first search (bfs), and adds the nodes to the new tree. If a node in
* the original tree is null, a null node is added to the cloned tree. If a node
*/
clone() {
clone(): TREE {
const cloned = this.createTree();
this.bfs(
node => {
@ -1663,11 +1745,11 @@ export class BinaryTree<
* @returns The `map` function is returning a new `BinaryTree` instance filled with entries that are
* the result of applying the provided `callback` function to each entry in the original tree.
*/
map<MK, MV, MR>(
map(
callback: EntryCallback<K, V | undefined, [MK, MV]>,
options?: BinaryTreeOptions<MK, MV, MR>,
thisArg?: any
) {
): BinaryTree<MK, MV, MR> {
const newTree = new BinaryTree<MK, MV, MR>([], options);
let index = 0;
for (const [key, value] of this) {
@ -1736,49 +1818,6 @@ export class BinaryTree<
console.log(this.toVisual(startNode, options));
}
/**
* The function `keyValueNodeEntryRawToNodeAndValue` converts various input types into a node object
* or returns null.
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The
* `keyValueNodeEntryRawToNodeAndValue` function takes in a parameter `keyNodeEntryOrRaw`, which
* can be of type `BTNRep<K, V, NODE>` or `R`. This parameter represents either a key, a
* node, an entry
* @param {V} [value] - The `value` parameter in the `keyValueNodeEntryRawToNodeAndValue` function is
* an optional parameter of type `V`. It represents the value associated with the key in the node
* being created. If a `value` is provided, it will be used when creating the node. If
* @returns The `keyValueNodeEntryRawToNodeAndValue` function returns an optional node
* (`OptNodeOrNull<NODE>`) based on the input parameters provided. The function checks the type of the
* input parameter (`keyNodeEntryOrRaw`) and processes it accordingly to return a node or null
* value.
*/
protected _keyValueNodeEntryRawToNodeAndValue(
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
value?: V
): [OptNodeOrNull<NODE>, V | undefined] {
if (keyNodeEntryOrRaw === undefined) return [undefined, undefined];
if (keyNodeEntryOrRaw === null) return [null, undefined];
if (this.isNode(keyNodeEntryOrRaw)) return [keyNodeEntryOrRaw, value];
if (this.isEntry(keyNodeEntryOrRaw)) {
const [key, entryValue] = keyNodeEntryOrRaw;
if (key === undefined) return [undefined, undefined];
else if (key === null) return [null, undefined];
const finalValue = value ?? entryValue;
return [this.createNode(key, finalValue), finalValue];
}
if (this.isRaw(keyNodeEntryOrRaw)) {
const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw);
const finalValue = value ?? entryValue;
if (this.isKey(key)) return [this.createNode(key, finalValue), finalValue];
}
if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value), value];
return [undefined, undefined];
}
/**
* Time complexity: O(n)
* Space complexity: O(n)

View file

@ -6,6 +6,7 @@
* @license MIT License
*/
import {
BSTNested,
BSTNodeNested,
BSTNOptKeyOrNode,
BSTOptions,
@ -18,7 +19,8 @@ import {
IterationType,
NodeCallback,
NodePredicate,
OptNode
OptNode,
OptNodeOrNull
} from '../../types';
import { BinaryTree, BinaryTreeNode } from './binary-tree';
import { IBinaryTree } from '../../interfaces';
@ -40,13 +42,13 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
this._right = undefined;
}
protected override _left?: NODE;
override _left?: OptNodeOrNull<NODE>;
/**
* The function returns the value of the `_left` property.
* @returns The `_left` property of the current object is being returned.
*/
override get left(): OptNode<NODE> {
override get left(): OptNodeOrNull<NODE> {
return this._left;
}
@ -55,21 +57,21 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
* @param {OptNode<NODE>} v - The parameter `v` is of type `OptNode<NODE>`. It can either be an
* instance of the `NODE` class or `undefined`.
*/
override set left(v: OptNode<NODE>) {
override set left(v: OptNodeOrNull<NODE>) {
if (v) {
v.parent = this as unknown as NODE;
}
this._left = v;
}
protected override _right?: NODE;
override _right?: OptNodeOrNull<NODE>;
/**
* The function returns the right node of a binary tree or undefined if there is no right node.
* @returns The method is returning the value of the `_right` property, which is of type `NODE` or
* `undefined`.
*/
override get right(): OptNode<NODE> {
override get right(): OptNodeOrNull<NODE> {
return this._right;
}
@ -78,7 +80,7 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
* @param {OptNode<NODE>} v - The parameter `v` is of type `OptNode<NODE>`. It can either be a
* `NODE` object or `undefined`.
*/
override set right(v: OptNode<NODE>) {
override set right(v: OptNodeOrNull<NODE>) {
if (v) {
v.parent = this as unknown as NODE;
}
@ -151,9 +153,27 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
* console.log(findLCA(5, 35)); // 15
* console.log(findLCA(20, 30)); // 25
*/
export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>>
extends BinaryTree<K, V, R, NODE>
implements IBinaryTree<K, V, R, NODE>
export class BST<
K = any,
V = any,
R = object,
MK = any,
MV = any,
MR = object,
NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>,
TREE extends BST<K, V, R, MK, MV, MR, NODE, TREE> = BST<
K,
V,
R,
MK,
MV,
MR,
NODE,
BSTNested<K, V, R, MK, MV, MR, NODE>
>
>
extends BinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
{
/**
* This is the constructor function for a Binary Search Tree class in TypeScript.
@ -196,45 +216,6 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
return this._isReverse;
}
protected _comparator: Comparator<K> = (a: K, b: K): number => {
if (isComparable(a) && isComparable(b)) {
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
if (this._specifyComparable) {
if (this._specifyComparable(a) > this._specifyComparable(b)) return 1;
if (this._specifyComparable(a) < this._specifyComparable(b)) return -1;
return 0;
}
if (typeof a === 'object' || typeof b === 'object') {
throw TypeError(
`When comparing object types, a custom specifyComparable must be defined in the constructor's options parameter.`
);
}
return 0;
};
/**
* The function returns the value of the _comparator property.
* @returns The `_comparator` property is being returned.
*/
get comparator() {
return this._comparator;
}
protected _specifyComparable?: (key: K) => Comparable;
/**
* This function returns the value of the `_specifyComparable` property.
* @returns The method `specifyComparable()` is being returned, which is a getter method for the
* `_specifyComparable` property.
*/
get specifyComparable() {
return this._specifyComparable;
}
/**
* The function creates a new BSTNode with the given key and value and returns it.
* @param {K} key - The key parameter is of type K, which represents the type of the key for the node
@ -248,26 +229,39 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The `createTree` function in TypeScript overrides the default options with the provided options to
* create a new Binary Search Tree.
* @param [options] - The `options` parameter in the `createTree` method is an optional object that
* can contain the following properties:
* @returns A new instance of a Binary Search Tree (BST) is being returned with the specified options
* and properties inherited from the current instance.
* The function creates a new binary search tree with the specified options.
* @param [options] - The `options` parameter is an optional object that allows you to customize the
* behavior of the `createTree` method. It accepts a partial `BSTOptions` object, which has the
* following properties:
* @returns a new instance of the BST class with the provided options.
*/
// @ts-ignore
override createTree(options?: BSTOptions<K, V, R>) {
return new BST<K, V, R>([], {
override createTree(options?: BSTOptions<K, V, R>): TREE {
return new BST<K, V, R, MK, MV, MR, NODE, TREE>([], {
iterationType: this.iterationType,
isMapMode: this._isMapMode,
specifyComparable: this._specifyComparable,
toEntryFn: this._toEntryFn,
isReverse: this._isReverse,
...options
});
}) as TREE;
}
/**
* The function overrides a method and converts a key, value pair or entry or raw element to a node.
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - A variable that can be of
* type R or BTNRep<K, V, NODE>. It represents either a key, a node, an entry, or a raw
* element.
* @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
* value associated with a key in a key-value pair.
* @returns either a NODE object or undefined.
*/
protected override _keyValueNodeEntryRawToNodeAndValue(
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
value?: V
): [OptNode<NODE>, V | undefined] {
const [node, entryValue] = super._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
if (node === null) return [undefined, undefined];
return [node, value ?? entryValue];
}
/**
@ -350,7 +344,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
this._size++;
return true;
}
current = current.left;
if (current.left !== null) current = current.left;
} else {
if (current.right === undefined) {
current.right = newNode;
@ -358,7 +352,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
this._size++;
return true;
}
current = current.right;
if (current.right !== null) current = current.right;
}
}
@ -483,19 +477,6 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
return inserted;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
*
* The `merge` function overrides the base class method by adding elements from another
* binary search tree.
* @param anotherTree - `anotherTree` is an instance of a Binary Search Tree (BST) with key type `K`,
* value type `V`, return type `R`, node type `NODE`, and tree type `TREE`.
*/
override merge(anotherTree: this) {
this.addMany(anotherTree, [], false);
}
/**
* Time Complexity: O(log n)
* Space Complexity: O(k + log n)
@ -906,7 +887,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
let balanced = true;
if (iterationType === 'RECURSIVE') {
const _height = (cur: OptNode<NODE>): number => {
const _height = (cur: OptNodeOrNull<NODE>): number => {
if (!cur) return 0;
const leftHeight = _height(cur.left),
rightHeight = _height(cur.right);
@ -923,7 +904,7 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
while (stack.length > 0 || node) {
if (node) {
stack.push(node);
node = node.left;
if (node.left !== null) node = node.left;
} else {
node = stack[stack.length - 1];
if (!node.right || last === node.right) {
@ -944,36 +925,43 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
return balanced;
}
// @ts-ignore
override map<MK, MV, MR>(
callback: EntryCallback<K, V | undefined, [MK, MV]>,
options?: BSTOptions<MK, MV, MR>,
thisArg?: any
) {
const newTree = new BST<MK, MV, MR>([], options);
let index = 0;
for (const [key, value] of this) {
newTree.add(callback.call(thisArg, key, value, index++, this));
protected _comparator: Comparator<K> = (a: K, b: K): number => {
if (isComparable(a) && isComparable(b)) {
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
return newTree;
}
if (this._specifyComparable) {
if (this._specifyComparable(a) > this._specifyComparable(b)) return 1;
if (this._specifyComparable(a) < this._specifyComparable(b)) return -1;
return 0;
}
if (typeof a === 'object' || typeof b === 'object') {
throw TypeError(
`When comparing object types, a custom specifyComparable must be defined in the constructor's options parameter.`
);
}
return 0;
};
/**
* The function overrides a method and converts a key, value pair or entry or raw element to a node.
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - A variable that can be of
* type R or BTNRep<K, V, NODE>. It represents either a key, a node, an entry, or a raw
* element.
* @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
* value associated with a key in a key-value pair.
* @returns either a NODE object or undefined.
* The function returns the value of the _comparator property.
* @returns The `_comparator` property is being returned.
*/
protected override _keyValueNodeEntryRawToNodeAndValue(
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
value?: V
): [OptNode<NODE>, V | undefined] {
const [node, entryValue] = super._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
if (node === null) return [undefined, undefined];
return [node, value ?? entryValue];
get comparator() {
return this._comparator;
}
protected _specifyComparable?: (key: K) => Comparable;
/**
* This function returns the value of the `_specifyComparable` property.
* @returns The method `specifyComparable()` is being returned, which is a getter method for the
* `_specifyComparable` property.
*/
get specifyComparable() {
return this._specifyComparable;
}
/**
@ -991,4 +979,17 @@ export class BST<K = any, V = any, R = object, NODE extends BSTNode<K, V, NODE>
protected _compare(a: K, b: K) {
return this._isReverse ? -this._comparator(a, b) : this._comparator(a, b);
}
override map(
callback: EntryCallback<K, V | undefined, [MK, MV]>,
options?: BSTOptions<MK, MV, MR>,
thisArg?: any
): BST<MK, MV, MR> {
const newTree = new BST<MK, MV, MR>([], options);
let index = 0;
for (const [key, value] of this) {
newTree.add(callback.call(thisArg, key, value, index++, this));
}
return newTree;
}
}

View file

@ -6,6 +6,7 @@ import type {
OptNode,
RBTNColor,
RedBlackTreeOptions,
RedBlackTreeNested,
RedBlackTreeNodeNested
} from '../../types';
import { BST, BSTNode } from './bst';
@ -31,24 +32,6 @@ export class RedBlackTreeNode<
super(key, value);
this._color = color;
}
protected _color: RBTNColor;
/**
* The function returns the color value of a variable.
* @returns The color value stored in the private variable `_color`.
*/
get color(): RBTNColor {
return this._color;
}
/**
* The function sets the color property to the specified value.
* @param {RBTNColor} value - The value parameter is of type RBTNColor.
*/
set color(value: RBTNColor) {
this._color = value;
}
}
/**
@ -108,16 +91,29 @@ export class RedBlackTree<
K = any,
V = any,
R = object,
NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>
MK = any,
MV = any,
MR = object,
NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>,
TREE extends RedBlackTree<K, V, R, MK, MV, MR, NODE, TREE> = RedBlackTree<
K,
V,
R,
MK,
MV,
MR,
NODE,
RedBlackTreeNested<K, V, R, MK, MV, MR, NODE>
>
>
extends BST<K, V, R, NODE>
implements IBinaryTree<K, V, R, NODE>
extends BST<K, V, R, MK, MV, MR, NODE, TREE>
implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
{
/**
* This is the constructor function for a Red-Black Tree data structure in TypeScript.
* @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter is an
* iterable object that can contain either keys, nodes, entries, or raw elements. It is used to
* initialize the RedBlackTree with the provided elements.
* initialize the RBTree with the provided elements.
* @param [options] - The `options` parameter is an optional object that can be passed to the
* constructor. It is of type `RedBlackTreeOptions<K, V, R>`. This object can contain various options for
* configuring the behavior of the Red-Black Tree. The specific properties and their meanings would
@ -162,23 +158,19 @@ export class RedBlackTree<
}
/**
* The function `createTree` overrides the default implementation to create a Red-Black Tree with
* specified options in TypeScript.
* @param [options] - The `options` parameter in the `createTree` method is of type `RedBlackTreeOptions<K,
* V, R>`, which is a generic type with three type parameters `K`, `V`, and `R`. This parameter
* allows you to pass additional configuration options when creating a new Red-
* @returns A new instance of a RedBlackTree with the specified options and properties from the
* current object is being returned.
* The function creates a new Red-Black Tree with the specified options.
* @param [options] - The `options` parameter is an optional object that contains additional
* configuration options for creating the Red-Black Tree. It has the following properties:
* @returns a new instance of a RedBlackTree object.
*/
// @ts-ignore
override createTree(options?: RedBlackTreeOptions<K, V, R>) {
return new RedBlackTree<K, V, R>([], {
override createTree(options?: RedBlackTreeOptions<K, V, R>): TREE {
return new RedBlackTree<K, V, R, MK, MV, MR, NODE, TREE>([], {
iterationType: this.iterationType,
isMapMode: this._isMapMode,
specifyComparable: this._specifyComparable,
toEntryFn: this._toEntryFn,
...options
});
}) as TREE;
}
/**
@ -276,8 +268,10 @@ export class RedBlackTree<
let replacementNode: NODE | undefined;
if (!this.isRealNode(nodeToDelete.left)) {
replacementNode = nodeToDelete.right;
this._transplant(nodeToDelete, nodeToDelete.right);
if (nodeToDelete.right !== null) {
replacementNode = nodeToDelete.right;
this._transplant(nodeToDelete, nodeToDelete.right);
}
} else if (!this.isRealNode(nodeToDelete.right)) {
replacementNode = nodeToDelete.left;
this._transplant(nodeToDelete, nodeToDelete.left);
@ -285,15 +279,17 @@ export class RedBlackTree<
const successor = this.getLeftMost(node => node, nodeToDelete.right);
if (successor) {
originalColor = successor.color;
replacementNode = successor.right;
if (successor.right !== null) replacementNode = successor.right;
if (successor.parent === nodeToDelete) {
if (this.isRealNode(replacementNode)) {
replacementNode.parent = successor;
}
} else {
this._transplant(successor, successor.right);
successor.right = nodeToDelete.right;
if (successor.right !== null) {
this._transplant(successor, successor.right);
successor.right = nodeToDelete.right;
}
if (this.isRealNode(successor.right)) {
successor.right.parent = successor;
}
@ -320,40 +316,6 @@ export class RedBlackTree<
return results;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(n)
*
* The `map` function in TypeScript overrides the default behavior to create a new Red-Black Tree by
* applying a callback to each entry in the original tree.
* @param callback - A function that will be called for each entry in the tree, with parameters
* representing the key, value, index, and the tree itself. It should return an entry for the new
* tree.
* @param [options] - The `options` parameter in the `map` method is of type `RedBlackTreeOptions<MK, MV,
* MR>`. This parameter allows you to specify additional options or configurations for the Red-Black
* Tree that will be created during the mapping process. These options could include things like
* custom comparators
* @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
* the value of `this` when executing the `callback` function. It allows you to set the context
* (value of `this`) for the callback function. This can be useful when you want to access properties
* or
* @returns A new Red-Black Tree is being returned, where each entry has been transformed using the
* provided callback function.
*/
// @ts-ignore
override map<MK, MV, MR>(
callback: EntryCallback<K, V | undefined, [MK, MV]>,
options?: RedBlackTreeOptions<MK, MV, MR>,
thisArg?: any
) {
const newTree = new RedBlackTree<MK, MV, MR>([], options);
let index = 0;
for (const [key, value] of this) {
newTree.add(callback.call(thisArg, key, value, index++, this));
}
return newTree;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
@ -498,7 +460,7 @@ export class RedBlackTree<
} else {
// Symmetric case for the right child (left and right exchanged)
// Follow the same logic as above with left and right exchanged
const y: NODE | undefined = z?.parent?.parent?.left;
const y: NODE | undefined = z?.parent?.parent?.left ?? undefined;
if (y?.color === 'RED') {
z.parent.color = 'BLACK';
y.color = 'BLACK';
@ -675,4 +637,37 @@ export class RedBlackTree<
x.right = y;
y.parent = x;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(n)
*
* The `map` function in TypeScript overrides the default behavior to create a new Red-Black Tree by
* applying a callback to each entry in the original tree.
* @param callback - A function that will be called for each entry in the tree, with parameters
* representing the key, value, index, and the tree itself. It should return an entry for the new
* tree.
* @param [options] - The `options` parameter in the `map` method is of type `RedBlackTreeOptions<MK, MV,
* MR>`. This parameter allows you to specify additional options or configurations for the Red-Black
* Tree that will be created during the mapping process. These options could include things like
* custom comparators
* @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
* the value of `this` when executing the `callback` function. It allows you to set the context
* (value of `this`) for the callback function. This can be useful when you want to access properties
* or
* @returns A new Red-Black Tree is being returned, where each entry has been transformed using the
* provided callback function.
*/
override map(
callback: EntryCallback<K, V | undefined, [MK, MV]>,
options?: RedBlackTreeOptions<MK, MV, MR>,
thisArg?: any
): RedBlackTree<MK, MV, MR> {
const newTree = new RedBlackTree<MK, MV, MR>([], options);
let index = 0;
for (const [key, value] of this) {
newTree.add(callback.call(thisArg, key, value, index++, this));
}
return newTree;
}
}

View file

@ -13,6 +13,7 @@ import type {
IterationType,
OptNode,
RBTNColor,
TreeMultiMapNested,
TreeMultiMapNodeNested,
TreeMultiMapOptions
} from '../../types';
@ -40,35 +41,29 @@ export class TreeMultiMapNode<
super(key, value, color);
this.count = count;
}
protected _count: number = 1;
/**
* The function returns the value of the private variable _count.
* @returns The count property of the object, which is of type number.
*/
get count(): number {
return this._count;
}
/**
* The above function sets the value of the count property.
* @param {number} value - The value parameter is of type number, which means it can accept any
* numeric value.
*/
set count(value: number) {
this._count = value;
}
}
export class TreeMultiMap<
K = any,
V = any,
R = object,
NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNode<K, V, TreeMultiMapNodeNested<K, V>>
MK = any,
MV = any,
MR = object,
NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNode<K, V, TreeMultiMapNodeNested<K, V>>,
TREE extends TreeMultiMap<K, V, R, MK, MV, MR, NODE, TREE> = TreeMultiMap<
K,
V,
R,
MK,
MV,
MR,
NODE,
TreeMultiMapNested<K, V, R, MK, MV, MR, NODE>
>
>
extends RedBlackTree<K, V, R, NODE>
implements IBinaryTree<K, V, R, NODE>
extends RedBlackTree<K, V, R, MK, MV, MR, NODE, TREE>
implements IBinaryTree<K, V, R, MK, MV, MR, NODE, TREE>
{
/**
* The constructor function initializes a TreeMultiMap object with optional initial data.
@ -134,15 +129,53 @@ export class TreeMultiMap<
* @returns a new instance of the `TreeMultiMap` class, with the provided options merged with the
* existing `iterationType` property. The returned value is casted as `TREE`.
*/
// @ts-ignore
override createTree(options?: TreeMultiMapOptions<K, V, R>) {
return new TreeMultiMap<K, V, R, NODE>([], {
override createTree(options?: TreeMultiMapOptions<K, V, R>): TREE {
return new TreeMultiMap<K, V, R, MK, MV, MR, NODE, TREE>([], {
iterationType: this.iterationType,
isMapMode: this._isMapMode,
specifyComparable: this._specifyComparable,
toEntryFn: this._toEntryFn,
...options
});
}) as TREE;
}
/**
* The function `keyValueNodeEntryRawToNodeAndValue` takes in a key, value, and count and returns a
* node based on the input.
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
* `keyNodeEntryOrRaw` can be of type `R` or `BTNRep<K, V, NODE>`.
* @param {V} [value] - The `value` parameter is an optional value that represents the value
* associated with the key in the node. It is used when creating a new node or updating the value of
* an existing node.
* @param [count=1] - The `count` parameter is an optional parameter that specifies the number of
* times the key-value pair should be added to the data structure. If not provided, it defaults to 1.
* @returns either a NODE object or undefined.
*/
protected override _keyValueNodeEntryRawToNodeAndValue(
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
value?: V,
count = 1
): [NODE | undefined, V | undefined] {
if (keyNodeEntryOrRaw === undefined || keyNodeEntryOrRaw === null) return [undefined, undefined];
if (this.isNode(keyNodeEntryOrRaw)) return [keyNodeEntryOrRaw, value];
if (this.isEntry(keyNodeEntryOrRaw)) {
const [key, entryValue] = keyNodeEntryOrRaw;
if (key === undefined || key === null) return [undefined, undefined];
const finalValue = value ?? entryValue;
if (this.isKey(key)) return [this.createNode(key, finalValue, 'BLACK', count), finalValue];
}
if (this.isRaw(keyNodeEntryOrRaw)) {
const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw);
const finalValue = value ?? entryValue;
if (this.isKey(key)) return [this.createNode(key, finalValue, 'BLACK', count), finalValue];
}
if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value, 'BLACK', count), value];
return [undefined, undefined];
}
/**
@ -217,10 +250,12 @@ export class TreeMultiMap<
let replacementNode: NODE | undefined;
if (!this.isRealNode(nodeToDelete.left)) {
replacementNode = nodeToDelete.right;
if (nodeToDelete.right !== null) replacementNode = nodeToDelete.right;
if (ignoreCount || nodeToDelete.count <= 1) {
this._transplant(nodeToDelete, nodeToDelete.right);
this._count -= nodeToDelete.count;
if (nodeToDelete.right !== null) {
this._transplant(nodeToDelete, nodeToDelete.right);
this._count -= nodeToDelete.count;
}
} else {
nodeToDelete.count--;
this._count--;
@ -242,7 +277,7 @@ export class TreeMultiMap<
const successor = this.getLeftMost(node => node, nodeToDelete.right);
if (successor) {
originalColor = successor.color;
replacementNode = successor.right;
if (successor.right !== null) replacementNode = successor.right;
if (successor.parent === nodeToDelete) {
if (this.isRealNode(replacementNode)) {
@ -250,8 +285,10 @@ export class TreeMultiMap<
}
} else {
if (ignoreCount || nodeToDelete.count <= 1) {
this._transplant(successor, successor.right);
this._count -= nodeToDelete.count;
if (successor.right !== null) {
this._transplant(successor, successor.right);
this._count -= nodeToDelete.count;
}
} else {
nodeToDelete.count--;
this._count--;
@ -363,82 +400,13 @@ export class TreeMultiMap<
* The function overrides the clone method to create a deep copy of a tree object.
* @returns The `clone()` method is returning a cloned instance of the `TREE` object.
*/
// @ts-ignore
override clone() {
override clone(): TREE {
const cloned = this.createTree();
this.bfs(node => cloned.add(node.key, undefined, node.count));
if (this._isMapMode) cloned._store = this._store;
return cloned;
}
/**
* The `map` function in TypeScript overrides the default behavior to create a new TreeMultiMap with
* modified entries based on a provided callback.
* @param callback - The `callback` parameter is a function that will be called for each entry in the
* map. It takes four arguments:
* @param [options] - The `options` parameter in the `override map` function is of type
* `TreeMultiMapOptions<MK, MV, MR>`. This parameter allows you to provide additional configuration
* options when creating a new `TreeMultiMap` instance within the `map` function. These options could
* include things like
* @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
* the value of `this` when executing the `callback` function. It allows you to set the context
* (value of `this`) for the callback function when it is called within the `map` function. This
* @returns A new TreeMultiMap instance is being returned, which is populated with entries generated
* by the provided callback function.
*/
// @ts-ignore
override map<MK, MV, MR>(
callback: EntryCallback<K, V | undefined, [MK, MV]>,
options?: TreeMultiMapOptions<MK, MV, MR>,
thisArg?: any
) {
const newTree = new TreeMultiMap<MK, MV, MR>([], options);
let index = 0;
for (const [key, value] of this) {
newTree.add(callback.call(thisArg, key, value, index++, this));
}
return newTree;
}
/**
* The function `keyValueNodeEntryRawToNodeAndValue` takes in a key, value, and count and returns a
* node based on the input.
* @param {BTNRep<K, V, NODE> | R} keyNodeEntryOrRaw - The parameter
* `keyNodeEntryOrRaw` can be of type `R` or `BTNRep<K, V, NODE>`.
* @param {V} [value] - The `value` parameter is an optional value that represents the value
* associated with the key in the node. It is used when creating a new node or updating the value of
* an existing node.
* @param [count=1] - The `count` parameter is an optional parameter that specifies the number of
* times the key-value pair should be added to the data structure. If not provided, it defaults to 1.
* @returns either a NODE object or undefined.
*/
protected override _keyValueNodeEntryRawToNodeAndValue(
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
value?: V,
count = 1
): [NODE | undefined, V | undefined] {
if (keyNodeEntryOrRaw === undefined || keyNodeEntryOrRaw === null) return [undefined, undefined];
if (this.isNode(keyNodeEntryOrRaw)) return [keyNodeEntryOrRaw, value];
if (this.isEntry(keyNodeEntryOrRaw)) {
const [key, entryValue] = keyNodeEntryOrRaw;
if (key === undefined || key === null) return [undefined, undefined];
const finalValue = value ?? entryValue;
if (this.isKey(key)) return [this.createNode(key, finalValue, 'BLACK', count), finalValue];
}
if (this.isRaw(keyNodeEntryOrRaw)) {
const [key, entryValue] = this._toEntryFn!(keyNodeEntryOrRaw);
const finalValue = value ?? entryValue;
if (this.isKey(key)) return [this.createNode(key, finalValue, 'BLACK', count), finalValue];
}
if (this.isKey(keyNodeEntryOrRaw)) return [this.createNode(keyNodeEntryOrRaw, value, 'BLACK', count), value];
return [undefined, undefined];
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
@ -496,4 +464,32 @@ export class TreeMultiMap<
newNode.count = oldNode.count + newNode.count;
return super._replaceNode(oldNode, newNode);
}
/**
* The `map` function in TypeScript overrides the default behavior to create a new TreeMultiMap with
* modified entries based on a provided callback.
* @param callback - The `callback` parameter is a function that will be called for each entry in the
* map. It takes four arguments:
* @param [options] - The `options` parameter in the `override map` function is of type
* `TreeMultiMapOptions<MK, MV, MR>`. This parameter allows you to provide additional configuration
* options when creating a new `TreeMultiMap` instance within the `map` function. These options could
* include things like
* @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
* the value of `this` when executing the `callback` function. It allows you to set the context
* (value of `this`) for the callback function when it is called within the `map` function. This
* @returns A new TreeMultiMap instance is being returned, which is populated with entries generated
* by the provided callback function.
*/
override map(
callback: EntryCallback<K, V | undefined, [MK, MV]>,
options?: TreeMultiMapOptions<MK, MV, MR>,
thisArg?: any
): TreeMultiMap<MK, MV, MR> {
const newTree = new TreeMultiMap<MK, MV, MR>([], options);
let index = 0;
for (const [key, value] of this) {
newTree.add(callback.call(thisArg, key, value, index++, this));
}
return newTree;
}
}

View file

@ -1,14 +1,27 @@
import { BinaryTreeNode } from '../data-structures';
import type { BinaryTreeDeleteResult, BinaryTreeNodeNested, BTNRep, NodePredicate } from '../types';
import { BinaryTree, BinaryTreeNode } from '../data-structures';
import type {
BinaryTreeDeleteResult,
BinaryTreeNested,
BinaryTreeNodeNested,
BinaryTreeOptions,
BTNRep,
NodePredicate
} from '../types';
export interface IBinaryTree<
K = any,
V = any,
R = object,
NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNodeNested<K, V>
MK = any,
MV = any,
MR = object,
NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNodeNested<K, V>,
TREE extends BinaryTree<K, V, R, MK, MV, MR, NODE, TREE> = BinaryTreeNested<K, V, R, MK, MV, MR, NODE>
> {
createNode(key: K, value?: NODE['value']): NODE;
createTree(options?: Partial<BinaryTreeOptions<K, V, R>>): TREE;
add(keyOrNodeOrEntryOrRawElement: BTNRep<K, V, NODE>, value?: V, count?: number): boolean;
addMany(nodes: Iterable<BTNRep<K, V, NODE>>, values?: Iterable<V | undefined>): boolean[];

View file

@ -1,6 +1,8 @@
import { AVLTreeMultiMapNode } from '../../../data-structures';
import { AVLTreeMultiMap, AVLTreeMultiMapNode } from '../../../data-structures';
import type { AVLTreeOptions } from './avl-tree';
export type AVLTreeMultiMapNodeNested<K, V> = AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, any>>>>>>>>>>
export type AVLTreeMultiMapNodeNested<K, V> = AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNode<K, V, any>>>
export type AVLTreeMultiMapNested<K, V, R, MK, MV, MR, NODE extends AVLTreeMultiMapNode<K, V, NODE>> = AVLTreeMultiMap<K, V, R, MK, MV, MR, NODE, AVLTreeMultiMap<K, V, R, MK, MV, MR, NODE, AVLTreeMultiMap<K, V, R, MK, MV, MR, NODE, any>>>
export type AVLTreeMultiMapOptions<K, V, R> = AVLTreeOptions<K, V, R> & {}

View file

@ -1,6 +1,8 @@
import { AVLTreeNode } from '../../../data-structures';
import { AVLTree, AVLTreeNode } from '../../../data-structures';
import { BSTOptions } from './bst';
export type AVLTreeNodeNested<K, V> = AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, any>>>>>>>>>>
export type AVLTreeNodeNested<K, V> = AVLTreeNode<K, V, AVLTreeNode<K, V, AVLTreeNode<K, V, any>>>
export type AVLTreeNested<K, V, R,MK, MV, MR, NODE extends AVLTreeNode<K, V, NODE>> = AVLTree<K, V, R,MK, MV, MR, NODE, AVLTree<K, V, R,MK, MV, MR, NODE, AVLTree<K, V, R,MK, MV, MR, NODE, any>>>
export type AVLTreeOptions<K, V, R> = BSTOptions<K, V, R> & {};

View file

@ -1,10 +1,10 @@
import { BinaryTreeNode } from '../../../data-structures';
import { BinaryTree, BinaryTreeNode } from '../../../data-structures';
import { IterationType, OptValue } from '../../common';
import { DFSOperation } from '../../../common';
export type BinaryTreeNodeNested<K, V> = BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, any>>>>>>>>>>
export type BinaryTreeNodeNested<K, V> = BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, any>>>
// export type BinaryTreeNested<K, V, R, NODE extends BinaryTreeNode<K, V, NODE>> = BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, BinaryTree<K, V, R, NODE, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type BinaryTreeNested<K, V, R, MK, MV, MR, NODE extends BinaryTreeNode<K, V, NODE>> = BinaryTree<K, V, R, MK, MV, MR, NODE,BinaryTree<K, V, R, MK, MV, MR, NODE,BinaryTree<K, V, R, MK, MV, MR, NODE,any>>>
export type ToEntryFn<K, V, R> = (rawElement: R) => BTNEntry<K, V>;

View file

@ -1,8 +1,10 @@
import { BSTNode } from '../../../data-structures';
import { BST, BSTNode } from '../../../data-structures';
import type { BinaryTreeOptions } from './binary-tree';
import { Comparable } from '../../utils';
export type BSTNodeNested<K, V> = BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, any>>>>>>>>>>
export type BSTNodeNested<K, V> = BSTNode<K, V, BSTNode<K, V, BSTNode<K, V, any>>>
export type BSTNested<K, V, R,MK, MV, MR, NODE extends BSTNode<K, V, NODE>> = BST<K, V, R,MK, MV, MR, NODE,BST<K, V, R,MK, MV, MR, NODE,BST<K, V, R,MK, MV, MR, NODE, any>>>
export type BSTOptions<K, V, R> = BinaryTreeOptions<K, V, R> & {
specifyComparable?: (key: K) => Comparable

View file

@ -1,8 +1,10 @@
import { RedBlackTreeNode } from '../../../data-structures';
import type { BSTOptions } from './bst';
import { RedBlackTree, RedBlackTreeNode } from '../../../data-structures';
import type { BSTOptions } from "./bst";
export type RBTNColor = 'RED' | 'BLACK';
export type RedBlackTreeNodeNested<K, V> = RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, any>>>>>>>>>>
export type RedBlackTreeNodeNested<K, V> = RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, any>>>
export type RedBlackTreeOptions<K, V, R> = Omit<BSTOptions<K, V, R>, 'isReverse'> & {};
export type RedBlackTreeNested<K, V, R, MK, MV, MR, NODE extends RedBlackTreeNode<K, V, NODE>> = RedBlackTree<K, V, R, MK, MV, MR, NODE, RedBlackTree<K, V, R, MK, MV, MR, NODE, RedBlackTree<K, V, R, MK, MV, MR, NODE, any>>>
export type RedBlackTreeOptions<K, V, R> = BSTOptions<K, V, R> & {};

View file

@ -1,6 +1,8 @@
import { TreeMultiMapNode } from '../../../data-structures';
import { TreeMultiMap, TreeMultiMapNode } from '../../../data-structures';
import type { RedBlackTreeOptions } from './rb-tree';
export type TreeMultiMapNodeNested<K, V> = TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, any>>>>>>>>>>
export type TreeMultiMapNodeNested<K, V> = TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, TreeMultiMapNode<K, V, any>>>
export type TreeMultiMapNested<K, V, R, MK, MV, MR, NODE extends TreeMultiMapNode<K, V, NODE>> = TreeMultiMap<K, V, R, MK, MV, MR, NODE, TreeMultiMap<K, V, R, MK, MV, MR, NODE,TreeMultiMap<K, V, R, MK, MV, MR, NODE, any>>>
export type TreeMultiMapOptions<K, V, R> = RedBlackTreeOptions<K, V, R> & {}