[binary-tree] bug fix#27

This commit is contained in:
Revone 2023-10-30 11:14:41 +08:00
parent f87e682f26
commit bf5b865e2c
48 changed files with 300 additions and 230 deletions

View file

@ -3,7 +3,7 @@ module.exports = {
"bracketSpacing": false,
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"bracketSameLine": false,
"bracketSameLine": true,
"jsxSingleQuote": true,
"printWidth": 120,
"proseWrap": "preserve",

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.39.1](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
## [v1.39.2](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
### Changes

12
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "data-structure-typed",
"version": "1.39.1",
"version": "1.39.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "data-structure-typed",
"version": "1.39.1",
"version": "1.39.2",
"license": "MIT",
"devDependencies": {
"@types/benchmark": "^2.1.3",
@ -15,17 +15,17 @@
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"auto-changelog": "^2.4.0",
"avl-tree-typed": "^1.39.0",
"avl-tree-typed": "^1.39.1",
"benchmark": "^2.1.4",
"binary-tree-typed": "^1.39.0",
"bst-typed": "^1.39.0",
"binary-tree-typed": "^1.39.1",
"bst-typed": "^1.39.1",
"dependency-cruiser": "^14.1.0",
"eslint": "^8.50.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"heap-typed": "^1.39.0",
"heap-typed": "^1.39.1",
"istanbul-badges-readme": "^1.8.5",
"jest": "^29.7.0",
"prettier": "^3.0.3",

View file

@ -1,6 +1,6 @@
{
"name": "data-structure-typed",
"version": "1.39.2",
"version": "1.39.3",
"description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
"main": "dist/cjs/index.js",
"module": "dist/mjs/index.js",
@ -61,17 +61,17 @@
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"auto-changelog": "^2.4.0",
"avl-tree-typed": "^1.39.0",
"avl-tree-typed": "^1.39.1",
"benchmark": "^2.1.4",
"binary-tree-typed": "^1.39.0",
"bst-typed": "^1.39.0",
"binary-tree-typed": "^1.39.1",
"bst-typed": "^1.39.1",
"dependency-cruiser": "^14.1.0",
"eslint": "^8.50.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"heap-typed": "^1.39.0",
"heap-typed": "^1.39.1",
"istanbul-badges-readme": "^1.8.5",
"jest": "^29.7.0",
"prettier": "^3.0.3",

View file

@ -6,14 +6,14 @@
* @license MIT License
*/
import {BST, BSTNode} from './bst';
import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BinaryTreeNodeKey} from '../../types';
import {OneParamCallback} from '../../types';
import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BTNKey} from '../../types';
import {BTNCallback} from '../../types';
import {IBinaryTree} from '../../interfaces';
export class AVLTreeNode<V = any, N extends AVLTreeNode<V, N> = AVLTreeNodeNested<V>> extends BSTNode<V, N> {
height: number;
constructor(key: BinaryTreeNodeKey, val?: V) {
constructor(key: BTNKey, val?: V) {
super(key, val);
this.height = 0;
}
@ -21,7 +21,8 @@ export class AVLTreeNode<V = any, N extends AVLTreeNode<V, N> = AVLTreeNodeNeste
export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTreeNodeNested<V>>>
extends BST<V, N>
implements IBinaryTree<V, N> {
implements IBinaryTree<V, N>
{
/**
* This is a constructor function for an AVL tree data structure in TypeScript.
* @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the
@ -34,27 +35,27 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
/**
* The function creates a new AVL tree node with the specified key and value.
* @param {BinaryTreeNodeKey} key - The key parameter is the key value that will be associated with
* @param {BTNKey} key - The key parameter is the key value that will be associated with
* the new node. It is used to determine the position of the node in the binary search tree.
* @param [val] - The parameter `val` is an optional value that can be assigned to the node. It is of
* type `V`, which means it can be any value that is assignable to the `val` property of the
* node type `N`.
* @returns a new AVLTreeNode object with the specified key and value.
*/
override createNode(key: BinaryTreeNodeKey, val?: V): N {
override createNode(key: BTNKey, val?: V): N {
return new AVLTreeNode<V, N>(key, val) as N;
}
/**
* The function overrides the add method of a binary tree node and balances the tree after inserting
* a new node.
* @param {BinaryTreeNodeKey | N | null} keyOrNode - The `keyOrNode` parameter can accept either a
* `BinaryTreeNodeKey` or a `N` (which represents a node in the binary tree) or `null`.
* @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can accept either a
* `BTNKey` or a `N` (which represents a node in the binary tree) or `null`.
* @param [val] - The `val` parameter is the value that you want to assign to the new node that you
* are adding to the binary search tree.
* @returns The method is returning the inserted node (`N`), `null`, or `undefined`.
*/
override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V): N | null | undefined {
override add(keyOrNode: BTNKey | N | null, val?: V): N | null | undefined {
// TODO support node as a param
const inserted = super.add(keyOrNode, val);
if (inserted) this._balancePath(inserted);
@ -65,7 +66,7 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
* The function overrides the delete method of a binary tree and balances the tree after deleting a
* node if necessary.
* @param {ReturnType<C>} identifier - The `identifier` parameter is either a
* `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
* `BTNKey` or a generic type `N`. It represents the property of the node that we are
* searching for. It can be a specific key value or any other property of the node.
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
* value. This value is compared with the `identifier` parameter to determine if the node should be
@ -73,7 +74,7 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
* `this._defaultCallbackByKey`
* @returns The method is returning an array of `BinaryTreeDeletedResult<N>` objects.
*/
override delete<C extends OneParamCallback<N>>(
override delete<C extends BTNCallback<N>>(
identifier: ReturnType<C>,
callback: C = this._defaultCallbackByKey as C
): BinaryTreeDeletedResult<N>[] {
@ -160,7 +161,7 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
// Balance Restoration: If a balance issue is discovered after inserting a node, it requires balance restoration operations. Balance restoration includes four basic cases where rotation operations need to be performed to fix the balance:
switch (
this._balanceFactor(A) // second O(1)
) {
) {
case -2:
if (A && A.left) {
if (this._balanceFactor(A.left) <= 0) {

View file

@ -17,7 +17,7 @@ export class BinaryIndexedTree {
* @param - - `frequency`: The default frequency value. It is optional and has a default
* value of 0.
*/
constructor({frequency = 0, max}: { frequency?: number; max: number }) {
constructor({frequency = 0, max}: {frequency?: number; max: number}) {
this._freq = frequency;
this._max = max;
this._freqMap = {0: 0};

View file

@ -6,7 +6,7 @@
* @license MIT License
*/
import type {BinaryTreeNodeKey, BinaryTreeNodeNested, BinaryTreeOptions, OneParamCallback} from '../../types';
import type {BinaryTreeNodeNested, BinaryTreeOptions, BTNCallback, BTNKey} from '../../types';
import {BinaryTreeDeletedResult, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
import {IBinaryTree} from '../../interfaces';
import {trampoline} from '../../utils';
@ -21,7 +21,7 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
/**
* The key associated with the node.
*/
key: BinaryTreeNodeKey;
key: BTNKey;
/**
* The value stored in the node.
@ -35,10 +35,10 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
/**
* Creates a new instance of BinaryTreeNode.
* @param {BinaryTreeNodeKey} key - The key associated with the node.
* @param {BTNKey} key - The key associated with the node.
* @param {V} val - The value stored in the node.
*/
constructor(key: BinaryTreeNodeKey, val?: V) {
constructor(key: BTNKey, val?: V) {
this.key = key;
this.val = val;
}
@ -108,7 +108,8 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
* @template N - The type of the binary tree's nodes.
*/
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>>
implements IBinaryTree<V, N> {
implements IBinaryTree<V, N>
{
/**
* Creates a new instance of BinaryTree.
* @param {BinaryTreeOptions} [options] - The options for the binary tree.
@ -157,11 +158,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
/**
* Creates a new instance of BinaryTreeNode with the given key and value.
* @param {BinaryTreeNodeKey} key - The key for the new node.
* @param {BTNKey} key - The key for the new node.
* @param {V} val - The value for the new node.
* @returns {N} - The newly created BinaryTreeNode.
*/
createNode(key: BinaryTreeNodeKey, val?: V): N {
createNode(key: BTNKey, val?: V): N {
return new BinaryTreeNode<V, N>(key, val) as N;
}
@ -183,11 +184,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
/**
* Add a node with the given key and value to the binary tree.
* @param {BinaryTreeNodeKey | N | null} keyOrNode - The key or node to add to the binary tree.
* @param {BTNKey | N | null} keyOrNode - The key or node to add to the binary tree.
* @param {V} val - The value for the new node (optional).
* @returns {N | null | undefined} - The inserted node, or null if nothing was inserted, or undefined if the operation failed.
*/
add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V): N | null | undefined {
add(keyOrNode: BTNKey | N | null, val?: V): N | null | undefined {
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
const queue = new Queue<N | null>([root]);
while (queue.size > 0) {
@ -240,14 +241,14 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
/**
* The `addMany` function takes an array of binary tree node IDs or nodes, and optionally an array of corresponding data
* values, and adds them to the binary tree.
* @param {(BinaryTreeNodeKey | null)[] | (N | null)[]} keysOrNodes - An array of BinaryTreeNodeKey or BinaryTreeNode
* @param {(BTNKey | null)[] | (N | null)[]} keysOrNodes - An array of BTNKey or BinaryTreeNode
* objects, or null values.
* @param {V[]} [values] - The `values` parameter is an optional array of values (`V[]`) that corresponds to
* the nodes or node IDs being added. It is used to set the value of each node being added. If `values` is not provided,
* the value of the nodes will be `undefined`.
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], values?: V[]): (N | null | undefined)[] {
addMany(keysOrNodes: (BTNKey | null)[] | (N | null)[], values?: V[]): (N | null | undefined)[] {
// TODO not sure addMany not be run multi times
return keysOrNodes.map((keyOrNode, i) => {
if (keyOrNode instanceof BinaryTreeNode) {
@ -265,33 +266,39 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
/**
* The `refill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data.
* @param {(BinaryTreeNodeKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
* `BinaryTreeNodeKey` or `N` values.
* @param {(BTNKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
* `BTNKey` or `N` values.
* @param {N[] | Array<V>} [data] - The `data` parameter is an optional array of values that will be assigned to
* the nodes being added. If provided, the length of the `data` array should be equal to the length of the `keysOrNodes`
* array. Each value in the `data` array will be assigned to the
* @returns The method is returning a boolean value.
*/
refill(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], data?: Array<V>): boolean {
refill(keysOrNodes: (BTNKey | null)[] | (N | null)[], data?: Array<V>): boolean {
this.clear();
return keysOrNodes.length === this.addMany(keysOrNodes, data).length;
}
delete<C extends BTNCallback<N, BTNKey>>(identifier: BTNKey, callback?: C): BinaryTreeDeletedResult<N>[];
delete<C extends BTNCallback<N, N>>(identifier: N | null, callback?: C): BinaryTreeDeletedResult<N>[];
delete<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C): BinaryTreeDeletedResult<N>[];
/**
* The `delete` function removes a node from a binary search tree and returns the deleted node along
* with the parent node that needs to be balanced.
* a key (`BinaryTreeNodeKey`). If it is a key, the function will find the corresponding node in the
* a key (`BTNKey`). If it is a key, the function will find the corresponding node in the
* binary tree.
* @returns an array of `BinaryTreeDeletedResult<N>` objects.
* @param {ReturnType<C>} identifier - The `identifier` parameter is either a
* `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
* `BTNKey` or a generic type `N`. It represents the property of the node that we are
* searching for. It can be a specific key value or any other property of the node.
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
* value. This value is compared with the `identifier` parameter to determine if the node should be
* included in the result. The `callback` parameter has a default value of
* `this._defaultCallbackByKey`, which
*/
delete<C extends OneParamCallback<N>>(
delete<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null,
callback: C = this._defaultCallbackByKey as C
): BinaryTreeDeletedResult<N>[] {
@ -341,16 +348,16 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
/**
* The function `getDepth` calculates the depth of a given node in a binary tree relative to a
* specified root node.
* @param {BinaryTreeNodeKey | N | null} distNode - The `distNode` parameter represents the node
* @param {BTNKey | N | null} distNode - The `distNode` parameter represents the node
* whose depth we want to find in the binary tree. It can be either a node object (`N`), a key value
* of the node (`BinaryTreeNodeKey`), or `null`.
* @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter represents the
* of the node (`BTNKey`), or `null`.
* @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter represents the
* starting node from which we want to calculate the depth. It can be either a node object or the key
* of a node in the binary tree. If no value is provided for `beginRoot`, it defaults to the root
* node of the binary tree.
* @returns the depth of the `distNode` relative to the `beginRoot`.
*/
getDepth(distNode: BinaryTreeNodeKey | N | null, beginRoot: BinaryTreeNodeKey | N | null = this.root): number {
getDepth(distNode: BTNKey | N | null, beginRoot: BTNKey | N | null = this.root): number {
if (typeof distNode === 'number') distNode = this.get(distNode);
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
let depth = 0;
@ -367,16 +374,16 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
/**
* The `getHeight` function calculates the maximum height of a binary tree using either recursive or
* iterative approach.
* @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter represents the
* @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter represents the
* starting node from which the height of the binary tree is calculated. It can be either a node
* object (`N`), a key value of a node in the tree (`BinaryTreeNodeKey`), or `null` if no starting
* object (`N`), a key value of a node in the tree (`BTNKey`), or `null` if no starting
* node is specified. If `
* @param iterationType - The `iterationType` parameter is used to determine whether to calculate the
* height of the binary tree using a recursive approach or an iterative approach. It can have two
* possible values:
* @returns the height of the binary tree.
*/
getHeight(beginRoot: BinaryTreeNodeKey | N | null = this.root, iterationType = this.iterationType): number {
getHeight(beginRoot: BTNKey | N | null = this.root, iterationType = this.iterationType): number {
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
if (!beginRoot) return -1;
@ -394,7 +401,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
return -1;
}
const stack: { node: N; depth: number }[] = [{node: beginRoot, depth: 0}];
const stack: {node: N; depth: number}[] = [{node: beginRoot, depth: 0}];
let maxHeight = 0;
while (stack.length > 0) {
@ -478,11 +485,35 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
}
getNodes<C extends BTNCallback<N, BTNKey>>(
identifier: BTNKey,
callback: C,
onlyOne?: boolean,
beginRoot?: N | null,
iterationType?: IterationType
): N[];
getNodes<C extends BTNCallback<N, N>>(
identifier: N | null,
callback: C,
onlyOne?: boolean,
beginRoot?: N | null,
iterationType?: IterationType
): N[];
getNodes<C extends BTNCallback<N>>(
identifier: ReturnType<C>,
callback: C,
onlyOne?: boolean,
beginRoot?: N | null,
iterationType?: IterationType
): N[];
/**
* The function `getNodes` returns an array of nodes that match a given node property, using either
* recursive or iterative traversal.
* @param {ReturnType<C>} identifier - The `identifier` parameter is either a
* `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
* `BTNKey` or a generic type `N`. It represents the property of the node that we are
* searching for. It can be a specific key value or any other property of the node.
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
* value. This value is compared with the `identifier` parameter to determine if the node should be
@ -499,7 +530,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* traverse the binary tree. It can have two possible values:
* @returns The function `getNodes` returns an array of nodes (`N[]`).
*/
getNodes<C extends OneParamCallback<N>>(
getNodes<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null,
callback: C = this._defaultCallbackByKey as C,
onlyOne = false,
@ -540,10 +571,31 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
return ans;
}
has<C extends BTNCallback<N, BTNKey>>(
identifier: BTNKey,
callback?: C,
beginRoot?: N,
iterationType?: IterationType
): boolean;
has<C extends BTNCallback<N, N>>(
identifier: N | null,
callback?: C,
beginRoot?: N,
iterationType?: IterationType
): boolean;
has<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null,
callback: C,
beginRoot?: N,
iterationType?: IterationType
): boolean;
/**
* The function checks if a binary tree has a node with a given property or key.
* @param {BinaryTreeNodeKey | N} identifier - The `identifier` parameter is the key or value of
* the node that you want to find in the binary tree. It can be either a `BinaryTreeNodeKey` or a
* @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
* the node that you want to find in the binary tree. It can be either a `BTNKey` or a
* generic type `N`.
* @param callback - The `callback` parameter is a function that is used to determine whether a node
* matches the desired criteria. It takes a node as input and returns a boolean value indicating
@ -557,7 +609,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* performed when searching for nodes in the binary tree. It can have one of the following values:
* @returns a boolean value.
*/
has<C extends OneParamCallback<N>>(
has<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null,
callback: C = this._defaultCallbackByKey as C,
beginRoot = this.root,
@ -568,10 +620,31 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
}
get<C extends BTNCallback<N, BTNKey>>(
identifier: BTNKey,
callback?: C,
beginRoot?: N,
iterationType?: IterationType
): N | null;
get<C extends BTNCallback<N, N>>(
identifier: N | null,
callback?: C,
beginRoot?: N,
iterationType?: IterationType
): N | null;
get<C extends BTNCallback<N>>(
identifier: ReturnType<C>,
callback: C,
beginRoot?: N,
iterationType?: IterationType
): N | null;
/**
* The function `get` returns the first node in a binary tree that matches the given property or key.
* @param {BinaryTreeNodeKey | N} identifier - The `identifier` parameter is the key or value of
* the node that you want to find in the binary tree. It can be either a `BinaryTreeNodeKey` or `N`
* @param {BTNKey | N} identifier - The `identifier` parameter is the key or value of
* the node that you want to find in the binary tree. It can be either a `BTNKey` or `N`
* type.
* @param callback - The `callback` parameter is a function that is used to determine whether a node
* matches the desired criteria. It takes a node as input and returns a boolean value indicating
@ -583,7 +656,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* performed when searching for a node in the binary tree. It can have one of the following values:
* @returns either the found node (of type N) or null if no node is found.
*/
get<C extends OneParamCallback<N>>(
get<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null,
callback: C = this._defaultCallbackByKey as C,
beginRoot = this.root,
@ -620,15 +693,15 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
/**
* The function `getLeftMost` returns the leftmost node in a binary tree, either using recursive or
* iterative traversal.
* @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
* @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
* for finding the leftmost node in a binary tree. It can be either a node object (`N`), a key value
* of a node (`BinaryTreeNodeKey`), or `null` if the tree is empty.
* of a node (`BTNKey`), or `null` if the tree is empty.
* @param iterationType - The `iterationType` parameter is used to determine the type of iteration to
* be performed when finding the leftmost node in a binary tree. It can have two possible values:
* @returns The function `getLeftMost` returns the leftmost node (`N`) in a binary tree. If there is
* no leftmost node, it returns `null`.
*/
getLeftMost(beginRoot: BinaryTreeNodeKey | N | null = this.root, iterationType = this.iterationType): N | null {
getLeftMost(beginRoot: BTNKey | N | null = this.root, iterationType = this.iterationType): N | null {
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
if (!beginRoot) return beginRoot;
@ -698,7 +771,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
if (!beginRoot) return true;
if (iterationType === IterationType.RECURSIVE) {
const dfs = (cur: N | null | undefined, min: BinaryTreeNodeKey, max: BinaryTreeNodeKey): boolean => {
const dfs = (cur: N | null | undefined, min: BTNKey, max: BTNKey): boolean => {
if (!cur) return true;
if (cur.key <= min || cur.key >= max) return false;
return dfs(cur.left, min, cur.key) && dfs(cur.right, cur.key, max);
@ -743,21 +816,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* subtree traversal. It takes a single argument, which is the current node being traversed, and
* returns a value. The return values from each callback invocation will be collected and returned as
* an array.
* @param {BinaryTreeNodeKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
* @param {BTNKey | N | null} beginRoot - The `beginRoot` parameter is the starting point
* for traversing the subtree. It can be either a node object, a key value of a node, or `null` to
* start from the root of the tree.
* @param iterationType - The `iterationType` parameter determines the type of traversal to be
* performed on the binary tree. It can have two possible values:
* @returns The function `subTreeTraverse` returns an array of `ReturnType<OneParamCallback<N>>`.
* @returns The function `subTreeTraverse` returns an array of `ReturnType<BTNCallback<N>>`.
*/
subTreeTraverse<C extends OneParamCallback<N>>(
subTreeTraverse<C extends BTNCallback<N>>(
callback: C = this._defaultCallbackByKey as C,
beginRoot: BinaryTreeNodeKey | N | null = this.root,
beginRoot: BTNKey | N | null = this.root,
iterationType = this.iterationType
): ReturnType<C>[] {
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
const ans: ReturnType<OneParamCallback<N>>[] = [];
const ans: ReturnType<BTNCallback<N>>[] = [];
if (!beginRoot) return ans;
if (iterationType === IterationType.RECURSIVE) {
@ -795,16 +868,16 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* is `null`, an empty array will be returned.
* @param {IterationType} iterationType - The `iterationType` parameter determines the type of
* iteration used in the depth-first search algorithm. It can have two possible values:
* @returns The function `dfs` returns an array of `ReturnType<OneParamCallback<N>>` values.
* @returns The function `dfs` returns an array of `ReturnType<BTNCallback<N>>` values.
*/
dfs<C extends OneParamCallback<N>>(
dfs<C extends BTNCallback<N>>(
callback: C = this._defaultCallbackByKey as C,
pattern: DFSOrderPattern = 'in',
beginRoot: N | null = this.root,
iterationType: IterationType = IterationType.ITERATIVE
): ReturnType<C>[] {
if (!beginRoot) return [];
const ans: ReturnType<OneParamCallback<N>>[] = [];
const ans: ReturnType<BTNCallback<N>>[] = [];
if (iterationType === IterationType.RECURSIVE) {
const _traverse = (node: N) => {
switch (pattern) {
@ -831,7 +904,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
_traverse(beginRoot);
} else {
// 0: visit, 1: print
const stack: { opt: 0 | 1; node: N | null | undefined }[] = [{opt: 0, node: beginRoot}];
const stack: {opt: 0 | 1; node: N | null | undefined}[] = [{opt: 0, node: beginRoot}];
while (stack.length > 0) {
const cur = stack.pop();
@ -873,22 +946,22 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* function on each node.
* @param callback - The `callback` parameter is a function that will be called for each node in the
* breadth-first search. It takes a node of type `N` as its argument and returns a value of type
* `ReturnType<OneParamCallback<N>>`. The default value for this parameter is `this._defaultCallbackByKey
* `ReturnType<BTNCallback<N>>`. The default value for this parameter is `this._defaultCallbackByKey
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the breadth-first
* search. It determines from which node the search will begin. If `beginRoot` is `null`, the search
* will not be performed and an empty array will be returned.
* @param iterationType - The `iterationType` parameter determines the type of iteration to be used
* in the breadth-first search (BFS) algorithm. It can have two possible values:
* @returns The function `bfs` returns an array of `ReturnType<OneParamCallback<N>>[]`.
* @returns The function `bfs` returns an array of `ReturnType<BTNCallback<N>>[]`.
*/
bfs<C extends OneParamCallback<N>>(
bfs<C extends BTNCallback<N>>(
callback: C = this._defaultCallbackByKey as C,
beginRoot: N | null = this.root,
iterationType = this.iterationType
): ReturnType<C>[] {
if (!beginRoot) return [];
const ans: ReturnType<OneParamCallback<N>>[] = [];
const ans: ReturnType<BTNCallback<N>>[] = [];
if (iterationType === IterationType.RECURSIVE) {
const queue = new Queue<N>([beginRoot]);
@ -938,7 +1011,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* level in a binary tree. Each inner array contains the return type of the provided callback
* function `C` applied to the nodes at that level.
*/
listLevels<C extends OneParamCallback<N>>(
listLevels<C extends BTNCallback<N>>(
callback: C = this._defaultCallbackByKey as C,
beginRoot: N | null = this.root,
iterationType = this.iterationType
@ -997,7 +1070,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* The `morris` function performs a depth-first traversal of a binary tree using the Morris traversal
* algorithm and returns an array of values obtained by applying a callback function to each node.
* @param callback - The `callback` parameter is a function that will be called on each node in the
* tree. It takes a node of type `N` as input and returns a value of type `ReturnType<OneParamCallback<N>>`. The
* tree. It takes a node of type `N` as input and returns a value of type `ReturnType<BTNCallback<N>>`. The
* default value for this parameter is `this._defaultCallbackByKey`.
* @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function
* determines the order in which the nodes of a binary tree are traversed. It can have one of the
@ -1005,15 +1078,15 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* @param {N | null} beginRoot - The `beginRoot` parameter is the starting node for the Morris
* traversal. It specifies the root node of the tree from which the traversal should begin. If
* `beginRoot` is `null`, an empty array will be returned.
* @returns The `morris` function returns an array of `ReturnType<OneParamCallback<N>>` values.
* @returns The `morris` function returns an array of `ReturnType<BTNCallback<N>>` values.
*/
morris<C extends OneParamCallback<N>>(
morris<C extends BTNCallback<N>>(
callback: C = this._defaultCallbackByKey as C,
pattern: DFSOrderPattern = 'in',
beginRoot: N | null = this.root
): ReturnType<C>[] {
if (beginRoot === null) return [];
const ans: ReturnType<OneParamCallback<N>>[] = [];
const ans: ReturnType<BTNCallback<N>>[] = [];
let cur: N | null | undefined = beginRoot;
const _reverseEdge = (node: N | null | undefined) => {
@ -1101,7 +1174,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* @returns The `*[Symbol.iterator]` method returns a generator object that yields the keys of the
* binary tree nodes in a specific order.
*/
* [Symbol.iterator](node = this.root): Generator<BinaryTreeNodeKey, void, undefined> {
*[Symbol.iterator](node = this.root): Generator<BTNKey, void, undefined> {
if (!node) {
return;
}
@ -1122,7 +1195,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
if (current) current = current.right;
}
} else {
if (node.left) {
yield* this[Symbol.iterator](node.left);
}
@ -1131,10 +1203,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
yield* this[Symbol.iterator](node.right);
}
}
}
/**
* Swap the data of two nodes in the binary tree.
* @param {N} srcNode - The source node to swap.
@ -1163,7 +1233,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* the tree's structure should be restored to its original state to maintain the tree's integrity.
* This is because the purpose of the Morris algorithm is to save space rather than permanently alter the tree's shape.
*/
protected _defaultCallbackByKey: OneParamCallback<N, BinaryTreeNodeKey> = node => node.key;
protected _defaultCallbackByKey: BTNCallback<N, BTNKey> = node => node.key;
/**
* The function `_addTo` adds a new node to a binary tree if there is an available position.

View file

@ -5,21 +5,22 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type {BinaryTreeNodeKey, BSTComparator, BSTNodeNested, BSTOptions, OneParamCallback} from '../../types';
import type {BTNKey, BSTComparator, BSTNodeNested, BSTOptions, BTNCallback} from '../../types';
import {CP, IterationType} from '../../types';
import {BinaryTree, BinaryTreeNode} from './binary-tree';
import {IBinaryTree} from '../../interfaces';
import {Queue} from '../queue';
export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
constructor(key: BinaryTreeNodeKey, val?: V) {
constructor(key: BTNKey, val?: V) {
super(key, val);
}
}
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>>
extends BinaryTree<V, N>
implements IBinaryTree<V, N> {
implements IBinaryTree<V, N>
{
/**
* The constructor function initializes a binary search tree object with an optional comparator
* function.
@ -38,27 +39,27 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
/**
* The function creates a new binary search tree node with the given key and value.
* @param {BinaryTreeNodeKey} key - The key parameter is the key value that will be associated with
* @param {BTNKey} key - The key parameter is the key value that will be associated with
* the new node. It is used to determine the position of the node in the binary search tree.
* @param [val] - The parameter `val` is an optional value that can be assigned to the node. It
* represents the value associated with the node in a binary search tree.
* @returns a new instance of the BSTNode class with the specified key and value.
*/
override createNode(key: BinaryTreeNodeKey, val?: V): N {
override createNode(key: BTNKey, val?: V): N {
return new BSTNode<V, N>(key, val) as N;
}
/**
* The `add` function in a binary search tree class inserts a new node with a given key and value
* into the tree.
* @param {BinaryTreeNodeKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
* `BinaryTreeNodeKey` (which can be a number or a string), a `BSTNode` object, or `null`.
* @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
* `BTNKey` (which can be a number or a string), a `BSTNode` object, or `null`.
* @param [val] - The `val` parameter is the value to be assigned to the new node being added to the
* binary search tree.
* @returns the inserted node (N) if it was successfully added to the binary search tree. If the node
* was not added or if the parameters were invalid, it returns null or undefined.
*/
override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V): N | null | undefined {
override add(keyOrNode: BTNKey | N | null, val?: V): N | null | undefined {
// TODO support node as a parameter
let inserted: N | null = null;
let newNode: N | null = null;
@ -127,9 +128,9 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
/**
* The `addMany` function is used to efficiently add multiple nodes to a binary search tree while
* maintaining balance.
* @param {[BinaryTreeNodeKey | N, N['val']][]} keysOrNodes - The `arr` parameter in the `addMany` function
* @param {[BTNKey | N, N['val']][]} keysOrNodes - The `arr` parameter in the `addMany` function
* represents an array of keys or nodes that need to be added to the binary search tree. It can be an
* array of `BinaryTreeNodeKey` or `N` (which represents the node type in the binary search tree) or
* array of `BTNKey` or `N` (which represents the node type in the binary search tree) or
* `null
* @param {V[]} data - The values of tree nodes
* @param {boolean} isBalanceAdd - If true the nodes will be balance inserted in binary search method.
@ -139,13 +140,13 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
*/
override addMany(
keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[],
keysOrNodes: (BTNKey | null)[] | (N | null)[],
data?: V[],
isBalanceAdd = true,
iterationType = this.iterationType
): (N | null | undefined)[] {
// TODO this addMany function is inefficient, it should be optimized
function hasNoNull(arr: (BinaryTreeNodeKey | null)[] | (N | null)[]): arr is BinaryTreeNodeKey[] | N[] {
function hasNoNull(arr: (BTNKey | null)[] | (N | null)[]): arr is BTNKey[] | N[] {
return arr.indexOf(null) === -1;
}
@ -153,17 +154,15 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
return super.addMany(keysOrNodes, data);
}
const inserted: (N | null | undefined)[] = [];
const combinedArr: [BinaryTreeNodeKey | N, N['val']][] = keysOrNodes.map((value, index) => [value, data?.[index]]);
const combinedArr: [BTNKey | N, N['val']][] = keysOrNodes.map((value, index) => [value, data?.[index]]);
let sorted = [];
function isNodeOrNullTuple(arr: [BinaryTreeNodeKey | N, N['val']][]): arr is [N, N['val']][] {
function isNodeOrNullTuple(arr: [BTNKey | N, N['val']][]): arr is [N, N['val']][] {
for (const [keyOrNode] of arr) if (keyOrNode instanceof BSTNode) return true;
return false;
}
function isBinaryTreeKeyOrNullTuple(
arr: [BinaryTreeNodeKey | N, N['val']][]
): arr is [BinaryTreeNodeKey, N['val']][] {
function isBinaryTreeKeyOrNullTuple(arr: [BTNKey | N, N['val']][]): arr is [BTNKey, N['val']][] {
for (const [keyOrNode] of arr) if (typeof keyOrNode === 'number') return true;
return false;
}
@ -180,7 +179,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
}
sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode);
sortedData = sorted.map(([, val]) => val);
const recursive = (arr: (BinaryTreeNodeKey | null | N)[], data?: (V | undefined)[]) => {
const recursive = (arr: (BTNKey | null | N)[], data?: (V | undefined)[]) => {
if (arr.length === 0) return;
const mid = Math.floor((arr.length - 1) / 2);
@ -220,7 +219,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* callback.
* @param {ReturnType<C> | N} identifier - The `nodeProperty` parameter is used to specify the
* property of the binary tree node that you want to search for. It can be either a specific key
* value (`BinaryTreeNodeKey`) or a custom callback function (`OneParamCallback<N>`) that determines
* value (`BTNKey`) or a custom callback function (`BTNCallback<N>`) that determines
* whether a node matches the desired property.
* @param callback - The `callback` parameter is a function that is used to determine whether a node
* matches the desired property. It takes a node as input and returns a boolean value indicating
@ -233,7 +232,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* @returns either the first node that matches the given nodeProperty and callback, or null if no
* matching node is found.
*/
override get<C extends OneParamCallback<N>>(
override get<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null,
callback: C = this._defaultCallbackByKey as C,
beginRoot = this.root,
@ -257,7 +256,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* the key of the leftmost node if the comparison result is greater than, and the key of the
* rightmost node otherwise. If no node is found, it returns 0.
*/
lastKey(beginRoot: N | null = this.root, iterationType = this.iterationType): BinaryTreeNodeKey {
lastKey(beginRoot: N | null = this.root, iterationType = this.iterationType): BTNKey {
if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
@ -267,7 +266,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* The function `getNodes` retrieves nodes from a binary tree based on a given node property or key,
* using either recursive or iterative traversal.
* @param {ReturnType<C> | N} identifier - The `nodeProperty` parameter represents the property
* of the binary tree node that you want to search for. It can be either a `BinaryTreeNodeKey` or a
* of the binary tree node that you want to search for. It can be either a `BTNKey` or a
* generic type `N`.
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
* value. This value is compared with the `nodeProperty` parameter to determine if the node should be
@ -284,7 +283,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* traverse the binary tree. It can have one of the following values:
* @returns an array of nodes (N[]).
*/
override getNodes<C extends OneParamCallback<N>>(
override getNodes<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null,
callback: C = this._defaultCallbackByKey as C,
onlyOne = false,
@ -350,22 +349,22 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
* traverse nodes that are lesser than, greater than, or equal to the `targetNode`. It can take one
* of the following values:
* @param {BinaryTreeNodeKey | N | null} targetNode - The `targetNode` parameter in the
* @param {BTNKey | N | null} targetNode - The `targetNode` parameter in the
* `lesserOrGreaterTraverse` function is used to specify the node from which the traversal should
* start. It can be either a reference to a specific node (`N`), the key of a node
* (`BinaryTreeNodeKey`), or `null` to
* (`BTNKey`), or `null` to
* @param iterationType - The `iterationType` parameter determines whether the traversal should be
* done recursively or iteratively. It can have two possible values:
* @returns The function `lesserOrGreaterTraverse` returns an array of `ReturnType<OneParamCallback<N>>`.
* @returns The function `lesserOrGreaterTraverse` returns an array of `ReturnType<BTNCallback<N>>`.
*/
lesserOrGreaterTraverse<C extends OneParamCallback<N>>(
lesserOrGreaterTraverse<C extends BTNCallback<N>>(
callback: C = this._defaultCallbackByKey as C,
lesserOrGreater: CP = CP.lt,
targetNode: BinaryTreeNodeKey | N | null = this.root,
targetNode: BTNKey | N | null = this.root,
iterationType = this.iterationType
): ReturnType<C>[] {
if (typeof targetNode === 'number') targetNode = this.get(targetNode);
const ans: ReturnType<OneParamCallback<N>>[] = [];
const ans: ReturnType<BTNCallback<N>>[] = [];
if (!targetNode) return ans;
const targetKey = targetNode.key;
if (!this.root) return ans;
@ -508,12 +507,12 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
/**
* The function compares two values using a comparator function and returns whether the first value
* is greater than, less than, or equal to the second value.
* @param {BinaryTreeNodeKey} a - The parameter "a" is of type BinaryTreeNodeKey.
* @param {BinaryTreeNodeKey} b - The parameter "b" in the above code represents a BinaryTreeNodeKey.
* @param {BTNKey} a - The parameter "a" is of type BTNKey.
* @param {BTNKey} b - The parameter "b" in the above code represents a BTNKey.
* @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater
* than), CP.lt (less than), or CP.eq (equal).
*/
protected _compare(a: BinaryTreeNodeKey, b: BinaryTreeNodeKey): CP {
protected _compare(a: BTNKey, b: BTNKey): CP {
const compared = this._comparator(a, b);
if (compared > 0) return CP.gt;
else if (compared < 0) return CP.lt;

View file

@ -1,9 +1,9 @@
import {BinaryTreeNodeKey, RBColor, RBTreeNodeNested, RBTreeOptions} from '../../types';
import {BTNKey, RBColor, RBTreeNodeNested, RBTreeOptions} from '../../types';
import {IBinaryTree} from '../../interfaces';
import {BST, BSTNode} from './bst';
export class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V>> extends BSTNode<V, N> {
constructor(key: BinaryTreeNodeKey, val?: V) {
constructor(key: BTNKey, val?: V) {
super(key, val);
this._color = RBColor.RED;
}
@ -21,16 +21,17 @@ export class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V
export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNested<V>>>
extends BST<V, N>
implements IBinaryTree<V, N> {
implements IBinaryTree<V, N>
{
constructor(options?: RBTreeOptions) {
super(options);
}
override createNode(key: BinaryTreeNodeKey, val?: V): N {
override createNode(key: BTNKey, val?: V): N {
return new RBTreeNode(key, val) as N;
}
// override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V): N | null | undefined {
// override add(keyOrNode: BTNKey | N | null, val?: V): N | null | undefined {
// const inserted = super.add(keyOrNode, val);
// if (inserted) this._fixInsertViolation(inserted);
// return inserted;
@ -204,7 +205,7 @@ export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNest
// node.right = null;
// }
//
// override delete(keyOrNode: BinaryTreeNodeKey | N): BinaryTreeDeletedResult<N>[] {
// override delete(keyOrNode: BTNKey | N): BinaryTreeDeletedResult<N>[] {
// const node = this.get(keyOrNode);
// const result: BinaryTreeDeletedResult<N>[] = [{deleted: undefined, needBalanced: null}];
// if (!node) return result; // Node does not exist

View file

@ -5,8 +5,8 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type {BinaryTreeNodeKey, TreeMultisetNodeNested, TreeMultisetOptions} from '../../types';
import {BinaryTreeDeletedResult, CP, FamilyPosition, IterationType, OneParamCallback} from '../../types';
import type {BTNKey, TreeMultisetNodeNested, TreeMultisetOptions} from '../../types';
import {BinaryTreeDeletedResult, CP, FamilyPosition, IterationType, BTNCallback} from '../../types';
import {IBinaryTree} from '../../interfaces';
import {AVLTree, AVLTreeNode} from './avl-tree';
@ -18,7 +18,7 @@ export class TreeMultisetNode<
/**
* The constructor function initializes a BinaryTreeNode object with a key, value, and count.
* @param {BinaryTreeNodeKey} key - The `key` parameter is of type `BinaryTreeNodeKey` and represents the unique identifier
* @param {BTNKey} key - The `key` parameter is of type `BTNKey` and represents the unique identifier
* of the binary tree node.
* @param {V} [val] - The `val` parameter is an optional parameter of type `V`. It represents the value of the binary
* tree node. If no value is provided, it will be `undefined`.
@ -26,7 +26,7 @@ export class TreeMultisetNode<
* occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`
* parameter when creating a new instance of the `BinaryTreeNode` class.
*/
constructor(key: BinaryTreeNodeKey, val?: V, count = 1) {
constructor(key: BTNKey, val?: V, count = 1) {
super(key, val);
this.count = count;
}
@ -37,7 +37,8 @@ export class TreeMultisetNode<
*/
export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultisetNode<V, TreeMultisetNodeNested<V>>>
extends AVLTree<V, N>
implements IBinaryTree<V, N> {
implements IBinaryTree<V, N>
{
/**
* The constructor function for a TreeMultiset class in TypeScript, which extends another class and sets an option to
* merge duplicated values.
@ -56,22 +57,22 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
/**
* The function creates a new BSTNode with the given key, value, and count.
* @param {BinaryTreeNodeKey} key - The key parameter is the unique identifier for the binary tree node. It is used to
* @param {BTNKey} key - The key parameter is the unique identifier for the binary tree node. It is used to
* distinguish one node from another in the tree.
* @param {N} val - The `val` parameter represents the value that will be stored in the binary search tree node.
* @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 search tree node. If not provided, the count will default to 1.
* @returns A new instance of the BSTNode class with the specified key, value, and count (if provided).
*/
override createNode(key: BinaryTreeNodeKey, val?: V, count?: number): N {
override createNode(key: BTNKey, val?: V, count?: number): N {
return new TreeMultisetNode(key, val, count) as N;
}
/**
* The `add` function adds a new node to a binary search tree, updating the count if the key already
* exists, and balancing the tree if necessary.
* @param {BinaryTreeNodeKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
* `BinaryTreeNodeKey` (which represents the key of the node to be added), a `N` (which represents a
* @param {BTNKey | N | null} keyOrNode - The `keyOrNode` parameter can be either a
* `BTNKey` (which represents the key of the node to be added), a `N` (which represents a
* node to be added), or `null` (which represents a null node).
* @param [val] - The `val` parameter represents the value associated with the key that is being
* added to the binary tree.
@ -80,7 +81,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
* count is specified, the default count will be 1.
* @returns The function `add` returns a value of type `N | null | undefined`.
*/
override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: V, count = 1): N | null | undefined {
override add(keyOrNode: BTNKey | N | null, val?: V, count = 1): N | null | undefined {
let inserted: N | null | undefined = undefined,
newNode: N | null;
if (keyOrNode instanceof TreeMultisetNode) {
@ -184,14 +185,14 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
/**
* The `addMany` function adds multiple keys or nodes to a TreeMultiset and returns an array of the
* inserted nodes.
* @param {(BinaryTreeNodeKey | null)[] | (N | null)[]} keysOrNodes - An array of keys or nodes to be
* added to the multiset. Each element can be either a BinaryTreeNodeKey or a TreeMultisetNode.
* @param {(BTNKey | null)[] | (N | null)[]} keysOrNodes - An array of keys or nodes to be
* added to the multiset. Each element can be either a BTNKey or a TreeMultisetNode.
* @param {V[]} [data] - The `data` parameter is an optional array of values that correspond
* to the keys or nodes being added to the multiset. It is used to associate additional data with
* each key or node.
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
override addMany(keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[], data?: V[]): (N | null | undefined)[] {
override addMany(keysOrNodes: (BTNKey | null)[] | (N | null)[], data?: V[]): (N | null | undefined)[] {
const inserted: (N | null | undefined)[] = [];
for (let i = 0; i < keysOrNodes.length; i++) {
@ -262,7 +263,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
* The `delete` function in a binary search tree deletes a node from the tree and returns the deleted
* node along with the parent node that needs to be balanced.
* @param {ReturnType<C>} identifier - The `identifier` parameter is either a
* `BinaryTreeNodeKey` or a generic type `N`. It represents the property of the node that we are
* `BTNKey` or a generic type `N`. It represents the property of the node that we are
* searching for. It can be a specific key value or any other property of the node.
* @param callback - The `callback` parameter is a function that takes a node as input and returns a
* value. This value is compared with the `identifier` parameter to determine if the node should be
@ -274,7 +275,7 @@ export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultis
* decremented by 1 and
* @returns The method `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
*/
override delete<C extends OneParamCallback<N>>(
override delete<C extends BTNCallback<N>>(
identifier: ReturnType<C>,
callback: C = this._defaultCallbackByKey as C,
ignoreCount = false

View file

@ -105,7 +105,8 @@ export abstract class AbstractEdge<V = any> {
export abstract class AbstractGraph<
V extends AbstractVertex<any> = AbstractVertex<any>,
E extends AbstractEdge<any> = AbstractEdge<any>
> implements IGraph<V, E> {
> implements IGraph<V, E>
{
private _vertices: Map<VertexKey, V> = new Map<VertexKey, V>();
get vertices(): Map<VertexKey, V> {
@ -553,14 +554,14 @@ export abstract class AbstractGraph<
}
getMinDist &&
distMap.forEach((d, v) => {
if (v !== srcVertex) {
if (d < minDist) {
minDist = d;
if (genPaths) minDest = v;
distMap.forEach((d, v) => {
if (v !== srcVertex) {
if (d < minDist) {
minDist = d;
if (genPaths) minDest = v;
}
}
}
});
});
genPaths && getPaths(minDest);
@ -622,7 +623,7 @@ export abstract class AbstractGraph<
if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);
}
const heap = new PriorityQueue<{ key: number; val: V }>({comparator: (a, b) => a.key - b.key});
const heap = new PriorityQueue<{key: number; val: V}>({comparator: (a, b) => a.key - b.key});
heap.add({key: 0, val: srcVertex});
distMap.set(srcVertex, 0);
@ -851,7 +852,7 @@ export abstract class AbstractGraph<
* `predecessor` property is a 2D array of vertices (or `null`) representing the predecessor vertices in the shortest
* path between vertices in the
*/
floyd(): { costs: number[][]; predecessor: (V | null)[][] } {
floyd(): {costs: number[][]; predecessor: (V | null)[][]} {
const idAndVertices = [...this._vertices];
const n = idAndVertices.length;

View file

@ -64,7 +64,8 @@ export class DirectedEdge<V = any> extends AbstractEdge<V> {
export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E extends DirectedEdge<any> = DirectedEdge>
extends AbstractGraph<V, E>
implements IGraph<V, E> {
implements IGraph<V, E>
{
/**
* The constructor function initializes an instance of a class.
*/

View file

@ -51,11 +51,12 @@ export class UndirectedEdge<V = number> extends AbstractEdge<V> {
}
export class UndirectedGraph<
V extends UndirectedVertex<any> = UndirectedVertex,
E extends UndirectedEdge<any> = UndirectedEdge
>
V extends UndirectedVertex<any> = UndirectedVertex,
E extends UndirectedEdge<any> = UndirectedEdge
>
extends AbstractGraph<V, E>
implements IGraph<V, E> {
implements IGraph<V, E>
{
/**
* The constructor initializes a new Map object to store edges.
*/

View file

@ -157,7 +157,7 @@ export class HashMap<K, V> {
}
}
* entries(): IterableIterator<[K, V]> {
*entries(): IterableIterator<[K, V]> {
for (const bucket of this.table) {
if (bucket) {
for (const [key, value] of bucket) {

View file

@ -1,2 +1 @@
export class TreeMap {
}
export class TreeMap {}

View file

@ -1,2 +1 @@
export class TreeSet {
}
export class TreeSet {}

View file

@ -11,7 +11,7 @@ export class Heap<E = any> {
protected nodes: E[] = [];
protected readonly comparator: Comparator<E>;
constructor(options: { comparator: Comparator<E>; nodes?: E[] }) {
constructor(options: {comparator: Comparator<E>; nodes?: E[]}) {
this.comparator = options.comparator;
if (options.nodes && options.nodes.length > 0) {
this.nodes = options.nodes;
@ -39,7 +39,7 @@ export class Heap<E = any> {
* @returns A new Heap instance.
* @param options
*/
static heapify<E>(options: { nodes: E[]; comparator: Comparator<E> }): Heap<E> {
static heapify<E>(options: {nodes: E[]; comparator: Comparator<E>}): Heap<E> {
return new Heap<E>(options);
}

View file

@ -11,7 +11,7 @@ import type {Comparator} from '../../types';
export class MaxHeap<E = any> extends Heap<E> {
constructor(
options: { comparator: Comparator<E>; nodes?: E[] } = {
options: {comparator: Comparator<E>; nodes?: E[]} = {
comparator: (a: E, b: E) => {
if (!(typeof a === 'number' && typeof b === 'number')) {
throw new Error('The a, b params of compare function must be number');

View file

@ -11,7 +11,7 @@ import type {Comparator} from '../../types';
export class MinHeap<E = any> extends Heap<E> {
constructor(
options: { comparator: Comparator<E>; nodes?: E[] } = {
options: {comparator: Comparator<E>; nodes?: E[]} = {
comparator: (a: E, b: E) => {
if (!(typeof a === 'number' && typeof b === 'number')) {
throw new Error('The a, b params of compare function must be number');

View file

@ -628,7 +628,7 @@ export class DoublyLinkedList<E = any> {
/**
* The function returns an iterator that iterates over the values of a linked list.
*/
* [Symbol.iterator]() {
*[Symbol.iterator]() {
let current = this.head;
while (current) {

View file

@ -590,7 +590,7 @@ export class SinglyLinkedList<E = any> {
/**
* The function returns an iterator that iterates over the values of a linked list.
*/
* [Symbol.iterator]() {
*[Symbol.iterator]() {
let current = this.head;
while (current) {

View file

@ -14,7 +14,7 @@ export class MatrixNTI2D<V = any> {
* given initial value or 0 if not provided.
* @param options - An object containing the following properties:
*/
constructor(options: { row: number; col: number; initialVal?: V }) {
constructor(options: {row: number; col: number; initialVal?: V}) {
const {row, col, initialVal} = options;
this._matrix = new Array(row).fill(undefined).map(() => new Array(col).fill(initialVal || 0));
}

View file

@ -10,8 +10,7 @@ export class Vector2D {
public x: number = 0,
public y: number = 0,
public w: number = 1 // needed for matrix multiplication
) {
}
) {}
/**
* The function checks if the x and y values of a point are both zero.

View file

@ -10,7 +10,7 @@ import type {Comparator} from '../../types';
export class MaxPriorityQueue<E = any> extends PriorityQueue<E> {
constructor(
options: { comparator: Comparator<E>; nodes?: E[] } = {
options: {comparator: Comparator<E>; nodes?: E[]} = {
comparator: (a: E, b: E) => {
if (!(typeof a === 'number' && typeof b === 'number')) {
throw new Error('The a, b params of compare function must be number');

View file

@ -10,7 +10,7 @@ import type {Comparator} from '../../types';
export class MinPriorityQueue<E = any> extends PriorityQueue<E> {
constructor(
options: { comparator: Comparator<E>; nodes?: E[] } = {
options: {comparator: Comparator<E>; nodes?: E[]} = {
comparator: (a: E, b: E) => {
if (!(typeof a === 'number' && typeof b === 'number')) {
throw new Error('The a, b params of compare function must be number');

View file

@ -10,7 +10,7 @@ import {Heap} from '../heap';
import {Comparator} from '../../types';
export class PriorityQueue<E = any> extends Heap<E> {
constructor(options: { comparator: Comparator<E>; nodes?: E[] }) {
constructor(options: {comparator: Comparator<E>; nodes?: E[]}) {
super(options);
}
}

View file

@ -9,8 +9,7 @@ import {DoublyLinkedList} from '../linked-list';
// O(n) time complexity of obtaining the value
// O(1) time complexity of adding at the beginning and the end
export class Deque<E = any> extends DoublyLinkedList<E> {
}
export class Deque<E = any> extends DoublyLinkedList<E> {}
// O(1) time complexity of obtaining the value
// O(n) time complexity of adding at the beginning and the end
@ -20,9 +19,9 @@ export class ObjectDeque<E = number> {
if (capacity !== undefined) this._capacity = capacity;
}
private _nodes: { [key: number]: E } = {};
private _nodes: {[key: number]: E} = {};
get nodes(): { [p: number]: E } {
get nodes(): {[p: number]: E} {
return this._nodes;
}
@ -157,7 +156,7 @@ export class ObjectDeque<E = number> {
return this._size <= 0;
}
protected _seNodes(value: { [p: number]: E }) {
protected _seNodes(value: {[p: number]: E}) {
this._nodes = value;
}

View file

@ -183,7 +183,7 @@ export class Queue<E = any> {
return new Queue(this.nodes.slice(this.offset));
}
* [Symbol.iterator]() {
*[Symbol.iterator]() {
for (const item of this.nodes) {
yield item;
}

View file

@ -1,10 +1,10 @@
import {BinaryTreeNode} from '../data-structures';
import {BinaryTreeDeletedResult, BinaryTreeNodeKey, BinaryTreeNodeNested, OneParamCallback} from '../types';
import {BinaryTreeDeletedResult, BTNKey, BinaryTreeNodeNested, BTNCallback} from '../types';
export interface IBinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNodeNested<V>> {
createNode(key: BinaryTreeNodeKey, val?: N['val']): N;
createNode(key: BTNKey, val?: N['val']): N;
add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined;
add(keyOrNode: BTNKey | N | null, val?: N['val']): N | null | undefined;
delete<C extends OneParamCallback<N>>(identifier: ReturnType<C> | null, callback: C): BinaryTreeDeletedResult<N>[];
delete<C extends BTNCallback<N>>(identifier: ReturnType<C> | null, callback: C): BinaryTreeDeletedResult<N>[];
}

View file

@ -22,7 +22,7 @@ export enum FamilyPosition {
MAL_NODE = 'MAL_NODE'
}
export type BinaryTreeNodeKey = number;
export type BTNKey = number;
export type BinaryTreeDeletedResult<N> = { deleted: N | null | undefined; needBalanced: N | null };

View file

@ -1,7 +1,7 @@
import {BSTNode} from '../../../data-structures';
import type {BinaryTreeNodeKey, BinaryTreeOptions} from './binary-tree';
import type {BTNKey, BinaryTreeOptions} from './binary-tree';
export type BSTComparator = (a: BinaryTreeNodeKey, b: BinaryTreeNodeKey) => number;
export type BSTComparator = (a: BTNKey, b: BTNKey) => number;
// prettier-ignore
export type BSTNodeNested<T> = BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, BSTNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

View file

@ -1,6 +1,6 @@
export type Direction = 'up' | 'right' | 'down' | 'left';
export type Turning = { [key in Direction]: Direction };
export type Turning = {[key in Direction]: Direction};
export type NavigatorParams<T = any> = {
matrix: T[][];

View file

@ -2,7 +2,7 @@ export type Comparator<T> = (a: T, b: T) => number;
export type DFSOrderPattern = 'pre' | 'in' | 'post';
export type OneParamCallback<N, D = any> = (node: N) => D;
export type BTNCallback<N, D = any> = (node: N) => D;
export enum CP {
lt = 'lt',

View file

@ -1,5 +1,5 @@
export type ToThunkFn = () => ReturnType<TrlFn>;
export type Thunk = () => ReturnType<ToThunkFn> & { __THUNK__: symbol };
export type Thunk = () => ReturnType<ToThunkFn> & {__THUNK__: symbol};
export type TrlFn = (...args: any[]) => any;
export type TrlAsyncFn = (...args: any[]) => any;

View file

@ -1,6 +1,6 @@
export type KeyValueObject = { [key: string]: any };
export type KeyValueObject = {[key: string]: any};
export type KeyValueObjectWithKey = { [key: string]: any; key: string | number | symbol };
export type KeyValueObjectWithKey = {[key: string]: any; key: string | number | symbol};
export type NonNumberNonObjectButDefined = string | boolean | symbol | null;

View file

@ -183,7 +183,7 @@ describe('Individual package BST operations test', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<{ key: number; keyA: number }>();
const objBST = new BST<{key: number; keyA: number}>();
expect(objBST).toBeInstanceOf(BST);
objBST.add(11, {key: 11, keyA: 11});
objBST.add(3, {key: 3, keyA: 3});

View file

@ -219,7 +219,7 @@ describe('AVL Tree Test recursively', () => {
});
describe('AVLTree APIs test', () => {
const avl = new AVLTree<{ id: number; text: string }>();
const avl = new AVLTree<{id: number; text: string}>();
beforeEach(() => {
avl.clear();
});

View file

@ -71,10 +71,10 @@ describe('BinaryTreeNode', () => {
});
describe('BinaryTree', () => {
let tree: BinaryTree;
let tree: BinaryTree<number>;
beforeEach(() => {
tree = new BinaryTree();
tree = new BinaryTree<number>();
});
afterEach(() => {
@ -99,16 +99,18 @@ describe('BinaryTree', () => {
});
it('should add and find nodes', () => {
tree.add(1);
tree.add(2);
tree.add(3);
tree.add(1, 1);
tree.add(2, 2);
tree.add(3, 3);
expect(tree.has(1)).toBe(true);
expect(tree.has(2)).toBe(true);
expect(tree.has(3)).toBe(true);
expect(tree.has(4)).toBe(false);
const node4 = tree.get(4);
expect(tree.has(node4)).toBe(false);
expect(tree.has(node4, node => node)).toBe(false);
expect(tree.has('3', node => node.val?.toString())).toBe(true);
});
it('should getDepth return correct depth', () => {
@ -241,7 +243,7 @@ describe('BinaryTree Morris Traversal', () => {
});
describe('BinaryTree APIs test', () => {
const avl = new AVLTree<{ id: number; text: string }>();
const avl = new AVLTree<{id: number; text: string}>();
beforeEach(() => {
avl.clear();
});
@ -265,10 +267,14 @@ describe('BinaryTree traversals', () => {
const arr = [35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55];
tree.refill(arr);
expect(tree.dfs(node => node.key, 'pre')).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([
35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55
]);
expect(tree.dfs(node => node.key, 'in')).toEqual([15, 16, 20, 28, 29, 30, 35, 40, 45, 50, 55]);
expect(tree.dfs(node => node.key, 'post')).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
expect(tree.dfs(node => node.key, 'post', tree.root, IterationType.RECURSIVE)).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
expect(tree.dfs(node => node.key, 'post', tree.root, IterationType.RECURSIVE)).toEqual([
16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35
]);
expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
]);

View file

@ -189,7 +189,7 @@ describe('BST operations test', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<{ key: number; keyA: number }>();
const objBST = new BST<{key: number; keyA: number}>();
expect(objBST).toBeInstanceOf(BST);
objBST.add(11, {key: 11, keyA: 11});
objBST.add(3, {key: 3, keyA: 3});
@ -260,7 +260,7 @@ describe('BST operations test', () => {
objBST.perfectlyBalance();
expect(objBST.isPerfectlyBalanced()).toBe(true);
const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
objBST.bfs(node => bfsNodesAfterBalanced.push(node));
expect(bfsNodesAfterBalanced[0].key).toBe(8);
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
@ -385,7 +385,7 @@ describe('BST operations test', () => {
expect(bfsIDs[1]).toBe(12);
expect(bfsIDs[2]).toBe(16);
const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
objBST.bfs(node => bfsNodes.push(node));
expect(bfsNodes[0].key).toBe(2);
expect(bfsNodes[1].key).toBe(12);
@ -579,7 +579,7 @@ describe('BST operations test recursively', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<{ key: number; keyA: number }>();
const objBST = new BST<{key: number; keyA: number}>();
expect(objBST).toBeInstanceOf(BST);
objBST.add(11, {key: 11, keyA: 11});
objBST.add(3, {key: 3, keyA: 3});
@ -650,7 +650,7 @@ describe('BST operations test recursively', () => {
objBST.perfectlyBalance();
expect(objBST.isPerfectlyBalanced()).toBe(true);
const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
objBST.bfs(node => bfsNodesAfterBalanced.push(node));
expect(bfsNodesAfterBalanced[0].key).toBe(8);
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
@ -775,7 +775,7 @@ describe('BST operations test recursively', () => {
expect(bfsIDs[1]).toBe(12);
expect(bfsIDs[2]).toBe(16);
const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
objBST.bfs(node => bfsNodes.push(node));
expect(bfsNodes[0].key).toBe(2);
expect(bfsNodes[1].key).toBe(12);

View file

@ -29,7 +29,7 @@ describe('Overall BinaryTree Test', () => {
bfsIDs[0] === 11; // true
expect(bfsIDs[0]).toBe(11);
const objBST = new BST<{ key: number; keyA: number }>();
const objBST = new BST<{key: number; keyA: number}>();
objBST.add(11, {key: 11, keyA: 11});
objBST.add(3, {key: 3, keyA: 3});

View file

@ -207,7 +207,7 @@ describe('TreeMultiset operations test', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objTreeMultiset = new TreeMultiset<{ key: number; keyA: number }>();
const objTreeMultiset = new TreeMultiset<{key: number; keyA: number}>();
expect(objTreeMultiset).toBeInstanceOf(TreeMultiset);
objTreeMultiset.add(11, {key: 11, keyA: 11});
objTreeMultiset.add(3, {key: 3, keyA: 3});
@ -447,7 +447,7 @@ describe('TreeMultiset operations test recursively', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objTreeMultiset = new TreeMultiset<{ key: number; keyA: number }>();
const objTreeMultiset = new TreeMultiset<{key: number; keyA: number}>();
expect(objTreeMultiset).toBeInstanceOf(TreeMultiset);
objTreeMultiset.add(11, {key: 11, keyA: 11});
objTreeMultiset.add(3, {key: 3, keyA: 3});

View file

@ -57,7 +57,7 @@ describe('CoordinateMap', () => {
class MyCoordinateMap<V = any> extends CoordinateMap<V> {
constructor(joint?: string) {
super(joint);
this._setJoint(joint += '-')
this._setJoint((joint += '-'));
}
}
@ -67,7 +67,7 @@ describe('CoordinateMap', () => {
cMap.set([0, 0], 0);
cMap.set([0, 1], 1);
cMap.set([1, 1], 11);
})
});
it('should joint to be *-', () => {
expect(cMap.joint).toBe('*-');
});

View file

@ -44,7 +44,7 @@ describe('MyCoordinateSet', () => {
class MyCoordinateSet extends CoordinateSet {
constructor(joint?: string) {
super(joint);
this._setJoint(joint += '-')
this._setJoint((joint += '-'));
}
}
@ -54,7 +54,7 @@ describe('MyCoordinateSet', () => {
mySet.add([0, 0]);
mySet.add([0, 1]);
mySet.add([1, 1]);
})
});
it('should joint to be *-', () => {
expect(mySet.joint).toBe('*-');
});

View file

@ -22,7 +22,7 @@ describe('Heap Operation Test', () => {
});
it('should object heap work well', function () {
const minHeap = new MinHeap<{ a: string; key: number }>({comparator: (a, b) => a.key - b.key});
const minHeap = new MinHeap<{a: string; key: number}>({comparator: (a, b) => a.key - b.key});
minHeap.add({key: 1, a: 'a1'});
minHeap.add({key: 6, a: 'a6'});
minHeap.add({key: 2, a: 'a2'});
@ -37,7 +37,7 @@ describe('Heap Operation Test', () => {
i++;
}
const maxHeap = new MaxHeap<{ key: number; a: string }>({comparator: (a, b) => b.key - a.key});
const maxHeap = new MaxHeap<{key: number; a: string}>({comparator: (a, b) => b.key - a.key});
maxHeap.add({key: 1, a: 'a1'});
maxHeap.add({key: 6, a: 'a6'});
maxHeap.add({key: 5, a: 'a5'});

View file

@ -7,7 +7,7 @@ describe('DoublyLinkedListNode', () => {
expect(node1.val).toBe(2);
node1.val = 1;
expect(node1.val).toBe(1);
})
});
});
describe('DoublyLinkedList Operation Test', () => {
@ -38,10 +38,8 @@ describe('DoublyLinkedList Operation Test', () => {
expect(list.tail?.val).toBe(4);
});
it('should find null', () => {
expect(list.find(val => val === 6)).toBe(null);
});
it('should indexOf -1', () => {
@ -60,13 +58,11 @@ describe('DoublyLinkedList Operation Test', () => {
// @ts-ignore
expect([...list]).toEqual([1, 2, 3, 4, 5]);
});
});
describe('DoublyLinkedList Operation Test', () => {
let list: DoublyLinkedList<number>;
let objectList: DoublyLinkedList<{ keyA: number }>;
let objectList: DoublyLinkedList<{keyA: number}>;
beforeEach(() => {
list = new DoublyLinkedList();

View file

@ -7,15 +7,15 @@ describe('SinglyLinkedListNode', () => {
expect(node1.val).toBe(2);
node1.val = 1;
expect(node1.val).toBe(1);
})
});
});
describe('SinglyLinkedList Operation Test', () => {
let list: SinglyLinkedList<number>;
let objectList: SinglyLinkedList<{ keyA: number }>;
let objectList: SinglyLinkedList<{keyA: number}>;
beforeEach(() => {
list = new SinglyLinkedList<number>();
objectList = new SinglyLinkedList<{ keyA: number }>();
objectList = new SinglyLinkedList<{keyA: number}>();
});
describe('push', () => {
@ -446,7 +446,6 @@ describe('SinglyLinkedList', () => {
expect(list.length).toBe(1);
});
it('should reverse the list', () => {
list.push(1);
list.push(2);
@ -457,7 +456,6 @@ describe('SinglyLinkedList', () => {
// Add more assertions for reversed order.
});
it('should convert the list to an array', () => {
list.push(1);
list.push(2);
@ -475,13 +473,12 @@ describe('SinglyLinkedList', () => {
expect(list.filter(val => val !== 2).toArray()).toEqual([1, 3]);
});
it('should forEach the list', () => {
list.push(1);
list.push(2);
list.push(3);
list.forEach(val => val++);
expect(list.toArray()).toEqual([1, 2, 3])
expect(list.toArray()).toEqual([1, 2, 3]);
});
it('should map the list', () => {

View file

@ -17,7 +17,7 @@ describe('MaxPriorityQueue Operation Test', () => {
});
it('should add elements and maintain heap property in a object MaxPriorityQueue', () => {
const priorityQueue = new MaxPriorityQueue<{ keyA: number }>({comparator: (a, b) => b.keyA - a.keyA});
const priorityQueue = new MaxPriorityQueue<{keyA: number}>({comparator: (a, b) => b.keyA - a.keyA});
priorityQueue.refill([{keyA: 5}, {keyA: 3}, {keyA: 1}]);
priorityQueue.add({keyA: 7});
@ -64,7 +64,7 @@ describe('MaxPriorityQueue Operation Test', () => {
it('should correctly heapify an object array', () => {
const nodes = [{keyA: 5}, {keyA: 3}, {keyA: 7}, {keyA: 1}];
const maxPQ = MaxPriorityQueue.heapify<{ keyA: number }>({nodes: nodes, comparator: (a, b) => b.keyA - a.keyA});
const maxPQ = MaxPriorityQueue.heapify<{keyA: number}>({nodes: nodes, comparator: (a, b) => b.keyA - a.keyA});
expect(maxPQ.poll()?.keyA).toBe(7);
expect(maxPQ.poll()?.keyA).toBe(5);

View file

@ -26,7 +26,7 @@ export const bigO = {
function findPotentialN(input: any): number {
let longestArray: any[] = [];
let mostProperties: { [key: string]: any } = {};
let mostProperties: {[key: string]: any} = {};
function recurse(obj: any) {
if (Array.isArray(obj)) {