[project] github workflow added. eslint added. formating code by using prettier.

This commit is contained in:
Revone 2023-09-21 12:52:17 +08:00
parent 95b44f439b
commit b263262a46
83 changed files with 804 additions and 688 deletions

65
.eslintrc.js Normal file
View file

@ -0,0 +1,65 @@
module.exports = {
'extends': [
'plugin:@typescript-eslint/recommended',
'prettier'
],
'rules': {
'react/display-name': 'off',
'@next/next/no-img-element': 'off',
'react/no-unescaped-entities': 'off',
'import/no-anonymous-default-export': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
// add new line above comment
'lines-around-comment': [
'error',
{
'beforeLineComment': false,
'beforeBlockComment': true,
'allowBlockStart': true,
'allowClassStart': true,
'allowObjectStart': true,
'allowArrayStart': true
}
],
// add new line above return
'newline-before-return': 'off',
// add new line below import
'import/newline-after-import': [
'error',
{
'count': 1
}
],
'@typescript-eslint/ban-types': [
'error',
{
'extendDefaults': true,
'types': {
'{}': false
}
}
]
},
'plugins': [
'import'
],
'settings': {
'import/parsers': {
'@typescript-eslint/parser': [
'.ts',
'.tsx'
]
},
'import/resolver': {
'typescript': {
'alwaysTryTypes': true,
'project': [
'./tsconfig.json'
]
}
}
}
}

View file

@ -1,65 +0,0 @@
{
"extends": [
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"react/display-name": "off",
"@next/next/no-img-element": "off",
"react/no-unescaped-entities": "off",
"import/no-anonymous-default-export": "off",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
// add new line above comment
"lines-around-comment": [
"error",
{
"beforeLineComment": false,
"beforeBlockComment": true,
"allowBlockStart": true,
"allowClassStart": true,
"allowObjectStart": true,
"allowArrayStart": true
}
],
// add new line above return
"newline-before-return": "off",
// add new line below import
"import/newline-after-import": [
"error",
{
"count": 1
}
],
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true,
"types": {
"{}": false
}
}
]
},
"plugins": [
"import"
],
"settings": {
"import/parsers": {
"@typescript-eslint/parser": [
".ts",
".tsx"
]
},
"import/resolver": {
"typescript": {
"alwaysTryTypes": true,
"project": [
"./tsconfig.json"
]
}
}
}
}

28
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,28 @@
name: CI
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 19
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Run tests
run: npm test

6
.prettierignore Normal file
View file

@ -0,0 +1,6 @@
src/types/data-structures/abstract-binary-tree.ts
src/types/data-structures/binary-tree.ts
src/types/data-structures/bst.ts
src/types/data-structures/avl-tree.ts
src/types/data-structures/tree-multiset.ts
src/types/data-structures/rb-tree.ts

16
.prettierrc.js Normal file
View file

@ -0,0 +1,16 @@
module.exports = {
arrowParens: 'avoid',
bracketSpacing: true,
htmlWhitespaceSensitivity: 'css',
insertPragma: false,
bracketSameLine: false,
jsxSingleQuote: true,
printWidth: 120,
proseWrap: 'preserve',
quoteProps: 'as-needed',
requirePragma: false,
singleQuote: true,
tabWidth: 2,
trailingComma: 'none',
useTabs: false
}

View file

@ -2,9 +2,9 @@
"name": "data-structure-typed",
"version": "1.3.6",
"description": "Data Structures of Javascript & TypeScript. AVLTree, Binary Search Tree, Binary Tree, Tree Multiset, Graph, Heap, Priority Queue, Linked List.",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"main": "lib/index.js",
"module": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
"build": "rm -rf dist && npx tsc && npm run build:browser",
"build:browser": "webpack",
@ -146,11 +146,6 @@
"deque-typed": "^1.3.3",
"directed-graph-typed": "^1.3.3",
"doubly-linked-list-typed": "^1.3.3",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.4",
"graph-typed": "^1.3.3",
"heap-typed": "^1.3.3",
"jest": "^29.6.2",
@ -159,6 +154,11 @@
"max-priority-queue-typed": "^1.3.3",
"min-heap-typed": "^1.3.3",
"min-priority-queue-typed": "^1.3.3",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.4",
"prettier": "^3.0.3",
"priority-queue-typed": "^1.3.3",
"queue-typed": "^1.3.3",

View file

@ -1,3 +1 @@
export class AaTree {
}
export class AaTree {}

View file

@ -6,7 +6,7 @@
* @license MIT License
*/
import {trampoline} from '../../utils';
import { trampoline } from '../../utils';
import type {
AbstractBinaryTreeNodeNested,
AbstractBinaryTreeNodeProperties,
@ -17,11 +17,14 @@ import type {
DFSOrderPattern,
NodeOrPropertyName
} from '../../types';
import {AbstractBinaryTreeOptions, FamilyPosition, LoopType} from '../../types';
import {IAbstractBinaryTree, IAbstractBinaryTreeNode} from '../../interfaces';
export abstract class AbstractBinaryTreeNode<T = any, NEIGHBOR extends AbstractBinaryTreeNode<T, NEIGHBOR> = AbstractBinaryTreeNodeNested<T>> implements IAbstractBinaryTreeNode<T, NEIGHBOR> {
import { AbstractBinaryTreeOptions, FamilyPosition, LoopType } from '../../types';
import { IAbstractBinaryTree, IAbstractBinaryTreeNode } from '../../interfaces';
export abstract class AbstractBinaryTreeNode<
T = any,
NEIGHBOR extends AbstractBinaryTreeNode<T, NEIGHBOR> = AbstractBinaryTreeNodeNested<T>
> implements IAbstractBinaryTreeNode<T, NEIGHBOR>
{
/**
* The constructor function initializes a BinaryTreeNode object with an id and an optional value.
* @param {BinaryTreeNodeId} id - The `id` parameter is of type `BinaryTreeNodeId` and represents the unique identifier
@ -132,8 +135,9 @@ export abstract class AbstractBinaryTreeNode<T = any, NEIGHBOR extends AbstractB
}
}
export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'], N> = AbstractBinaryTreeNode> implements IAbstractBinaryTree<N> {
export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'], N> = AbstractBinaryTreeNode>
implements IAbstractBinaryTree<N>
{
/**
* The protected constructor initializes the options for an abstract binary tree.
* @param {AbstractBinaryTreeOptions} [options] - An optional object that contains configuration options for the binary
@ -141,7 +145,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
*/
protected constructor(options?: AbstractBinaryTreeOptions) {
if (options !== undefined) {
const {loopType = LoopType.ITERATIVE} = options;
const { loopType = LoopType.ITERATIVE } = options;
this._loopType = loopType;
}
this.clear();
@ -189,7 +193,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
return this._visitedLeftSum;
}
abstract createNode(id: BinaryTreeNodeId, val?: N['val']): N | null ;
abstract createNode(id: BinaryTreeNodeId, val?: N['val']): N | null;
/**
* The `swapLocation` function swaps the location of two nodes in a binary tree.
@ -199,7 +203,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @returns The `destNode` is being returned.
*/
swapLocation(srcNode: N, destNode: N): N {
const {id, val, height} = destNode;
const { id, val, height } = destNode;
const tempNode = this.createNode(id, val);
if (tempNode) {
@ -297,7 +301,6 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
return inserted;
}
/**
* 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.
@ -344,7 +347,6 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
return idsOrNodes.length === this.addMany(idsOrNodes, data).length;
}
/**
* The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent node
* that needs to be balanced.
@ -356,7 +358,6 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @returns The function `remove` returns an array of `BinaryTreeDeletedResult<N>` objects.
*/
remove(nodeOrId: N | BinaryTreeNodeId, isUpdateAllLeftSum?: boolean): BinaryTreeDeletedResult<N>[] {
isUpdateAllLeftSum = isUpdateAllLeftSum === undefined ? true : isUpdateAllLeftSum;
// TODO may implement update all left sum
if (isUpdateAllLeftSum) {
@ -365,17 +366,18 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
if (!this.root) return bstDeletedResult;
const curr: N | null = (typeof nodeOrId === 'number') ? this.get(nodeOrId) : nodeOrId;
const curr: N | null = typeof nodeOrId === 'number' ? this.get(nodeOrId) : nodeOrId;
if (!curr) return bstDeletedResult;
const parent: N | null = curr?.parent ? curr.parent : null;
let needBalanced: N | null = null, orgCurrent = curr;
let needBalanced: N | null = null,
orgCurrent = curr;
if (!curr.left) {
if (!parent) {
if (curr.right !== undefined) this._setRoot(curr.right);
} else {
const {familyPosition: fp} = curr;
const { familyPosition: fp } = curr;
if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {
parent.left = curr.right;
} else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {
@ -389,7 +391,8 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
orgCurrent = this.swapLocation(curr, leftSubTreeRightMost);
if (parentOfLeftSubTreeMax) {
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
else parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
needBalanced = parentOfLeftSubTreeMax;
}
@ -397,7 +400,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
}
this._setSize(this.size - 1);
bstDeletedResult.push({deleted: orgCurrent, needBalanced});
bstDeletedResult.push({ deleted: orgCurrent, needBalanced });
return bstDeletedResult;
}
@ -444,18 +447,18 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
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) {
const {node, depth} = stack.pop()!;
const { node, depth } = stack.pop()!;
if (node.left) {
stack.push({node: node.left, depth: depth + 1});
stack.push({ node: node.left, depth: depth + 1 });
}
if (node.right) {
stack.push({node: node.right, depth: depth + 1});
stack.push({ node: node.right, depth: depth + 1 });
}
maxHeight = Math.max(maxHeight, depth);
@ -489,7 +492,8 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
return _getMinHeight(beginRoot);
} else {
const stack: N[] = [];
let node: N | null | undefined = beginRoot, last: N | null = null;
let node: N | null | undefined = beginRoot,
last: N | null = null;
const depths: Map<N, number> = new Map();
while (stack.length > 0 || node) {
@ -497,7 +501,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
stack.push(node);
node = node.left;
} else {
node = stack[stack.length - 1]
node = stack[stack.length - 1];
if (!node.right || last === node.right) {
node = stack.pop();
if (node) {
@ -507,7 +511,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
last = node;
node = null;
}
} else node = node.right
} else node = node.right;
}
}
@ -523,7 +527,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @returns The method is returning a boolean value.
*/
isPerfectlyBalanced(beginRoot?: N | null): boolean {
return (this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot));
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
}
/**
@ -537,7 +541,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* function will stop traversing the tree and return the first matching node. If `only
* @returns an array of nodes (type N).
*/
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean): N[] {
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName?: BinaryTreeNodePropertyName, onlyOne?: boolean): N[] {
if (!this.root) return [];
propertyName = propertyName ?? 'id';
@ -549,7 +553,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
if (!cur.left && !cur.right) return;
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
}
};
_traverse(this.root);
} else {
@ -575,7 +579,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* specifies the name of the property to be checked in the nodes. If not provided, it defaults to 'id'.
* @returns a boolean value.
*/
has(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): boolean {
has(nodeProperty: BinaryTreeNodeId | N, propertyName?: BinaryTreeNodePropertyName): boolean {
propertyName = propertyName ?? 'id';
// TODO may support finding node by value equal
return this.getNodes(nodeProperty, propertyName).length > 0;
@ -592,7 +596,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @returns either the value of the specified property of the node, or the node itself if no property name is provided.
* If no matching node is found, it returns null.
*/
get(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): N | null {
get(nodeProperty: BinaryTreeNodeId | N, propertyName?: BinaryTreeNodePropertyName): N | null {
propertyName = propertyName ?? 'id';
// TODO may support finding node by value equal
return this.getNodes(nodeProperty, propertyName, true)[0] ?? null;
@ -642,11 +646,10 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
if (!beginRoot) return beginRoot;
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N): N => {
if (!cur.left) return cur;
return _traverse(cur.left);
}
};
return _traverse(beginRoot);
} else {
@ -683,7 +686,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
const _traverse = (cur: N): N => {
if (!cur.right) return cur;
return _traverse(cur.right);
}
};
return _traverse(node);
} else {
@ -711,19 +714,20 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
if (!cur) return true;
if (cur.id <= min || cur.id >= max) return false;
return dfs(cur.left, min, cur.id) && dfs(cur.right, cur.id, max);
}
};
return dfs(node, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
} else {
const stack = [];
let prev = Number.MIN_SAFE_INTEGER, curr: N | null | undefined = node;
let prev = Number.MIN_SAFE_INTEGER,
curr: N | null | undefined = node;
while (curr || stack.length > 0) {
while (curr) {
stack.push(curr);
curr = curr.left;
}
curr = stack.pop()!;
if (!(curr) || prev >= curr.id) return false;
if (!curr || prev >= curr.id) return false;
prev = curr.id;
curr = curr.right;
}
@ -755,7 +759,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
size++;
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
}
};
_traverse(subTreeRoot);
return size;
@ -782,7 +786,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* not provided, it defaults to 'id'.
* @returns a number, which is the sum of the values of the specified property in the subtree rooted at `subTreeRoot`.
*/
subTreeSum(subTreeRoot: N | BinaryTreeNodeId | null, propertyName ?: BinaryTreeNodePropertyName): number {
subTreeSum(subTreeRoot: N | BinaryTreeNodeId | null, propertyName?: BinaryTreeNodePropertyName): number {
propertyName = propertyName ?? 'id';
if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'id');
@ -804,14 +808,14 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
break;
}
return needSum;
}
};
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N): void => {
sum += _sumByProperty(cur);
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
}
};
_traverse(subTreeRoot);
} else {
@ -838,7 +842,11 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* specifies the property of the binary tree node that should be modified. If not provided, it defaults to 'id'.
* @returns a boolean value.
*/
subTreeAdd(subTreeRoot: N | BinaryTreeNodeId | null, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean {
subTreeAdd(
subTreeRoot: N | BinaryTreeNodeId | null,
delta: number,
propertyName?: BinaryTreeNodePropertyName
): boolean {
propertyName = propertyName ?? 'id';
if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'id');
@ -853,7 +861,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
cur.id += delta;
break;
}
}
};
if (this._loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
@ -894,7 +902,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* the
* @returns an instance of the `AbstractBinaryTreeNodeProperties` class with generic type `N`.
*/
BFS(nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
BFS(nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
this._clearResults();
const queue: Array<N | null | undefined> = [this.root];
@ -930,7 +938,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* @returns an instance of the AbstractBinaryTreeNodeProperties class, which contains the accumulated properties of the
* binary tree nodes based on the specified pattern and node or property name.
*/
DFS(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
DFS(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
pattern = pattern ?? 'in';
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
this._clearResults();
@ -960,7 +968,6 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
DFSIterative(): BinaryTreeNodeId[];
// --- start additional methods ---
DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[];
@ -980,13 +987,16 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* the
* @returns an object of type AbstractBinaryTreeNodeProperties<N>.
*/
DFSIterative(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
DFSIterative(
pattern?: 'in' | 'pre' | 'post',
nodeOrPropertyName?: NodeOrPropertyName
): AbstractBinaryTreeNodeProperties<N> {
pattern = pattern || 'in';
nodeOrPropertyName = nodeOrPropertyName || 'id';
this._clearResults();
if (!this.root) return this._getResultByPropertyName(nodeOrPropertyName);
// 0: visit, 1: print
const stack: { opt: 0 | 1, node: N | null | undefined }[] = [{opt: 0, node: this.root}];
const stack: { opt: 0 | 1; node: N | null | undefined }[] = [{ opt: 0, node: this.root }];
while (stack.length > 0) {
const cur = stack.pop();
@ -996,24 +1006,24 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
} else {
switch (pattern) {
case 'in':
stack.push({opt: 0, node: cur.node.right});
stack.push({opt: 1, node: cur.node});
stack.push({opt: 0, node: cur.node.left});
stack.push({ opt: 0, node: cur.node.right });
stack.push({ opt: 1, node: cur.node });
stack.push({ opt: 0, node: cur.node.left });
break;
case 'pre':
stack.push({opt: 0, node: cur.node.right});
stack.push({opt: 0, node: cur.node.left});
stack.push({opt: 1, node: cur.node});
stack.push({ opt: 0, node: cur.node.right });
stack.push({ opt: 0, node: cur.node.left });
stack.push({ opt: 1, node: cur.node });
break;
case 'post':
stack.push({opt: 1, node: cur.node});
stack.push({opt: 0, node: cur.node.right});
stack.push({opt: 0, node: cur.node.left});
stack.push({ opt: 1, node: cur.node });
stack.push({ opt: 0, node: cur.node.right });
stack.push({ opt: 0, node: cur.node.left });
break;
default:
stack.push({opt: 0, node: cur.node.right});
stack.push({opt: 1, node: cur.node});
stack.push({opt: 0, node: cur.node.left});
stack.push({ opt: 0, node: cur.node.right });
stack.push({ opt: 1, node: cur.node });
stack.push({ opt: 0, node: cur.node.left });
break;
}
}
@ -1042,7 +1052,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* accumulating results
* @returns The function `levelIterative` returns an object of type `AbstractBinaryTreeNodeProperties<N>`.
*/
levelIterative(node: N | null, nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
levelIterative(node: N | null, nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
nodeOrPropertyName = nodeOrPropertyName || 'id';
node = node || this.root;
if (!node) return [];
@ -1105,7 +1115,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
levelsNodes[level].push(node.id);
break;
}
}
};
if (this.loopType === LoopType.RECURSIVE) {
const _recursive = (node: N, level: number) => {
@ -1141,7 +1151,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
getPredecessor(node: N): N {
if (node.left) {
let predecessor: N | null | undefined = node.left;
while (!(predecessor) || predecessor.right && predecessor.right !== node) {
while (!predecessor || (predecessor.right && predecessor.right !== node)) {
if (predecessor) {
predecessor = predecessor.right;
}
@ -1175,7 +1185,10 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* tree.
* @returns an array of AbstractBinaryTreeNodeProperties<N> objects.
*/
morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
morris(
pattern?: 'in' | 'pre' | 'post',
nodeOrPropertyName?: NodeOrPropertyName
): AbstractBinaryTreeNodeProperties<N> {
if (this.root === null) return [];
pattern = pattern || 'in';
@ -1335,7 +1348,6 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
this._visitedLeftSum = value;
}
/**
* The function sets the root property of an object to a given value, and if the value is not null, it also sets the
* parent property of the value to undefined.
@ -1382,7 +1394,13 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* `true`, the function will stop after finding the first matching node and return `true`. If `onlyOne
* @returns a boolean value indicating whether only one matching node should be pushed into the result array.
*/
protected _pushByPropertyNameStopOrNot(cur: N, result: (N | null | undefined)[], nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean) {
protected _pushByPropertyNameStopOrNot(
cur: N,
result: (N | null | undefined)[],
nodeProperty: BinaryTreeNodeId | N,
propertyName?: BinaryTreeNodePropertyName,
onlyOne?: boolean
) {
switch (propertyName) {
case 'id':
if (cur.id === nodeProperty) {
@ -1412,7 +1430,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* can be either a string representing a property name or a reference to a `Node` object. If it is a string, it
* specifies the property name to be used for accumulating values. If it is a `Node` object, it specifies
*/
protected _accumulatedByPropertyName(node: N, nodeOrPropertyName ?: NodeOrPropertyName) {
protected _accumulatedByPropertyName(node: N, nodeOrPropertyName?: NodeOrPropertyName) {
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
switch (nodeOrPropertyName) {
@ -1443,7 +1461,7 @@ export abstract class AbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val
* can accept either a `NodeOrPropertyName` type or be undefined.
* @returns The method `_getResultByPropertyName` returns an instance of `AbstractBinaryTreeNodeProperties<N>`.
*/
protected _getResultByPropertyName(nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
protected _getResultByPropertyName(nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N> {
nodeOrPropertyName = nodeOrPropertyName ?? 'id';
switch (nodeOrPropertyName) {

View file

@ -5,11 +5,14 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import {BST, BSTNode} from './bst';
import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BinaryTreeNodeId} from '../../types';
import {IAVLTree, IAVLTreeNode} from '../../interfaces';
import { BST, BSTNode } from './bst';
import type { AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BinaryTreeNodeId } from '../../types';
import { IAVLTree, IAVLTreeNode } from '../../interfaces';
export class AVLTreeNode<T = any, NEIGHBOR extends AVLTreeNode<T, NEIGHBOR> = AVLTreeNodeNested<T>> extends BSTNode<T, NEIGHBOR> implements IAVLTreeNode<T, NEIGHBOR> {
export class AVLTreeNode<T = any, NEIGHBOR extends AVLTreeNode<T, NEIGHBOR> = AVLTreeNodeNested<T>>
extends BSTNode<T, NEIGHBOR>
implements IAVLTreeNode<T, NEIGHBOR>
{
constructor(id: BinaryTreeNodeId, val?: T) {
super(id, val);
}
@ -64,7 +67,7 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
*/
override remove(id: BinaryTreeNodeId, isUpdateAllLeftSum?: boolean): BinaryTreeDeletedResult<N>[] {
const deletedResults = super.remove(id, isUpdateAllLeftSum);
for (const {needBalanced} of deletedResults) {
for (const { needBalanced } of deletedResults) {
if (needBalanced) {
this._balancePath(needBalanced);
}
@ -79,12 +82,13 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
* @returns The balance factor of the given AVL tree node.
*/
protected _balanceFactor(node: N): number {
if (!node.right) // node has no right subtree
if (!node.right)
// node has no right subtree
return -node.height;
else if (!node.left) // node has no left subtree
else if (!node.left)
// node has no left subtree
return +node.height;
else
return node.right.height - node.left.height;
else return node.right.height - node.left.height;
}
/**
@ -92,15 +96,12 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
* @param node - The parameter `node` is an AVLTreeNode object, which represents a node in an AVL tree.
*/
protected _updateHeight(node: N): void {
if (!node.left && !node.right)
node.height = 0;
if (!node.left && !node.right) node.height = 0;
else if (!node.left) {
const rightHeight = node.right ? node.right.height : 0;
node.height = 1 + rightHeight;
} else if (!node.right)
node.height = 1 + node.left.height;
else
node.height = 1 + Math.max(node.right.height, node.left.height);
} else if (!node.right) node.height = 1 + node.left.height;
else node.height = 1 + Math.max(node.right.height, node.left.height);
}
/**
@ -109,18 +110,21 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
* @param node - The `node` parameter is an AVLTreeNode object, which represents a node in an AVL tree.
*/
protected _balancePath(node: N): void {
const path = this.getPathToRoot(node, false); // first O(log n) + O(log n)
for (let i = 0; i < path.length; i++) { // second O(log n)
const path = this.getPathToRoot(node, false); // first O(log n) + O(log n)
for (let i = 0; i < path.length; i++) {
// second O(log n)
const A = path[i];
// Update Heights: After inserting a node, backtrack from the insertion point to the root node, updating the height of each node along the way.
this._updateHeight(A); // first O(1)
this._updateHeight(A); // first O(1)
// Check Balance: Simultaneously with height updates, check if each node violates the balance property of an AVL tree.
// 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)
switch (
this._balanceFactor(A) // second O(1)
) {
case -2:
if (A && A.left) {
if (this._balanceFactor(A.left) <= 0) { // second O(1)
if (this._balanceFactor(A.left) <= 0) {
// second O(1)
// Left Rotation (LL Rotation): When the inserted node is in the left subtree of the left subtree, causing an imbalance.
this._balanceLL(A);
} else {
@ -282,7 +286,6 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
C.parent = parentOfA;
}
if (A === this.root) {
if (C) this._setRoot(C);
} else {
@ -305,5 +308,3 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
C && this._updateHeight(C);
}
}

View file

@ -1,3 +1 @@
export class BTree {
}
export class BTree {}

View file

@ -6,7 +6,6 @@
* @license MIT License
*/
export class BinaryIndexedTree {
/**
* The constructor initializes an array with a specified length and fills it with zeros.
* @param {number} n - The parameter `n` represents the size of the array that will be used to store the sum tree. The
@ -24,7 +23,7 @@ export class BinaryIndexedTree {
}
static lowBit(x: number) {
return x & (-x);
return x & -x;
}
/**
@ -67,8 +66,7 @@ export class BinaryIndexedTree {
* @returns the sum of the elements in the range specified by the start and end indices.
*/
getRangeSum(start: number, end: number): number {
if (!(0 <= start && start <= end && end <= this._sumTree.length))
throw 'Index out of bounds';
if (!(0 <= start && start <= end && end <= this._sumTree.length)) throw 'Index out of bounds';
return this.getPrefixSum(end) - this.getPrefixSum(start);
}

View file

@ -6,18 +6,23 @@
* @license MIT License
*/
import type {BinaryTreeNodeId, BinaryTreeNodeNested, BinaryTreeOptions} from '../../types';
import {AbstractBinaryTree, AbstractBinaryTreeNode} from './abstract-binary-tree';
import {IBinaryTree, IBinaryTreeNode} from '../../interfaces';
import type { BinaryTreeNodeId, BinaryTreeNodeNested, BinaryTreeOptions } from '../../types';
import { AbstractBinaryTree, AbstractBinaryTreeNode } from './abstract-binary-tree';
import { IBinaryTree, IBinaryTreeNode } from '../../interfaces';
export class BinaryTreeNode<T = any, NEIGHBOR extends BinaryTreeNode<T, NEIGHBOR> = BinaryTreeNodeNested<T>> extends AbstractBinaryTreeNode<T, NEIGHBOR> implements IBinaryTreeNode<T, NEIGHBOR> {
export class BinaryTreeNode<T = any, NEIGHBOR extends BinaryTreeNode<T, NEIGHBOR> = BinaryTreeNodeNested<T>>
extends AbstractBinaryTreeNode<T, NEIGHBOR>
implements IBinaryTreeNode<T, NEIGHBOR>
{
constructor(id: BinaryTreeNodeId, val?: T) {
super(id, val);
}
}
export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode> extends AbstractBinaryTree<N> implements IBinaryTree<N> {
export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
extends AbstractBinaryTree<N>
implements IBinaryTree<N>
{
/**
* This is a constructor function for a binary tree class that takes an optional options parameter.
* @param {BinaryTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the

View file

@ -5,12 +5,21 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type {BinaryTreeNodeId, BinaryTreeNodePropertyName, BSTComparator, BSTNodeNested, BSTOptions} from '../../types';
import {CP, LoopType} from '../../types';
import {BinaryTree, BinaryTreeNode} from './binary-tree';
import {IBST, IBSTNode} from '../../interfaces';
import type {
BinaryTreeNodeId,
BinaryTreeNodePropertyName,
BSTComparator,
BSTNodeNested,
BSTOptions
} from '../../types';
import { CP, LoopType } from '../../types';
import { BinaryTree, BinaryTreeNode } from './binary-tree';
import { IBST, IBSTNode } from '../../interfaces';
export class BSTNode<T = any, NEIGHBOR extends BSTNode<T, NEIGHBOR> = BSTNodeNested<T>> extends BinaryTreeNode<T, NEIGHBOR> implements IBSTNode<T, NEIGHBOR> {
export class BSTNode<T = any, NEIGHBOR extends BSTNode<T, NEIGHBOR> = BSTNodeNested<T>>
extends BinaryTreeNode<T, NEIGHBOR>
implements IBSTNode<T, NEIGHBOR>
{
constructor(id: BinaryTreeNodeId, val?: T) {
super(id, val);
}
@ -24,7 +33,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
constructor(options?: BSTOptions) {
super(options);
if (options !== undefined) {
const {comparator} = options;
const { comparator } = options;
if (comparator !== undefined) {
this._comparator = comparator;
}
@ -66,7 +75,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
if (this.root === null) {
this._setRoot(newNode);
this._setSize(this.size + 1);
inserted = (this.root);
inserted = this.root;
} else {
let cur = this.root;
let traversing = true;
@ -104,7 +113,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
cur.right = newNode;
this._setSize(this.size + 1);
traversing = false;
inserted = (cur.right);
inserted = cur.right;
} else {
//Traverse the left of the current node
if (cur.right) cur = cur.right;
@ -128,35 +137,40 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* @param {boolean} isBalanceAdd - If true the nodes will be balance inserted in binary search method.
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
override addMany(idsOrNodes: (BinaryTreeNodeId | null)[] | (N | null)[], data?: N['val'][], isBalanceAdd = false): (N | null | undefined)[] {
function hasNoNull (arr: (BinaryTreeNodeId | null)[] | (N | null)[]): arr is BinaryTreeNodeId[] | N[] {
override addMany(
idsOrNodes: (BinaryTreeNodeId | null)[] | (N | null)[],
data?: N['val'][],
isBalanceAdd = false
): (N | null | undefined)[] {
function hasNoNull(arr: (BinaryTreeNodeId | null)[] | (N | null)[]): arr is BinaryTreeNodeId[] | N[] {
return arr.indexOf(null) === -1;
}
if (!isBalanceAdd || !hasNoNull(idsOrNodes)) {
return super.addMany(idsOrNodes, data);
}
const inserted: (N | null | undefined)[] = [];
const combinedArr: [BinaryTreeNodeId | N , N['val']][] = idsOrNodes.map((value, index) => [value, data?.[index]]);
const combinedArr: [BinaryTreeNodeId | N, N['val']][] = idsOrNodes.map((value, index) => [value, data?.[index]]);
let sorted = [];
function isNodeOrNullTuple(arr: [BinaryTreeNodeId | N , N['val']][]): arr is [N , N['val']][] {
function isNodeOrNullTuple(arr: [BinaryTreeNodeId | N, N['val']][]): arr is [N, N['val']][] {
for (const [idOrNode] of arr) if (idOrNode instanceof BSTNode) return true;
return false;
}
function isBinaryTreeIdOrNullTuple(arr: [BinaryTreeNodeId | N , N['val']][]): arr is [BinaryTreeNodeId , N['val']][] {
function isBinaryTreeIdOrNullTuple(arr: [BinaryTreeNodeId | N, N['val']][]): arr is [BinaryTreeNodeId, N['val']][] {
for (const [idOrNode] of arr) if (typeof idOrNode === 'number') return true;
return false;
}
let sortedIdsOrNodes: (number | N | null)[] = [], sortedData: (N["val"] | undefined)[] | undefined = [];
let sortedIdsOrNodes: (number | N | null)[] = [],
sortedData: (N['val'] | undefined)[] | undefined = [];
if (isNodeOrNullTuple(combinedArr)) {
sorted = combinedArr.sort((a, b) => a[0].id - b[0].id);
} else if (isBinaryTreeIdOrNullTuple(combinedArr)) {
sorted = combinedArr.sort((a, b) => a[0] - b[0]);
} else {
throw new Error('Invalid input idsOrNodes')
throw new Error('Invalid input idsOrNodes');
}
sortedIdsOrNodes = sorted.map(([idOrNode,]) => idOrNode);
sortedData = sorted.map(([,val]) => val);
sortedIdsOrNodes = sorted.map(([idOrNode]) => idOrNode);
sortedData = sorted.map(([, val]) => val);
const recursive = (arr: (BinaryTreeNodeId | null | N)[], data?: N['val'][]) => {
if (arr.length === 0) return;
@ -165,7 +179,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
inserted.push(newNode);
recursive(arr.slice(0, mid), data?.slice(0, mid));
recursive(arr.slice(mid + 1), data?.slice(mid + 1));
}
};
const iterative = () => {
const n = sorted.length;
const stack: [[number, number]] = [[0, n - 1]];
@ -182,9 +196,9 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
}
}
}
}
};
if (this.loopType === LoopType.RECURSIVE) {
recursive(sortedIdsOrNodes, sortedData)
recursive(sortedIdsOrNodes, sortedData);
} else {
iterative();
}
@ -200,7 +214,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* specifies the property name to use for searching the binary tree nodes. If not provided, it defaults to `'id'`.
* @returns The method is returning either a BinaryTreeNodeId or N (generic type) or null.
*/
override get(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): N | null {
override get(nodeProperty: BinaryTreeNodeId | N, propertyName?: BinaryTreeNodePropertyName): N | null {
propertyName = propertyName ?? 'id';
return this.getNodes(nodeProperty, propertyName, true)[0] ?? null;
}
@ -229,7 +243,11 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* is set to `true`, the function will return an array with only one node (if
* @returns an array of nodes (type N).
*/
override getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName : BinaryTreeNodePropertyName = 'id', onlyOne ?: boolean): N[] {
override getNodes(
nodeProperty: BinaryTreeNodeId | N,
propertyName: BinaryTreeNodePropertyName = 'id',
onlyOne?: boolean
): N[] {
if (!this.root) return [];
const result: N[] = [];
@ -245,7 +263,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
}
}
};
_traverse(this.root);
} else {
@ -278,7 +296,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* @returns The function `lesserSum` returns a number, which represents the sum of the values of the nodes in the
* binary tree that have a lesser value than the specified `beginNode` based on the `propertyName`.
*/
lesserSum(beginNode: N | BinaryTreeNodeId | null, propertyName ?: BinaryTreeNodePropertyName): number {
lesserSum(beginNode: N | BinaryTreeNodeId | null, propertyName?: BinaryTreeNodePropertyName): number {
propertyName = propertyName ?? 'id';
if (typeof beginNode === 'number') beginNode = this.get(beginNode, 'id');
if (!beginNode) return 0;
@ -295,7 +313,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
break;
}
return needSum;
}
};
let sum = 0;
@ -326,7 +344,8 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
if (compared === CP.eq) {
if (cur.right) sum += this.subTreeSum(cur.right, propertyName);
return sum;
} else if (compared === CP.lt) { // todo maybe a bug
} else if (compared === CP.lt) {
// todo maybe a bug
if (cur.left) sum += this.subTreeSum(cur.left, propertyName);
sum += getSumByPropertyName(cur);
if (cur.right) queue.push(cur.right);
@ -354,7 +373,11 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* 'id'.
* @returns a boolean value.
*/
allGreaterNodesAdd(node: N | BinaryTreeNodeId | null, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean {
allGreaterNodesAdd(
node: N | BinaryTreeNodeId | null,
delta: number,
propertyName?: BinaryTreeNodePropertyName
): boolean {
propertyName = propertyName ?? 'id';
if (typeof node === 'number') node = this.get(node, 'id');
if (!node) return false;
@ -370,7 +393,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
cur.id += delta;
break;
}
}
};
if (this.loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
const compared = this._compare(cur.id, id);
@ -409,14 +432,14 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* AVL Tree: AVL trees are well-suited for scenarios involving frequent searching, insertion, and deletion operations. Through rotation adjustments, AVL trees maintain their balance, ensuring average and worst-case time complexity of O(log n).
*/
/**
* The `perfectlyBalance` function takes a binary tree, performs a depth-first search to sort the nodes, and then
* constructs a balanced binary search tree using either a recursive or iterative approach.
* @returns The function `perfectlyBalance()` returns a boolean value.
*/
perfectlyBalance(): boolean {
const sorted = this.DFS('in', 'node'), n = sorted.length;
const sorted = this.DFS('in', 'node'),
n = sorted.length;
this.clear();
if (sorted.length < 1) return false;
@ -463,14 +486,16 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
if (this.loopType === LoopType.RECURSIVE) {
const _height = (cur: N | null | undefined): number => {
if (!cur) return 0;
const leftHeight = _height(cur.left), rightHeight = _height(cur.right);
const leftHeight = _height(cur.left),
rightHeight = _height(cur.right);
if (Math.abs(leftHeight - rightHeight) > 1) balanced = false;
return Math.max(leftHeight, rightHeight) + 1;
};
_height(this.root);
} else {
const stack: N[] = [];
let node: N | null | undefined = this.root, last: N | null = null;
let node: N | null | undefined = this.root,
last: N | null = null;
const depths: Map<N, number> = new Map();
while (stack.length > 0 || node) {
@ -478,7 +503,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
stack.push(node);
node = node.left;
} else {
node = stack[stack.length - 1]
node = stack[stack.length - 1];
if (!node.right || last === node.right) {
node = stack.pop();
if (node) {
@ -489,7 +514,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
last = node;
node = null;
}
} else node = node.right
} else node = node.right;
}
}
}

View file

@ -1,9 +1,11 @@
import {BinaryTreeNodeId, RBColor, RBTreeNodeNested, RBTreeOptions} from '../../types';
import {IRBTree, IRBTreeNode} from '../../interfaces/rb-tree';
import {BST, BSTNode} from './bst';
import { BinaryTreeNodeId, RBColor, RBTreeNodeNested, RBTreeOptions } from '../../types';
import { IRBTree, IRBTreeNode } from '../../interfaces/rb-tree';
import { BST, BSTNode } from './bst';
export class RBTreeNode<T = any, NEIGHBOR extends RBTreeNode<T, NEIGHBOR> = RBTreeNodeNested<T>> extends BSTNode<T, NEIGHBOR> implements IRBTreeNode<T, NEIGHBOR> {
export class RBTreeNode<T = any, NEIGHBOR extends RBTreeNode<T, NEIGHBOR> = RBTreeNodeNested<T>>
extends BSTNode<T, NEIGHBOR>
implements IRBTreeNode<T, NEIGHBOR>
{
constructor(id: BinaryTreeNodeId, val?: T, color: RBColor = RBColor.RED) {
super(id, val);
this._color = color;
@ -19,7 +21,6 @@ export class RBTreeNode<T = any, NEIGHBOR extends RBTreeNode<T, NEIGHBOR> = RBTr
this._color = value;
}
// private override _parent: RBNode<T> | null;
// override set parent(v: RBNode<T> | null) {
// this._parent = v;
@ -97,6 +98,4 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
//
// return [{deleted: new N(0, 0), needBalanced: null}];
// }
}

View file

@ -6,7 +6,7 @@
* @license MIT License
*/
import type {SegmentTreeNodeVal} from '../../types';
import type { SegmentTreeNodeVal } from '../../types';
export class SegmentTreeNode {
constructor(start: number, end: number, sum: number, val?: SegmentTreeNodeVal | null) {
@ -209,7 +209,6 @@ export class SegmentTree {
if (cur.right) {
// TODO after no-non-null-assertion not ensure the logic
return dfs(cur.right, i, j);
} else {
return NaN;
}

View file

@ -1,3 +1 @@
export class SplayTree {
}
export class SplayTree {}

View file

@ -5,13 +5,15 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type {BinaryTreeNodeId, TreeMultisetNodeNested, TreeMultisetOptions} from '../../types';
import {BinaryTreeDeletedResult, CP, DFSOrderPattern, FamilyPosition, LoopType} from '../../types';
import {ITreeMultiset, ITreeMultisetNode} from '../../interfaces';
import {AVLTree, AVLTreeNode} from './avl-tree';
export class TreeMultisetNode<T = any, NEIGHBOR extends TreeMultisetNode<T, NEIGHBOR> = TreeMultisetNodeNested<T>> extends AVLTreeNode<T, NEIGHBOR> implements ITreeMultisetNode<T, NEIGHBOR> {
import type { BinaryTreeNodeId, TreeMultisetNodeNested, TreeMultisetOptions } from '../../types';
import { BinaryTreeDeletedResult, CP, DFSOrderPattern, FamilyPosition, LoopType } from '../../types';
import { ITreeMultiset, ITreeMultisetNode } from '../../interfaces';
import { AVLTree, AVLTreeNode } from './avl-tree';
export class TreeMultisetNode<T = any, NEIGHBOR extends TreeMultisetNode<T, NEIGHBOR> = TreeMultisetNodeNested<T>>
extends AVLTreeNode<T, NEIGHBOR>
implements ITreeMultisetNode<T, NEIGHBOR>
{
/**
* The constructor function initializes a BinaryTreeNode object with an id, value, and count.
* @param {BinaryTreeNodeId} id - The `id` parameter is of type `BinaryTreeNodeId` and represents the unique identifier
@ -41,8 +43,10 @@ export class TreeMultisetNode<T = any, NEIGHBOR extends TreeMultisetNode<T, NEIG
/**
* The only distinction between a TreeMultiset and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.
*/
export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultisetNode> extends AVLTree<N> implements ITreeMultiset<N> {
export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultisetNode>
extends AVLTree<N>
implements ITreeMultiset<N>
{
/**
* The constructor function for a TreeMultiset class in TypeScript, which extends another class and sets an option to
* merge duplicated values.
@ -50,7 +54,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
* TreeMultiset.
*/
constructor(options?: TreeMultisetOptions) {
super({...options});
super({ ...options });
}
private _count = 0;
@ -80,7 +84,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
* @returns the `destNode` after swapping its values with the `srcNode`.
*/
override swapLocation(srcNode: N, destNode: N): N {
const {id, val, count, height} = destNode;
const { id, val, count, height } = destNode;
const tempNode = this.createNode(id, val, count);
if (tempNode) {
tempNode.height = height;
@ -111,7 +115,8 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
*/
override add(idOrNode: BinaryTreeNodeId | N | null, val?: N['val'], count?: number): N | null | undefined {
count = count ?? 1;
let inserted: N | null | undefined = undefined, newNode: N | null;
let inserted: N | null | undefined = undefined,
newNode: N | null;
if (idOrNode instanceof TreeMultisetNode) {
newNode = this.createNode(idOrNode.id, idOrNode.val, idOrNode.count);
} else if (idOrNode === null) {
@ -159,7 +164,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
this._setCount(this.count + newNode.count);
traversing = false;
inserted = (cur.right);
inserted = cur.right;
} else {
//Traverse the left of the current node
if (cur.right) cur = cur.right;
@ -192,12 +197,11 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
parent.left = newNode;
if (newNode !== null) {
this._setSize(this.size + 1);
this._setCount(this.count + newNode.count)
this._setCount(this.count + newNode.count);
}
return parent.left;
} else if (parent.right === undefined) {
parent.right = newNode;
if (newNode !== null) {
this._setSize(this.size + 1);
@ -222,7 +226,10 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
* method. If provided, the `data` array should
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
override addMany(idsOrNodes: (BinaryTreeNodeId | null)[] | (N | null)[], data?: N['val'][]): (N | null | undefined)[] {
override addMany(
idsOrNodes: (BinaryTreeNodeId | null)[] | (N | null)[],
data?: N['val'][]
): (N | null | undefined)[] {
const inserted: (N | null | undefined)[] = [];
for (let i = 0; i < idsOrNodes.length; i++) {
@ -249,7 +256,8 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
* @returns The function `perfectlyBalance()` returns a boolean value.
*/
override perfectlyBalance(): boolean {
const sorted = this.DFS('in', 'node'), n = sorted.length;
const sorted = this.DFS('in', 'node'),
n = sorted.length;
if (sorted.length < 1) return false;
this.clear();
@ -302,7 +310,8 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
if (!curr) return bstDeletedResult;
const parent: N | null = curr?.parent ? curr.parent : null;
let needBalanced: N | null = null, orgCurrent = curr;
let needBalanced: N | null = null,
orgCurrent = curr;
if (curr.count > 1 && !ignoreCount) {
curr.count--;
@ -312,7 +321,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
if (!parent) {
if (curr.right !== undefined) this._setRoot(curr.right);
} else {
const {familyPosition: fp} = curr;
const { familyPosition: fp } = curr;
if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {
parent.left = curr.right;
} else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {
@ -340,7 +349,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
this._setCount(this.count - orgCurrent.count);
}
bstDeletedResult.push({deleted: orgCurrent, needBalanced});
bstDeletedResult.push({ deleted: orgCurrent, needBalanced });
if (needBalanced) {
this._balancePath(needBalanced);
@ -366,7 +375,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
res[1] += cur.count;
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
}
};
_traverse(subTreeRoot);
return res;
@ -394,7 +403,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
* @returns the sum of the count values of all nodes in the subtree rooted at `subTreeRoot`.
*/
subTreeSumCount(subTreeRoot: N | BinaryTreeNodeId | null): number {
if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'id');
if (!subTreeRoot) return 0;
@ -406,7 +414,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
sum += cur.count;
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
}
};
_traverse(subTreeRoot);
} else {
@ -441,7 +449,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
const _addByProperty = (cur: N) => {
cur.count += delta;
this._setCount(this.count + delta);
}
};
if (this.loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
@ -475,7 +483,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
* to `true`, the function will return only one node. If `onlyOne`
* @returns an array of nodes that match the given nodeProperty.
*/
getNodesByCount(nodeProperty: BinaryTreeNodeId | N, onlyOne ?: boolean): N[] {
getNodesByCount(nodeProperty: BinaryTreeNodeId | N, onlyOne?: boolean): N[] {
if (!this.root) return [];
const result: N[] = [];
@ -489,7 +497,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
if (!cur.left && !cur.right) return;
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
}
};
_traverse(this.root);
} else {
@ -504,7 +512,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
cur.left && queue.push(cur.left);
cur.right && queue.push(cur.right);
}
}
}
@ -548,7 +555,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
return nodes.map(node => node.count);
}
/**
* The function DFSIterativeCount performs an iterative depth-first search and returns an array of node counts based on
* the specified traversal pattern.
@ -557,13 +563,12 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
* @returns The DFSIterativeCount function returns an array of numbers, which represents the count property of each node
* in the DFS traversal.
*/
DFSIterativeCount(pattern ?: 'in' | 'pre' | 'post'): number[] {
DFSIterativeCount(pattern?: 'in' | 'pre' | 'post'): number[] {
pattern = pattern ?? 'in';
const nodes = super.DFSIterative(pattern, 'node');
return nodes.map(node => node.count);
}
/**
* The DFSCount function returns an array of counts for each node in a depth-first search traversal.
* @param {DFSOrderPattern} [pattern] - The pattern parameter is an optional parameter that specifies the order in which
@ -575,7 +580,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
pattern = pattern ?? 'in';
const nodes = super.DFS(pattern, 'node');
return nodes.map(node => node.count);
}
/**
@ -619,7 +623,8 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
if (compared === CP.eq) {
if (cur.right) sum += this.subTreeSumCount(cur.right);
return sum;
} else if (compared === CP.lt) { // todo maybe a bug
} else if (compared === CP.lt) {
// todo maybe a bug
if (cur.left) sum += this.subTreeSumCount(cur.left);
sum += cur.count;
if (cur.right) queue.push(cur.right);
@ -649,7 +654,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
const id = node.id;
if (!this.root) return false;
if (this.loopType === LoopType.RECURSIVE) {
const _traverse = (cur: N) => {
const compared = this._compare(cur.id, id);
@ -668,7 +672,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
const cur = queue.shift();
if (cur) {
const compared = this._compare(cur.id, id);
if (compared === CP.gt) cur.count += delta
if (compared === CP.gt) cur.count += delta;
if (cur.left && this._compare(cur.left.id, id) === CP.gt) queue.push(cur.left);
if (cur.right && this._compare(cur.right.id, id) === CP.gt) queue.push(cur.right);
@ -693,5 +697,4 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
protected _setCount(v: number) {
this._count = v;
}
}

View file

@ -1,3 +1 @@
export class TwoThreeTree {
}
export class TwoThreeTree {}

View file

@ -5,13 +5,12 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import {arrayRemove, uuidV4} from '../../utils';
import {PriorityQueue} from '../priority-queue';
import type {DijkstraResult, VertexId} from '../../types';
import {IAbstractGraph} from '../../interfaces';
import { arrayRemove, uuidV4 } from '../../utils';
import { PriorityQueue } from '../priority-queue';
import type { DijkstraResult, VertexId } from '../../types';
import { IAbstractGraph } from '../../interfaces';
export abstract class AbstractVertex<T = any> {
/**
* The function is a protected constructor that takes an id and an optional value as parameters.
* @param {VertexId} id - The `id` parameter is of type `VertexId` and represents the identifier of the vertex. It is
@ -46,7 +45,6 @@ export abstract class AbstractVertex<T = any> {
}
export abstract class AbstractEdge<T = any> {
/**
* The above function is a protected constructor that initializes the weight, value, and hash code properties of an
* object.
@ -103,7 +101,11 @@ export abstract class AbstractEdge<T = any> {
}
}
export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVertex<any>, E extends AbstractEdge<any> = AbstractEdge<any>> implements IAbstractGraph<V, E> {
export abstract class AbstractGraph<
V extends AbstractVertex<any> = AbstractVertex<any>,
E extends AbstractEdge<any> = AbstractEdge<any>
> implements IAbstractGraph<V, E>
{
private _vertices: Map<VertexId, V> = new Map<VertexId, V>();
get vertices(): Map<VertexId, V> {
@ -163,14 +165,13 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
return this._vertices.has(this._getVertexId(vertexOrId));
}
addVertex(vertex: V): boolean
addVertex(vertex: V): boolean;
addVertex(id: VertexId, val?: V['val']): boolean
addVertex(id: VertexId, val?: V['val']): boolean;
addVertex(idOrVertex: VertexId | V, val?: V['val']): boolean {
if (idOrVertex instanceof AbstractVertex) {
return this._addVertexOnly(idOrVertex);
} else {
const newVertex = this.createVertex(idOrVertex, val);
return this._addVertexOnly(newVertex);
@ -216,9 +217,9 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
return !!edge;
}
addEdge(edge: E): boolean
addEdge(edge: E): boolean;
addEdge(src: V | VertexId, dest: V | VertexId, weight?: number, val?: E['val']): boolean
addEdge(src: V | VertexId, dest: V | VertexId, weight?: number, val?: E['val']): boolean;
addEdge(srcOrEdge: V | VertexId | E, dest?: V | VertexId, weight?: number, val?: E['val']): boolean {
if (srcOrEdge instanceof AbstractEdge) {
@ -231,7 +232,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
const newEdge = this.createEdge(srcOrEdge, dest, weight, val);
return this._addEdgeOnly(newEdge);
} else {
throw new Error('dest must be a Vertex or vertex id while srcOrEdge is an Edge')
throw new Error('dest must be a Vertex or vertex id while srcOrEdge is an Edge');
}
}
}
@ -452,7 +453,12 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
* shortest paths from the source vertex to all other vertices in the graph. If `genPaths
* @returns The function `dijkstraWithoutHeap` returns an object of type `DijkstraResult<V>`.
*/
dijkstraWithoutHeap(src: V | VertexId, dest?: V | VertexId | null, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<V> {
dijkstraWithoutHeap(
src: V | VertexId,
dest?: V | VertexId | null,
getMinDist?: boolean,
genPaths?: boolean
): DijkstraResult<V> {
if (getMinDist === undefined) getMinDist = false;
if (genPaths === undefined) genPaths = false;
@ -524,7 +530,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
if (genPaths) {
getPaths(destVertex);
}
return {distMap, preMap, seen, paths, minDist, minPath};
return { distMap, preMap, seen, paths, minDist, minPath };
}
const neighbors = this.getNeighbors(cur);
for (const neighbor of neighbors) {
@ -540,25 +546,25 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
preMap.set(neighbor, cur);
}
}
}
}
}
}
}
getMinDist && distMap.forEach((d, v) => {
if (v !== srcVertex) {
if (d < minDist) {
minDist = d;
if (genPaths) minDest = v;
getMinDist &&
distMap.forEach((d, v) => {
if (v !== srcVertex) {
if (d < minDist) {
minDist = d;
if (genPaths) minDest = v;
}
}
}
});
});
genPaths && getPaths(minDest);
return {distMap, preMap, seen, paths, minDist, minPath};
return { distMap, preMap, seen, paths, minDist, minPath };
}
/**
@ -611,8 +617,10 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
if (vertexOrId instanceof AbstractVertex) distMap.set(vertexOrId, Infinity);
}
const heap = new PriorityQueue<{ id: number, val: V }>({comparator: (a, b) => a.id - b.id});
heap.add({id: 0, val: srcVertex});
const heap = new PriorityQueue<{ id: number; val: V }>({
comparator: (a, b) => a.id - b.id
});
heap.add({ id: 0, val: srcVertex });
distMap.set(srcVertex, 0);
preMap.set(srcVertex, null);
@ -636,7 +644,6 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
if (vertex[1] === minV) minPath = reversed;
paths.push(reversed);
}
}
};
@ -654,7 +661,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
if (genPaths) {
getPaths(destVertex);
}
return {distMap, preMap, seen, paths, minDist, minPath};
return { distMap, preMap, seen, paths, minDist, minPath };
}
const neighbors = this.getNeighbors(cur);
for (const neighbor of neighbors) {
@ -664,7 +671,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
const distSrcToNeighbor = distMap.get(neighbor);
if (distSrcToNeighbor) {
if (dist + weight < distSrcToNeighbor) {
heap.add({id: dist + weight, val: neighbor});
heap.add({ id: dist + weight, val: neighbor });
preMap.set(neighbor, cur);
distMap.set(neighbor, dist + weight);
}
@ -691,7 +698,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
getPaths(minDest);
}
return {distMap, preMap, seen, paths, minDist, minPath};
return { distMap, preMap, seen, paths, minDist, minPath };
}
/**
@ -728,7 +735,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
// TODO
let hasNegativeCycle: boolean | undefined;
if (scanNegativeCycle) hasNegativeCycle = false;
if (!srcVertex) return {hasNegativeCycle, distMap, preMap, paths, min, minPath};
if (!srcVertex) return { hasNegativeCycle, distMap, preMap, paths, min, minPath };
const vertices = this._vertices;
const numOfVertices = vertices.size;
@ -800,7 +807,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
}
}
return {hasNegativeCycle, distMap, preMap, paths, min, minPath};
return { hasNegativeCycle, distMap, preMap, paths, min, minPath };
}
/**
@ -812,7 +819,6 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
* Dijkstra's algorithm is used to find the shortest paths from a source node to all other nodes in a graph. Its basic idea is to repeatedly choose the node closest to the source node and update the distances of other nodes using this node as an intermediary. Dijkstra's algorithm requires that the edge weights in the graph are non-negative.
*/
/**
* BellmanFord time:O(VE) space:O(V)
* one to rest pairs
@ -842,7 +848,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
* `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;
@ -874,8 +880,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
}
}
}
return {costs, predecessor};
return { costs, predecessor };
}
/**
@ -953,7 +958,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
const curFromMap = dfnMap.get(cur);
if (childLow !== undefined && curFromMap !== undefined) {
if (needArticulationPoints) {
if ((cur === root && childCount >= 2) || ((cur !== root) && (childLow >= curFromMap))) {
if ((cur === root && childCount >= 2) || (cur !== root && childLow >= curFromMap)) {
// todo not ensure the logic if (cur === root && childCount >= 2 || ((cur !== root) && (childLow >= curFromMap))) {
articulationPoints.push(cur);
}
@ -970,7 +975,6 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
}
}
}
};
dfs(root, null);
@ -1007,7 +1011,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any> = AbstractVert
});
}
return {dfnMap, lowMap, bridges, articulationPoints, SCCs, cycles};
return { dfnMap, lowMap, bridges, articulationPoints, SCCs, cycles };
}
protected abstract _addEdgeOnly(edge: E): boolean;

View file

@ -5,10 +5,10 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import {arrayRemove} from '../../utils';
import {AbstractEdge, AbstractGraph, AbstractVertex} from './abstract-graph';
import type {TopologicalStatus, VertexId} from '../../types';
import {IDirectedGraph} from '../../interfaces';
import { arrayRemove } from '../../utils';
import { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';
import type { TopologicalStatus, VertexId } from '../../types';
import { IDirectedGraph } from '../../interfaces';
export class DirectedVertex<T = number> extends AbstractVertex<T> {
/**
@ -24,7 +24,6 @@ export class DirectedVertex<T = number> extends AbstractVertex<T> {
}
export class DirectedEdge<T = number> extends AbstractEdge<T> {
/**
* The constructor function initializes the source and destination vertices of an edge, along with an optional weight
* and value.
@ -63,8 +62,10 @@ export class DirectedEdge<T = number> extends AbstractEdge<T> {
}
}
export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E extends DirectedEdge<any> = DirectedEdge> extends AbstractGraph<V, E> implements IDirectedGraph<V, E> {
export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E extends DirectedEdge<any> = DirectedEdge>
extends AbstractGraph<V, E>
implements IDirectedGraph<V, E>
{
/**
* The constructor function initializes an instance of a class.
*/
@ -107,7 +108,6 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
* This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden.
*/
/**
* The function creates a directed edge between two vertices with an optional weight and value.
* @param {VertexId} src - The source vertex ID of the edge. It represents the starting point of the edge.
@ -155,7 +155,6 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
* @returns the removed edge (E) if it exists, or null if either the source or destination vertex does not exist.
*/
removeEdgeSrcToDest(srcOrId: V | VertexId, destOrId: V | VertexId): E | null {
const src: V | null = this._getVertex(srcOrId);
const dest: V | null = this._getVertex(destOrId);
let removed: E | null = null;
@ -195,7 +194,6 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
if (destInEdges && destInEdges.length > 0) {
removed = arrayRemove(destInEdges, (edge: E) => edge.dest === dest.id)[0];
}
}
return removed;
@ -232,7 +230,7 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
incomingEdgesOf(vertexOrId: V | VertexId): E[] {
const target = this._getVertex(vertexOrId);
if (target) {
return this.inEdgeMap.get(target) || []
return this.inEdgeMap.get(target) || [];
}
return [];
}
@ -368,7 +366,7 @@ export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E ext
if (hasCycle) return null;
if (propertyName === 'id') sorted = sorted.map(vertex => vertex instanceof DirectedVertex ? vertex.id : vertex);
if (propertyName === 'id') sorted = sorted.map(vertex => (vertex instanceof DirectedVertex ? vertex.id : vertex));
return sorted.reverse();
}

View file

@ -1,5 +1,5 @@
import {MapGraphCoordinate, VertexId} from '../../types';
import {DirectedEdge, DirectedGraph, DirectedVertex} from './directed-graph';
import { MapGraphCoordinate, VertexId } from '../../types';
import { DirectedEdge, DirectedGraph, DirectedVertex } from './directed-graph';
export class MapVertex<T = any> extends DirectedVertex<T> {
/**
@ -57,9 +57,10 @@ export class MapEdge<T = any> extends DirectedEdge<T> {
}
}
export class MapGraph<V extends MapVertex<V['val']> = MapVertex, E extends MapEdge = MapEdge> extends DirectedGraph<V, E> {
export class MapGraph<V extends MapVertex<V['val']> = MapVertex, E extends MapEdge = MapEdge> extends DirectedGraph<
V,
E
> {
/**
* The constructor function initializes the origin and bottomRight properties of a MapGraphCoordinate object.
* @param {MapGraphCoordinate} origin - The `origin` parameter is a `MapGraphCoordinate` object that represents the

View file

@ -5,10 +5,10 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import {arrayRemove} from '../../utils';
import {AbstractEdge, AbstractGraph, AbstractVertex} from './abstract-graph';
import type {VertexId} from '../../types';
import {IUNDirectedGraph} from '../../interfaces';
import { arrayRemove } from '../../utils';
import { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';
import type { VertexId } from '../../types';
import { IUNDirectedGraph } from '../../interfaces';
export class UndirectedVertex<T = number> extends AbstractVertex<T> {
/**
@ -50,8 +50,13 @@ export class UndirectedEdge<T = number> extends AbstractEdge<T> {
}
}
export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex, E extends UndirectedEdge<any> = UndirectedEdge> extends AbstractGraph<V, E> implements IUNDirectedGraph<V, E> {
export class UndirectedGraph<
V extends UndirectedVertex<any> = UndirectedVertex,
E extends UndirectedEdge<any> = UndirectedEdge
>
extends AbstractGraph<V, E>
implements IUNDirectedGraph<V, E>
{
/**
* The constructor initializes a new Map object to store edges.
*/
@ -124,7 +129,6 @@ export class UndirectedGraph<V extends UndirectedVertex<any> = UndirectedVertex,
* @returns the removed edge (E) if it exists, or null if either of the vertices (V) does not exist.
*/
removeEdgeBetween(v1: V | VertexId, v2: V | VertexId): E | null {
const vertex1: V | null = this._getVertex(v1);
const vertex2: V | null = this._getVertex(v2);

View file

@ -1,3 +1 @@
export class HashTable {
}
export class HashTable {}

View file

@ -1,3 +1 @@
export class Pair {
}
export class Pair {}

View file

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

View file

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

View file

@ -5,11 +5,10 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import {PriorityQueue} from '../priority-queue';
import type {HeapOptions} from '../../types';
import { PriorityQueue } from '../priority-queue';
import type { HeapOptions } from '../../types';
export class HeapItem<T = number> {
/**
* The constructor function initializes an instance of a class with a priority and a value.
* @param {number} priority - The `priority` parameter is a number that represents the priority of the value. It is
@ -51,13 +50,13 @@ export abstract class Heap<T = number> {
*/
protected constructor(options?: HeapOptions<T>) {
if (options) {
const {priorityExtractor} = options;
const { priorityExtractor } = options;
if (priorityExtractor !== undefined && typeof priorityExtractor !== 'function') {
throw new Error('.constructor expects a valid priority function');
}
this._priorityExtractor = priorityExtractor || ((el) => +el);
this._priorityExtractor = priorityExtractor || (el => +el);
} else {
this._priorityExtractor = (el) => +el;
this._priorityExtractor = el => +el;
}
}
@ -128,8 +127,8 @@ export abstract class Heap<T = number> {
* @returns The `add` method returns the instance of the `Heap` class.
* @throws {Error} if priority is not a valid number
*/
add(priority: number, val?: T,): Heap<T> {
val = (val === undefined) ? priority as unknown as T : val;
add(priority: number, val?: T): Heap<T> {
val = val === undefined ? (priority as unknown as T) : val;
this._pq.add(new HeapItem<T>(priority, val));
return this;
@ -162,9 +161,11 @@ export abstract class Heap<T = number> {
if (node instanceof HeapItem) {
return this.pq.getNodes().includes(node);
} else {
return this.pq.getNodes().findIndex(item => {
return item.val === node;
}) !== -1;
return (
this.pq.getNodes().findIndex(item => {
return item.val === node;
}) !== -1
);
}
}

View file

@ -6,9 +6,9 @@
* @license MIT License
*/
import {Heap, HeapItem} from './heap';
import {PriorityQueue} from '../priority-queue';
import type {HeapOptions} from '../../types';
import { Heap, HeapItem } from './heap';
import { PriorityQueue } from '../priority-queue';
import type { HeapOptions } from '../../types';
/**
* @class MaxHeap

View file

@ -6,9 +6,9 @@
* @license MIT License
*/
import {Heap, HeapItem} from './heap';
import {PriorityQueue} from '../priority-queue';
import type {HeapOptions} from '../../types';
import { Heap, HeapItem } from './heap';
import { PriorityQueue } from '../priority-queue';
import type { HeapOptions } from '../../types';
/**
* @class MinHeap
@ -30,5 +30,3 @@ export class MinHeap<T = number> extends Heap<T> {
});
}
}

View file

@ -1,11 +1,11 @@
export * from './hash';
export * from './linked-list';
export * from './stack';
export * from './queue';
export * from './graph';
export * from './binary-tree';
export * from './tree';
export * from './heap';
export * from './priority-queue';
export * from './matrix';
export * from './trie';
export * from './hash';
export * from './linked-list';
export * from './stack';
export * from './queue';
export * from './graph';
export * from './binary-tree';
export * from './tree';
export * from './heap';
export * from './priority-queue';
export * from './matrix';
export * from './trie';

View file

@ -6,7 +6,6 @@
* @license MIT License
*/
export class DoublyLinkedListNode<T = number> {
/**
* The constructor function initializes the value, next, and previous properties of an object.
* @param {T} val - The "val" parameter is the value that will be stored in the node. It can be of any data type, as it
@ -50,7 +49,6 @@ export class DoublyLinkedListNode<T = number> {
}
export class DoublyLinkedList<T = any> {
/**
* The constructor initializes the linked list with an empty head, tail, and length.
*/
@ -573,4 +571,3 @@ export class DoublyLinkedList<T = any> {
return false;
}
}

View file

@ -6,7 +6,6 @@
* @license MIT License
*/
export class SinglyLinkedListNode<T = number> {
/**
* The constructor function initializes an instance of a class with a given value and sets the next property to null.
* @param {T} val - The "val" parameter is of type T, which means it can be any data type. It represents the value that
@ -39,7 +38,6 @@ export class SinglyLinkedListNode<T = number> {
}
export class SinglyLinkedList<T = any> {
/**
* The constructor initializes the linked list with an empty head, tail, and length.
*/
@ -233,7 +231,8 @@ export class SinglyLinkedList<T = any> {
} else {
value = valueOrNode;
}
let current = this.head, prev = null;
let current = this.head,
prev = null;
while (current) {
if (current.val === value) {
@ -398,8 +397,8 @@ export class SinglyLinkedList<T = any> {
return null;
}
insertBefore(existingValue: T, newValue: T): boolean
insertBefore(existingValue: SinglyLinkedListNode<T>, newValue: T): boolean
insertBefore(existingValue: T, newValue: T): boolean;
insertBefore(existingValue: SinglyLinkedListNode<T>, newValue: T): boolean;
/**
* The `insertBefore` function inserts a new value before an existing value in a singly linked list.
@ -438,8 +437,8 @@ export class SinglyLinkedList<T = any> {
return false;
}
insertAfter(existingValueOrNode: T, newValue: T): boolean
insertAfter(existingValueOrNode: SinglyLinkedListNode<T>, newValue: T): boolean
insertAfter(existingValueOrNode: T, newValue: T): boolean;
insertAfter(existingValueOrNode: SinglyLinkedListNode<T>, newValue: T): boolean;
/**
* The `insertAfter` function inserts a new node with a given value after an existing node in a singly linked list.
@ -491,8 +490,7 @@ export class SinglyLinkedList<T = any> {
return count;
}
* [Symbol.iterator]() {
*[Symbol.iterator]() {
let current = this.head;
while (current) {

View file

@ -1,3 +1 @@
export class SkipLinkedList {
}
export class SkipLinkedList {}

View file

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

View file

@ -5,7 +5,7 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import Vector2D from './vector2d'
import Vector2D from './vector2d';
export class Matrix2D {
private readonly _matrix: number[][];
@ -18,14 +18,14 @@ export class Matrix2D {
*/
constructor(value?: number[][] | Vector2D) {
if (typeof value === 'undefined') {
this._matrix = Matrix2D.identity
this._matrix = Matrix2D.identity;
} else if (value instanceof Vector2D) {
this._matrix = Matrix2D.identity
this._matrix[0][0] = value.x
this._matrix[1][0] = value.y
this._matrix[2][0] = value.w
this._matrix = Matrix2D.identity;
this._matrix[0][0] = value.x;
this._matrix[1][0] = value.y;
this._matrix[2][0] = value.w;
} else {
this._matrix = value
this._matrix = value;
}
}
@ -34,7 +34,7 @@ export class Matrix2D {
* @returns An empty 2-dimensional array with 3 empty arrays inside.
*/
static get empty(): number[][] {
return [[], [], []]
return [[], [], []];
}
/**
@ -45,7 +45,8 @@ export class Matrix2D {
return [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
[0, 0, 1]
];
}
/**
@ -54,7 +55,7 @@ export class Matrix2D {
* array of numbers.
*/
get m(): number[][] {
return this._matrix
return this._matrix;
}
/**
@ -64,7 +65,7 @@ export class Matrix2D {
* the first column of the matrix.
*/
get toVector(): Vector2D {
return new Vector2D(this._matrix[0][0], this._matrix[1][0])
return new Vector2D(this._matrix[0][0], this._matrix[1][0]);
}
/**
@ -74,10 +75,10 @@ export class Matrix2D {
* @returns a new instance of the Matrix2D class, which is created using the result array.
*/
static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
const result = Matrix2D.empty
const result = Matrix2D.empty;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
result[i][j] = matrix1.m[i][j] + matrix2.m[i][j]
result[i][j] = matrix1.m[i][j] + matrix2.m[i][j];
}
}
return new Matrix2D(result);
@ -91,10 +92,10 @@ export class Matrix2D {
* @returns a new instance of the Matrix2D class, which is created using the result array.
*/
static subtract(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
const result = Matrix2D.empty
const result = Matrix2D.empty;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
result[i][j] = matrix1.m[i][j] - matrix2.m[i][j]
result[i][j] = matrix1.m[i][j] - matrix2.m[i][j];
}
}
return new Matrix2D(result);
@ -107,7 +108,7 @@ export class Matrix2D {
* @returns a new instance of the Matrix2D class, created using the result array.
*/
static multiply(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
const result = Matrix2D.empty
const result = Matrix2D.empty;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
result[i][j] = 0;
@ -127,10 +128,10 @@ export class Matrix2D {
* @returns a new instance of the Matrix2D class, which is created using the result array.
*/
static multiplyByValue(matrix: Matrix2D, value: number): Matrix2D {
const result = Matrix2D.empty
const result = Matrix2D.empty;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
result[i][j] = matrix.m[i][j] * value
result[i][j] = matrix.m[i][j] * value;
}
}
return new Matrix2D(result);
@ -143,7 +144,7 @@ export class Matrix2D {
* @returns a Vector2D.
*/
static multiplyByVector(matrix: Matrix2D, vector: Vector2D): Vector2D {
return Matrix2D.multiply(matrix, new Matrix2D(vector)).toVector
return Matrix2D.multiply(matrix, new Matrix2D(vector)).toVector;
}
/**
@ -155,15 +156,16 @@ export class Matrix2D {
* @returns a Matrix2D object.
*/
static view(width: number, height: number): Matrix2D {
const scaleStep = 1 // Scale every vector * scaleStep
const centerX = width / 2
const centerY = height / 2
const flipX = Math.cos(Math.PI) // rotate 180deg / 3.14radian around X-axis
const scaleStep = 1; // Scale every vector * scaleStep
const centerX = width / 2;
const centerY = height / 2;
const flipX = Math.cos(Math.PI); // rotate 180deg / 3.14radian around X-axis
return new Matrix2D([
[scaleStep, 0, centerX],
[0, flipX * scaleStep, centerY],
[0, 0, 1]])
[0, 0, 1]
]);
}
/**
@ -173,7 +175,7 @@ export class Matrix2D {
* @returns the result of multiplying a new instance of Matrix2D by the given factor.
*/
static scale(factor: number) {
return Matrix2D.multiplyByValue(new Matrix2D(), factor)
return Matrix2D.multiplyByValue(new Matrix2D(), factor);
}
/**
@ -182,13 +184,14 @@ export class Matrix2D {
* @returns The code is returning a new instance of a Matrix2D object.
*/
static rotate(radians: number) {
const cos = Math.cos(radians)
const sin = Math.sin(radians)
const cos = Math.cos(radians);
const sin = Math.sin(radians);
return new Matrix2D([
[cos, -sin, 0],
[sin, cos, 0],
[0, 0, 1]])
[0, 0, 1]
]);
}
/**
@ -201,8 +204,9 @@ export class Matrix2D {
return new Matrix2D([
[1, 0, vector.x],
[0, 1, vector.y],
[0, 0, vector.w]])
[0, 0, vector.w]
]);
}
}
export default Matrix2D
export default Matrix2D;

View file

@ -5,7 +5,7 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type {Direction, NavigatorParams, Turning} from '../../types';
import type { Direction, NavigatorParams, Turning } from '../../types';
export class Character {
direction: Direction;
@ -37,7 +37,7 @@ export class Navigator<T = number> {
* in the matrix.
* @param - - `matrix`: a 2D array representing the grid or map
*/
constructor({matrix, turning, onMove, init: {cur, charDir, VISITED}}: NavigatorParams<T>) {
constructor({ matrix, turning, onMove, init: { cur, charDir, VISITED } }: NavigatorParams<T>) {
this._matrix = matrix;
this._cur = cur;
this._character = new Character(charDir, turning);
@ -53,7 +53,7 @@ export class Navigator<T = number> {
*/
start() {
while (this.check(this._character.direction) || this.check(this._character.turn().direction)) {
const {direction} = this._character;
const { direction } = this._character;
if (this.check(direction)) {
this.move(direction);
} else if (this.check(this._character.turn().direction)) {
@ -119,4 +119,3 @@ export class Navigator<T = number> {
this.onMove && this.onMove(this._cur);
}
}

View file

@ -10,15 +10,14 @@ 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.
* @returns A boolean value indicating whether both the x and y properties of the object are equal to 0.
*/
get isZero(): boolean {
return this.x === 0 && this.y === 0
return this.x === 0 && this.y === 0;
}
/**
@ -26,7 +25,7 @@ export class Vector2D {
* @returns The length of a vector, calculated using the Pythagorean theorem.
*/
get length(): number {
return Math.sqrt((this.x * this.x) + (this.y * this.y))
return Math.sqrt(this.x * this.x + this.y * this.y);
}
/**
@ -34,7 +33,7 @@ export class Vector2D {
* @returns The method is returning the sum of the squares of the x and y values.
*/
get lengthSq(): number {
return (this.x * this.x) + (this.y * this.y)
return this.x * this.x + this.y * this.y;
}
/**
@ -43,7 +42,7 @@ export class Vector2D {
* whole number.
*/
get rounded(): Vector2D {
return new Vector2D(Math.round(this.x), Math.round(this.y))
return new Vector2D(Math.round(this.x), Math.round(this.y));
}
/**
@ -57,7 +56,7 @@ export class Vector2D {
* vectors added together.
*/
static add(vector1: Vector2D, vector2: Vector2D): Vector2D {
return new Vector2D(vector1.x + vector2.x, vector1.y + vector2.y)
return new Vector2D(vector1.x + vector2.x, vector1.y + vector2.y);
}
/**
@ -72,7 +71,7 @@ export class Vector2D {
* vector2.
*/
static subtract(vector1: Vector2D, vector2: Vector2D): Vector2D {
return new Vector2D(vector1.x - vector2.x, vector1.y - vector2.y)
return new Vector2D(vector1.x - vector2.x, vector1.y - vector2.y);
}
/**
@ -85,7 +84,7 @@ export class Vector2D {
* @returns A new Vector2D object with the x and y values subtracted by the given value.
*/
static subtractValue(vector: Vector2D, value: number): Vector2D {
return new Vector2D(vector.x - value, vector.y - value)
return new Vector2D(vector.x - value, vector.y - value);
}
/**
@ -97,7 +96,7 @@ export class Vector2D {
* @returns A new Vector2D object with the x and y values multiplied by the given value.
*/
static multiply(vector: Vector2D, value: number): Vector2D {
return new Vector2D(vector.x * value, vector.y * value)
return new Vector2D(vector.x * value, vector.y * value);
}
/**
@ -109,7 +108,7 @@ export class Vector2D {
* @returns A new instance of the Vector2D class with the x and y values divided by the given value.
*/
static divide(vector: Vector2D, value: number): Vector2D {
return new Vector2D(vector.x / value, vector.y / value)
return new Vector2D(vector.x / value, vector.y / value);
}
/**
@ -120,7 +119,7 @@ export class Vector2D {
* @returns a boolean value, which indicates whether the two input vectors are equal or not.
*/
static equals(vector1: Vector2D, vector2: Vector2D): boolean {
return vector1.x === vector2.x && vector1.y === vector2.y
return vector1.x === vector2.x && vector1.y === vector2.y;
}
/**
@ -134,12 +133,12 @@ export class Vector2D {
* @returns a boolean value.
*/
static equalsRounded(vector1: Vector2D, vector2: Vector2D, roundingFactor = 12): boolean {
const vector = Vector2D.abs(Vector2D.subtract(vector1, vector2))
const vector = Vector2D.abs(Vector2D.subtract(vector1, vector2));
if (vector.x < roundingFactor && vector.y < roundingFactor) {
return true
return true;
}
return false
return false;
}
/**
@ -149,12 +148,13 @@ export class Vector2D {
* original vector.
*/
static normalize(vector: Vector2D): Vector2D {
const length = vector.length
if (length > 2.220446049250313e-16) { // Epsilon
return Vector2D.divide(vector, length)
const length = vector.length;
if (length > 2.220446049250313e-16) {
// Epsilon
return Vector2D.divide(vector, length);
}
return vector
return vector;
}
/**
@ -167,10 +167,10 @@ export class Vector2D {
*/
static truncate(vector: Vector2D, max: number): Vector2D {
if (vector.length > max) {
return Vector2D.multiply(Vector2D.normalize(vector), max)
return Vector2D.multiply(Vector2D.normalize(vector), max);
}
return vector
return vector;
}
/**
@ -179,7 +179,7 @@ export class Vector2D {
* @returns A new Vector2D object is being returned.
*/
static perp(vector: Vector2D): Vector2D {
return new Vector2D(-vector.y, vector.x)
return new Vector2D(-vector.y, vector.x);
}
/**
@ -189,7 +189,7 @@ export class Vector2D {
* @returns A new Vector2D object with the negated x and y values of the input vector. Returns the vector that is the reverse of this vector
*/
static reverse(vector: Vector2D): Vector2D {
return new Vector2D(-vector.x, -vector.y)
return new Vector2D(-vector.x, -vector.y);
}
/**
@ -201,7 +201,7 @@ export class Vector2D {
* input vector.
*/
static abs(vector: Vector2D): Vector2D {
return new Vector2D(Math.abs(vector.x), Math.abs(vector.y))
return new Vector2D(Math.abs(vector.x), Math.abs(vector.y));
}
/**
@ -212,7 +212,7 @@ export class Vector2D {
* @returns The dot product of the two input vectors.
*/
static dot(vector1: Vector2D, vector2: Vector2D): number {
return (vector1.x * vector2.x) + (vector1.y * vector2.y)
return vector1.x * vector2.x + vector1.y * vector2.y;
}
// /**
@ -242,9 +242,9 @@ export class Vector2D {
* @returns The distance between vector1 and vector2.
*/
static distance(vector1: Vector2D, vector2: Vector2D): number {
const ySeparation = vector2.y - vector1.y
const xSeparation = vector2.x - vector1.x
return Math.sqrt((ySeparation * ySeparation) + (xSeparation * xSeparation))
const ySeparation = vector2.y - vector1.y;
const xSeparation = vector2.x - vector1.x;
return Math.sqrt(ySeparation * ySeparation + xSeparation * xSeparation);
}
/**
@ -256,9 +256,9 @@ export class Vector2D {
* @returns the square of the distance between the two input vectors.
*/
static distanceSq(vector1: Vector2D, vector2: Vector2D): number {
const ySeparation = vector2.y - vector1.y
const xSeparation = vector2.x - vector1.x
return (ySeparation * ySeparation) + (xSeparation * xSeparation)
const ySeparation = vector2.y - vector1.y;
const xSeparation = vector2.x - vector1.x;
return ySeparation * ySeparation + xSeparation * xSeparation;
}
/**
@ -272,10 +272,10 @@ export class Vector2D {
*/
static sign(vector1: Vector2D, vector2: Vector2D): number {
if (vector1.y * vector2.x > vector1.x * vector2.y) {
return -1
return -1;
}
return 1
return 1;
}
/**
@ -286,9 +286,9 @@ export class Vector2D {
* @returns the angle between the given vector and the vector (0, -1) in radians.Returns the angle between origin and the given vector in radians
*/
static angle(vector: Vector2D): number {
const origin = new Vector2D(0, -1)
const radian = Math.acos(Vector2D.dot(vector, origin) / (vector.length * origin.length))
return Vector2D.sign(vector, origin) === 1 ? ((Math.PI * 2) - radian) : radian
const origin = new Vector2D(0, -1);
const radian = Math.acos(Vector2D.dot(vector, origin) / (vector.length * origin.length));
return Vector2D.sign(vector, origin) === 1 ? Math.PI * 2 - radian : radian;
}
/**
@ -299,18 +299,18 @@ export class Vector2D {
* @returns a new instance of the Vector2D class with random x and y values.
*/
static random(maxX: number, maxY: number): Vector2D {
const randX = Math.floor(Math.random() * maxX - (maxX / 2))
const randY = Math.floor(Math.random() * maxY - (maxY / 2))
return new Vector2D(randX, randY)
const randX = Math.floor(Math.random() * maxX - maxX / 2);
const randY = Math.floor(Math.random() * maxY - maxY / 2);
return new Vector2D(randX, randY);
}
/**
* The function sets the values of x and y to zero.
*/
zero(): void {
this.x = 0
this.y = 0
this.x = 0;
this.y = 0;
}
}
export default Vector2D
export default Vector2D;

View file

@ -5,12 +5,12 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import {PriorityQueue} from './priority-queue';
import type {PriorityQueueOptions, SpecifyOptional} from '../../types';
import { PriorityQueue } from './priority-queue';
import type { PriorityQueueOptions, SpecifyOptional } from '../../types';
export class MaxPriorityQueue<T = number> extends PriorityQueue<T> {
constructor(options?: Omit<PriorityQueueOptions<number>, 'comparator'>)
constructor(options: PriorityQueueOptions<T>)
constructor(options?: Omit<PriorityQueueOptions<number>, 'comparator'>);
constructor(options: PriorityQueueOptions<T>);
/**
* The constructor initializes a priority queue with an optional comparator function.
@ -20,15 +20,18 @@ export class MaxPriorityQueue<T = number> extends PriorityQueue<T> {
constructor(options?: SpecifyOptional<PriorityQueueOptions<T>, 'comparator'>) {
super({
...options,
comparator: options?.comparator ? options.comparator : (a: T, b: T) => {
const aKey = a as unknown as number, bKey = b as unknown as number;
return bKey - aKey;
}
comparator: options?.comparator
? options.comparator
: (a: T, b: T) => {
const aKey = a as unknown as number,
bKey = b as unknown as number;
return bKey - aKey;
}
});
}
static override heapify<T extends number>(options?: Omit<PriorityQueueOptions<T>, 'comparator'>): MaxPriorityQueue<T>
static override heapify<T>(options: PriorityQueueOptions<T>): MaxPriorityQueue<T>
static override heapify<T extends number>(options?: Omit<PriorityQueueOptions<T>, 'comparator'>): MaxPriorityQueue<T>;
static override heapify<T>(options: PriorityQueueOptions<T>): MaxPriorityQueue<T>;
/**
* The function `heapify` creates a max priority queue from the given options and returns it.
@ -39,10 +42,13 @@ export class MaxPriorityQueue<T = number> extends PriorityQueue<T> {
static override heapify<T>(options: PriorityQueueOptions<T>): MaxPriorityQueue<T> {
const maxPQ = new MaxPriorityQueue<T>({
...options,
comparator: options?.comparator ? options.comparator : (a: T, b: T) => {
const aKey = a as unknown as number, bKey = b as unknown as number;
return bKey - aKey;
}
comparator: options?.comparator
? options.comparator
: (a: T, b: T) => {
const aKey = a as unknown as number,
bKey = b as unknown as number;
return bKey - aKey;
}
});
maxPQ._fix();
return maxPQ;

View file

@ -5,12 +5,12 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import {PriorityQueue} from './priority-queue';
import type {PriorityQueueOptions, SpecifyOptional} from '../../types';
import { PriorityQueue } from './priority-queue';
import type { PriorityQueueOptions, SpecifyOptional } from '../../types';
export class MinPriorityQueue<T = number> extends PriorityQueue<T> {
constructor(options?: Omit<PriorityQueueOptions<number>, 'comparator'>)
constructor(options: PriorityQueueOptions<T>)
constructor(options?: Omit<PriorityQueueOptions<number>, 'comparator'>);
constructor(options: PriorityQueueOptions<T>);
/**
* The constructor initializes a priority queue with an optional comparator function.
@ -20,15 +20,18 @@ export class MinPriorityQueue<T = number> extends PriorityQueue<T> {
constructor(options?: SpecifyOptional<PriorityQueueOptions<T>, 'comparator'>) {
super({
...options,
comparator: options?.comparator ? options.comparator : (a: T, b: T) => {
const aKey = a as unknown as number, bKey = b as unknown as number;
return aKey - bKey;
}
comparator: options?.comparator
? options.comparator
: (a: T, b: T) => {
const aKey = a as unknown as number,
bKey = b as unknown as number;
return aKey - bKey;
}
});
}
static override heapify<T extends number>(options?: Omit<PriorityQueueOptions<T>, 'comparator'>): MinPriorityQueue<T>
static override heapify<T>(options: PriorityQueueOptions<T>): MinPriorityQueue<T>
static override heapify<T extends number>(options?: Omit<PriorityQueueOptions<T>, 'comparator'>): MinPriorityQueue<T>;
static override heapify<T>(options: PriorityQueueOptions<T>): MinPriorityQueue<T>;
/**
* The function `heapify` creates a new MinPriorityQueue instance and sets the comparator function based on the options
@ -40,10 +43,13 @@ export class MinPriorityQueue<T = number> extends PriorityQueue<T> {
static override heapify<T>(options: PriorityQueueOptions<T>): MinPriorityQueue<T> {
const minPQ = new MinPriorityQueue<T>({
...options,
comparator: options?.comparator ? options.comparator : (a: T, b: T) => {
const aKey = a as unknown as number, bKey = b as unknown as number;
return aKey - bKey;
}
comparator: options?.comparator
? options.comparator
: (a: T, b: T) => {
const aKey = a as unknown as number,
bKey = b as unknown as number;
return aKey - bKey;
}
});
minPQ._fix();
return minPQ;

View file

@ -5,7 +5,7 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type {PriorityQueueComparator, PriorityQueueDFSOrderPattern, PriorityQueueOptions} from '../../types';
import type { PriorityQueueComparator, PriorityQueueDFSOrderPattern, PriorityQueueOptions } from '../../types';
export class PriorityQueue<T = number> {
/**
@ -14,7 +14,7 @@ export class PriorityQueue<T = number> {
* @param options - The `options` parameter is an object that contains the following properties:
*/
constructor(options: PriorityQueueOptions<T>) {
const {nodes, comparator, isFix = true} = options;
const { nodes, comparator, isFix = true } = options;
this._comparator = comparator;
if (nodes && Array.isArray(nodes) && nodes.length > 0) {
@ -55,7 +55,7 @@ export class PriorityQueue<T = number> {
* @returns the result of calling the `isValid()` method on a new instance of the `PriorityQueue` class.
*/
static isPriorityQueueified<T>(options: Omit<PriorityQueueOptions<T>, 'isFix'>) {
return new PriorityQueue({...options, isFix: false}).isValid();
return new PriorityQueue({ ...options, isFix: false }).isValid();
}
/**
@ -151,7 +151,10 @@ export class PriorityQueue<T = number> {
* `comparator` properties as the original instance.
*/
clone(): PriorityQueue<T> {
return new PriorityQueue<T>({nodes: this.nodes, comparator: this._comparator});
return new PriorityQueue<T>({
nodes: this.nodes,
comparator: this._comparator
});
}
// --- start additional methods ---
@ -232,7 +235,8 @@ export class PriorityQueue<T = number> {
}
protected readonly _comparator: PriorityQueueComparator<T> = (a: T, b: T) => {
const aKey = a as unknown as number, bKey = b as unknown as number;
const aKey = a as unknown as number,
bKey = b as unknown as number;
return aKey - bKey;
};
@ -284,7 +288,7 @@ export class PriorityQueue<T = number> {
* @returns the left child of a given parent node in a binary tree.
*/
protected _getLeft(parent: number): number {
return (2 * parent) + 1;
return 2 * parent + 1;
}
/**
@ -293,7 +297,7 @@ export class PriorityQueue<T = number> {
* @returns the right child of a given parent node in a binary tree.
*/
protected _getRight(parent: number): number {
return (2 * parent) + 2;
return 2 * parent + 2;
}
/**
@ -304,7 +308,8 @@ export class PriorityQueue<T = number> {
*/
protected _getComparedChild(parent: number) {
let min = parent;
const left = this._getLeft(parent), right = this._getRight(parent);
const left = this._getLeft(parent),
right = this._getRight(parent);
if (left < this.size && this._compare(min, left)) {
min = left;

View file

@ -5,13 +5,11 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import {DoublyLinkedList} from '../linked-list';
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<T> extends DoublyLinkedList<T> {
}
export class Deque<T> extends DoublyLinkedList<T> {}
// O(1) time complexity of obtaining the value
// O(n) time complexity of adding at the beginning and the end
@ -261,7 +259,7 @@ export class ArrayDeque<T> {
* @returns The value that is being set at the specified index in the `_nodes` array.
*/
set(index: number, value: T) {
return this._nodes[index] = value;
return (this._nodes[index] = value);
}
/**

View file

@ -3,10 +3,9 @@
* @copyright Tyler Zeng <zrwusa@gmail.com>
* @class
*/
import {SinglyLinkedList} from '../linked-list';
import { SinglyLinkedList } from '../linked-list';
export class LinkedListQueue<T = any> extends SinglyLinkedList<T> {
/**
* The enqueue function adds a value to the end of an array.
* @param {T} value - The value parameter represents the value that you want to add to the queue.
@ -33,7 +32,6 @@ export class LinkedListQueue<T = any> extends SinglyLinkedList<T> {
}
export class Queue<T = any> {
/**
* The constructor initializes an instance of a class with an optional array of elements and sets the offset to 0.
* @param {T[]} [elements] - The `elements` parameter is an optional array of elements of type `T`. If provided, it
@ -185,7 +183,7 @@ export class Queue<T = any> {
return new Queue(this.nodes.slice(this.offset));
}
* [Symbol.iterator]() {
*[Symbol.iterator]() {
for (const item of this.nodes) {
yield item;
}

View file

@ -1 +1 @@
export * from './tree';
export * from './tree';

View file

@ -35,7 +35,7 @@ export class TreeNode<T = any> {
this._children = value;
}
addChildren(children: TreeNode<T> | TreeNode<T> []) {
addChildren(children: TreeNode<T> | TreeNode<T>[]) {
if (!this.children) {
this.children = [];
}
@ -55,7 +55,7 @@ export class TreeNode<T = any> {
if (level > maxDepth) {
maxDepth = level;
}
const {children} = node;
const { children } = node;
if (children) {
for (let i = 0, len = children.length; i < len; i++) {
bfs(children[i], level + 1);

View file

@ -6,7 +6,6 @@
* @license MIT License
*/
export class TrieNode {
constructor(v: string) {
this._val = v;
this._isEnd = false;
@ -42,7 +41,6 @@ export class TrieNode {
set isEnd(v: boolean) {
this._isEnd = v;
}
}
export class Trie {
@ -115,7 +113,7 @@ export class Trie {
return false;
}
return false;
}
};
dfs(this.root, 0);
return isDeleted;
@ -166,7 +164,7 @@ export class Trie {
if (cur.isEnd) return;
if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);
else return;
}
};
dfs(this._root);
return commonPre === input;
}
@ -184,7 +182,7 @@ export class Trie {
if (cur.isEnd) return;
if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);
else return;
}
};
dfs(this._root);
return commonPre;
}

View file

@ -1,4 +1,4 @@
export * from './data-structures';
export * from './utils';
export * from './interfaces';
export * from './types';
export * from './types';

View file

@ -9,107 +9,106 @@ import {
LoopType,
NodeOrPropertyName
} from '../types';
import {AbstractBinaryTreeNode} from '../data-structures';
import { AbstractBinaryTreeNode } from '../data-structures';
export interface IAbstractBinaryTreeNode<T, NEIGHBOR extends IAbstractBinaryTreeNode<T, NEIGHBOR>> {
get id(): BinaryTreeNodeId;
get id(): BinaryTreeNodeId
set id(v: BinaryTreeNodeId);
set id(v: BinaryTreeNodeId)
get val(): T | undefined;
get val(): T | undefined
set val(v: T | undefined);
set val(v: T | undefined)
get left(): NEIGHBOR | null | undefined;
get left(): NEIGHBOR | null | undefined
set left(v: NEIGHBOR | null | undefined);
set left(v: NEIGHBOR | null | undefined)
get right(): NEIGHBOR | null | undefined;
get right(): NEIGHBOR | null | undefined
set right(v: NEIGHBOR | null | undefined);
set right(v: NEIGHBOR | null | undefined)
get parent(): NEIGHBOR | null | undefined;
get parent(): NEIGHBOR | null | undefined
set parent(v: NEIGHBOR | null | undefined);
set parent(v: NEIGHBOR | null | undefined)
get familyPosition(): FamilyPosition;
get familyPosition(): FamilyPosition
get height(): number;
get height(): number
set height(v: number)
set height(v: number);
}
export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'], N>> {
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null;
get loopType(): LoopType
get loopType(): LoopType;
get visitedId(): BinaryTreeNodeId[]
get visitedId(): BinaryTreeNodeId[];
get visitedVal(): Array<N['val']>
get visitedVal(): Array<N['val']>;
get visitedNode(): N[]
get visitedNode(): N[];
get visitedLeftSum(): number[]
get visitedLeftSum(): number[];
get root(): N | null
get root(): N | null;
get size(): number
get size(): number;
swapLocation(srcNode: N, destNode: N): N
swapLocation(srcNode: N, destNode: N): N;
clear(): void
clear(): void;
isEmpty(): boolean
isEmpty(): boolean;
add(id: BinaryTreeNodeId | N, val?: N['val']): N | null | undefined
add(id: BinaryTreeNodeId | N, val?: N['val']): N | null | undefined;
addMany(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N['val'][]): (N | null | undefined)[]
addMany(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N['val'][]): (N | null | undefined)[];
fill(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N[] | Array<N['val']>): boolean
fill(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N[] | Array<N['val']>): boolean;
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[]
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[];
getDepth(node: N): number
getDepth(node: N): number;
getHeight(beginRoot?: N | null): number
getHeight(beginRoot?: N | null): number;
getMinHeight(beginRoot?: N | null): number
getMinHeight(beginRoot?: N | null): number;
isPerfectlyBalanced(beginRoot?: N | null): boolean
isPerfectlyBalanced(beginRoot?: N | null): boolean;
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean): N[]
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName?: BinaryTreeNodePropertyName, onlyOne?: boolean): N[];
has(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): boolean
has(nodeProperty: BinaryTreeNodeId | N, propertyName?: BinaryTreeNodePropertyName): boolean;
get(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): N | null
get(nodeProperty: BinaryTreeNodeId | N, propertyName?: BinaryTreeNodePropertyName): N | null;
getPathToRoot(node: N): N[]
getPathToRoot(node: N): N[];
getLeftMost(): N | null;
getLeftMost(node: N): N;
getLeftMost(node?: N | null): N | null
getLeftMost(node?: N | null): N | null;
getRightMost(): N | null;
getRightMost(node: N): N;
getRightMost(node?: N | null): N | null
getRightMost(node?: N | null): N | null;
isSubtreeBST(node: N | null): boolean
isSubtreeBST(node: N | null): boolean;
isBST(): boolean
isBST(): boolean;
getSubTreeSize(subTreeRoot: N | null | undefined): number
getSubTreeSize(subTreeRoot: N | null | undefined): number;
// --- start additional methods ---
subTreeSum(subTreeRoot: N, propertyName ?: BinaryTreeNodePropertyName): number
subTreeSum(subTreeRoot: N, propertyName?: BinaryTreeNodePropertyName): number;
subTreeAdd(subTreeRoot: N, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean
subTreeAdd(subTreeRoot: N, delta: number, propertyName?: BinaryTreeNodePropertyName): boolean;
BFS(): BinaryTreeNodeId[];
@ -121,7 +120,7 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
BFS(nodeOrPropertyName: 'count'): number[];
BFS(nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
BFS(nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>;
DFS(): BinaryTreeNodeId[];
@ -133,7 +132,7 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
DFS(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'count'): number[];
DFS(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
DFS(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>;
DFSIterative(): BinaryTreeNodeId[];
@ -145,7 +144,10 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'count'): number[];
DFSIterative(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
DFSIterative(
pattern?: 'in' | 'pre' | 'post',
nodeOrPropertyName?: NodeOrPropertyName
): AbstractBinaryTreeNodeProperties<N>;
levelIterative(node: N | null): BinaryTreeNodeId[];
@ -157,7 +159,7 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
levelIterative(node: N | null, nodeOrPropertyName?: 'count'): number[];
levelIterative(node: N | null, nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
levelIterative(node: N | null, nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>;
listLevels(node: N | null): BinaryTreeNodeId[][];
@ -169,9 +171,9 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
listLevels(node: N | null, nodeOrPropertyName?: 'count'): number[][];
listLevels(node: N | null, nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperty<N>[][]
listLevels(node: N | null, nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperty<N>[][];
getPredecessor(node: N): N
getPredecessor(node: N): N;
morris(): BinaryTreeNodeId[];
@ -183,8 +185,7 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
morris(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'count'): number[];
morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>;
// --- end additional methods ---
}

View file

@ -1,7 +1,6 @@
import {VertexId} from '../types';
import { VertexId } from '../types';
export interface IAbstractGraph<V, E> {
hasVertex(vertexOrId: V | VertexId): boolean;
addVertex(id: VertexId, val?: V): boolean;

View file

@ -1,14 +1,13 @@
import {AVLTreeNode} from '../data-structures';
import {IBST, IBSTNode} from './bst';
import {BinaryTreeDeletedResult, BinaryTreeNodeId} from '../types';
import { AVLTreeNode } from '../data-structures';
import { IBST, IBSTNode } from './bst';
import { BinaryTreeDeletedResult, BinaryTreeNodeId } from '../types';
export type IAVLTreeNode<T, NEIGHBOR extends IAVLTreeNode<T, NEIGHBOR>> = IBSTNode<T, NEIGHBOR>
export type IAVLTreeNode<T, NEIGHBOR extends IAVLTreeNode<T, NEIGHBOR>> = IBSTNode<T, NEIGHBOR>;
export interface IAVLTree<N extends AVLTreeNode<N['val'], N>> extends IBST<N> {
add(id: BinaryTreeNodeId, val?: N['val'] | null): N | null | undefined;
add(id: BinaryTreeNodeId, val?: N['val'] | null): N | null | undefined
remove(id: BinaryTreeNodeId, isUpdateAllLeftSum?: boolean): BinaryTreeDeletedResult<N>[]
remove(id: BinaryTreeNodeId, isUpdateAllLeftSum?: boolean): BinaryTreeDeletedResult<N>[];
// _balanceFactor(node: N): number
//

View file

@ -1,6 +1,6 @@
import {BinaryTreeNode} from '../data-structures';
import {IAbstractBinaryTree, IAbstractBinaryTreeNode} from './abstract-binary-tree';
import { BinaryTreeNode } from '../data-structures';
import { IAbstractBinaryTree, IAbstractBinaryTreeNode } from './abstract-binary-tree';
export type IBinaryTreeNode<T, NEIGHBOR extends IBinaryTreeNode<T, NEIGHBOR>> = IAbstractBinaryTreeNode<T, NEIGHBOR>
export type IBinaryTreeNode<T, NEIGHBOR extends IBinaryTreeNode<T, NEIGHBOR>> = IAbstractBinaryTreeNode<T, NEIGHBOR>;
export type IBinaryTree<N extends BinaryTreeNode<N['val'], N>> = IAbstractBinaryTree<N>
export type IBinaryTree<N extends BinaryTreeNode<N['val'], N>> = IAbstractBinaryTree<N>;

View file

@ -1,31 +1,31 @@
import {BSTNode} from '../data-structures';
import {IBinaryTree, IBinaryTreeNode} from './binary-tree';
import {BinaryTreeDeletedResult, BinaryTreeNodeId, BinaryTreeNodePropertyName} from '../types';
import { BSTNode } from '../data-structures';
import { IBinaryTree, IBinaryTreeNode } from './binary-tree';
import { BinaryTreeDeletedResult, BinaryTreeNodeId, BinaryTreeNodePropertyName } from '../types';
export type IBSTNode<T, NEIGHBOR extends IBSTNode<T, NEIGHBOR>> = IBinaryTreeNode<T, NEIGHBOR>
export type IBSTNode<T, NEIGHBOR extends IBSTNode<T, NEIGHBOR>> = IBinaryTreeNode<T, NEIGHBOR>;
export interface IBST<N extends BSTNode<N['val'], N>> extends IBinaryTree<N> {
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N;
add(id: BinaryTreeNodeId, val?: N['val'] | null, count?: number): N | null | undefined
add(id: BinaryTreeNodeId, val?: N['val'] | null, count?: number): N | null | undefined;
get(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName): N | null
get(nodeProperty: BinaryTreeNodeId | N, propertyName?: BinaryTreeNodePropertyName): N | null;
lastKey(): BinaryTreeNodeId
lastKey(): BinaryTreeNodeId;
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[]
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[];
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean): N[]
getNodes(nodeProperty: BinaryTreeNodeId | N, propertyName?: BinaryTreeNodePropertyName, onlyOne?: boolean): N[];
// --- start additional functions
lesserSum(id: BinaryTreeNodeId, propertyName ?: BinaryTreeNodePropertyName): number
lesserSum(id: BinaryTreeNodeId, propertyName?: BinaryTreeNodePropertyName): number;
allGreaterNodesAdd(node: N, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean
allGreaterNodesAdd(node: N, delta: number, propertyName?: BinaryTreeNodePropertyName): boolean;
perfectlyBalance(): boolean
perfectlyBalance(): boolean;
isAVLBalanced(): boolean
isAVLBalanced(): boolean;
// --- end additional functions
}

View file

@ -1,5 +1,5 @@
import {VertexId} from '../types';
import {IAbstractGraph} from './abstract-graph';
import { VertexId } from '../types';
import { IAbstractGraph } from './abstract-graph';
export interface IDirectedGraph<V, E> extends IAbstractGraph<V, E> {
incomingEdgesOf(vertex: V): E[];

View file

@ -1 +1 @@
export {}
export {};

View file

@ -1 +1 @@
export {}
export {};

View file

@ -12,4 +12,4 @@ export * from './rb-tree';
export * from './segment-tree';
export * from './singly-linked-list';
export * from './tree-multiset';
export * from './undirected-graph';
export * from './undirected-graph';

View file

@ -1 +1 @@
export {}
export {};

View file

@ -1 +1 @@
export {}
export {};

View file

@ -1,10 +1,9 @@
import {RBTreeNode} from '../data-structures';
import {IBST, IBSTNode} from './bst';
import {BinaryTreeNodeId} from '../types';
import { RBTreeNode } from '../data-structures';
import { IBST, IBSTNode } from './bst';
import { BinaryTreeNodeId } from '../types';
export type IRBTreeNode<T, NEIGHBOR extends IRBTreeNode<T, NEIGHBOR>> = IBSTNode<T, NEIGHBOR>
export type IRBTreeNode<T, NEIGHBOR extends IRBTreeNode<T, NEIGHBOR>> = IBSTNode<T, NEIGHBOR>;
export interface IRBTree<N extends RBTreeNode<N['val'], N>> extends IBST<N> {
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N
createNode(id: BinaryTreeNodeId, val?: N['val'], count?: number): N;
}

View file

@ -1 +1 @@
export {}
export {};

View file

@ -1 +1 @@
export {}
export {};

View file

@ -1,7 +1,7 @@
import {TreeMultisetNode} from '../data-structures';
import {IBSTNode} from './bst';
import {IAVLTree} from './avl-tree';
import { TreeMultisetNode } from '../data-structures';
import { IBSTNode } from './bst';
import { IAVLTree } from './avl-tree';
export type ITreeMultisetNode<T, NEIGHBOR extends ITreeMultisetNode<T, NEIGHBOR>> = IBSTNode<T, NEIGHBOR>
export type ITreeMultisetNode<T, NEIGHBOR extends ITreeMultisetNode<T, NEIGHBOR>> = IBSTNode<T, NEIGHBOR>;
export type ITreeMultiset<N extends TreeMultisetNode<N['val'], N>> = IAVLTree<N>
export type ITreeMultiset<N extends TreeMultisetNode<N['val'], N>> = IAVLTree<N>;

View file

@ -1,5 +1,5 @@
import {VertexId} from '../types';
import {IAbstractGraph} from './abstract-graph';
import { VertexId } from '../types';
import { IAbstractGraph } from './abstract-graph';
export interface IUNDirectedGraph<V, E> extends IAbstractGraph<V, E> {
removeEdgeBetween(v1: V | VertexId, v2: V | VertexId): E | null;

View file

@ -1,4 +1,4 @@
import {AbstractBinaryTreeNode} from '../../data-structures/binary-tree';
import {AbstractBinaryTreeNode} from '../../data-structures';
/**
* Enum representing different loop types.
@ -6,7 +6,11 @@ import {AbstractBinaryTreeNode} from '../../data-structures/binary-tree';
* - `iterative`: Indicates the iterative loop type (with loops that use iterations).
* - `recursive`: Indicates the recursive loop type (with loops that call themselves).
*/
export enum LoopType { ITERATIVE = 'ITERATIVE', RECURSIVE = 'RECURSIVE'}
export enum LoopType {
ITERATIVE = 'ITERATIVE',
RECURSIVE = 'RECURSIVE'
}
/* This enumeration defines the position of a node within a family tree composed of three associated nodes, where 'root' represents the root node of the family tree, 'left' represents the left child node, and 'right' represents the right child node. */
export enum FamilyPosition {
@ -20,21 +24,27 @@ export enum FamilyPosition {
}
export type BinaryTreeNodePropertyName = 'id' | 'val';
export type NodeOrPropertyName = 'node' | BinaryTreeNodePropertyName;
export type DFSOrderPattern = 'in' | 'pre' | 'post';
export type BinaryTreeNodeId = number;
export type BinaryTreeDeletedResult<N> = { deleted: N | null | undefined, needBalanced: N | null };
export type BinaryTreeDeletedResult<N> = { deleted: N | null | undefined; needBalanced: N | null };
export type AbstractBinaryTreeNodeProperty<N extends AbstractBinaryTreeNode<N['val'], N>> =
N['val']
| N['val']
| N
| number
| BinaryTreeNodeId;
export type AbstractBinaryTreeNodeProperties<N extends AbstractBinaryTreeNode<N['val'], N>> = AbstractBinaryTreeNodeProperty<N>[];
export type AbstractBinaryTreeNodeNested<T> = AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type AbstractBinaryTreeNodeProperties<N extends AbstractBinaryTreeNode<N['val'], N>> =
AbstractBinaryTreeNodeProperty<N>[];
export type AbstractBinaryTreeNodeNested<T> = AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
export type AbstractBinaryTreeOptions = {
loopType?: LoopType,
}
loopType?: LoopType
};

View file

@ -1,5 +1,11 @@
export type VertexId = string | number;
export type EdgeId = string;
export type DijkstraResult<V> =
{ distMap: Map<V, number>, distPaths?: Map<V, V[]>, preMap: Map<V, V | null>, seen: Set<V>, paths: V[][], minDist: number, minPath: V[] }
| null;
export type DijkstraResult<V> = {
distMap: Map<V, number>;
distPaths?: Map<V, V[]>;
preMap: Map<V, V | null>;
seen: Set<V>;
paths: V[][];
minDist: number;
minPath: V[];
} | null;

View file

@ -1,5 +1,5 @@
import {AVLTreeNode} from '../../data-structures/binary-tree';
import {AVLTreeNode} from '../../data-structures';
import {BSTOptions} from './bst';
export type AVLTreeNodeNested<T> = AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type AVLTreeOptions = BSTOptions & {};
export type AVLTreeOptions = BSTOptions & {};

View file

@ -1,9 +1,5 @@
import {BinaryTreeNode} from '../../data-structures/binary-tree';
import {AbstractBinaryTreeOptions} from './abstract-binary-tree';
// export type BinaryTreeDeleted<N> = { deleted: N | null | undefined, needBalanced: N | null };
// export type ResultByProperty<N extends BinaryTreeNode<N['val'], N>> = N['val'] | N | number | BinaryTreeNodeId;
// export type ResultsByProperty<N extends BinaryTreeNode<N['val'], N>> = ResultByProperty<N>[];
export type BinaryTreeNodeNested<T> = BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type BinaryTreeOptions = AbstractBinaryTreeOptions & {}
export type BinaryTreeOptions = AbstractBinaryTreeOptions & {}

View file

@ -4,6 +4,7 @@ import {BinaryTreeNodeId} from './abstract-binary-tree';
export type BSTComparator = (a: BinaryTreeNodeId, b: BinaryTreeNodeId) => 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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
export type BSTOptions = BinaryTreeOptions & {
comparator?: BSTComparator,

View file

@ -4,5 +4,5 @@ export type TopologicalStatus = 0 | 1 | 2;
export enum TopologicalProperty {
VAL = 'VAL',
NODE = 'NODE',
ID = 'ID',
ID = 'ID'
}

View file

@ -1 +1 @@
export {}
export {};

View file

@ -2,4 +2,4 @@ export type HeapOptions<T> = {
priorityExtractor?: (element: T) => number;
// TODO there is an idea that support chaining which is for conveniently using the data structure
// isChaining? : boolean
}
};

View file

@ -12,4 +12,4 @@ export * from './priority-queue';
export * from './heap';
export * from './singly-linked-list';
export * from './doubly-linked-list';
export * from './navigator';
export * from './navigator';

View file

@ -1 +1 @@
export type MapGraphCoordinate = [number, number];
export type MapGraphCoordinate = [number, number];

View file

@ -2,12 +2,12 @@ export type Direction = 'up' | 'right' | 'down' | 'left';
export type Turning = { [key in Direction]: Direction };
export type NavigatorParams<T> = {
matrix: T[][],
turning: Turning,
onMove: (cur: [number, number]) => void
matrix: T[][];
turning: Turning;
onMove: (cur: [number, number]) => void;
init: {
cur: [number, number],
charDir: Direction,
VISITED: T,
}
}
cur: [number, number];
charDir: Direction;
VISITED: T;
};
};

View file

@ -4,6 +4,6 @@ export type PriorityQueueOptions<T> = {
nodes?: T[];
isFix?: boolean;
comparator: PriorityQueueComparator<T>;
}
};
export type PriorityQueueDFSOrderPattern = 'pre' | 'in' | 'post';

View file

@ -1 +1 @@
export {}
export {};

View file

@ -1 +1 @@
export {}
export {};

View file

@ -1,3 +1,3 @@
export * from './data-structures';
export * from './helpers';
export * from './utils';
export * from './utils';

View file

@ -1,2 +1,2 @@
export * from './utils';
export * from './validate-type';
export * from './validate-type';

View file

@ -1,25 +1,35 @@
export type KeyValueObject = { [key: string]: any };
export type KeyValueObjectWithId = { [key: string]: any, id: string | number | symbol };
export type KeyValueObjectWithId = { [key: string]: any; id: string | number | symbol };
export type NonNumberNonObjectButDefined = string | boolean | symbol | null;
export type ObjectWithoutId = Omit<KeyValueObject, 'id'>;
export type ObjectWithNonNumberId = {
[key: string]: any,
[key: string]: any;
id: string | boolean | symbol | null | object | undefined;
}
};
export type ObjectWithNumberId = {
[key: string]: any,
[key: string]: any;
id: number;
}
};
export type RestrictValById =
NonNumberNonObjectButDefined
| NonNumberNonObjectButDefined
| ObjectWithoutId
| ObjectWithNonNumberId
| ObjectWithNumberId;
export type DummyAny = string | number | boolean | null | undefined | object | symbol | void | ((...args: []) => any) | never;
export type DummyAny =
| string
| number
| boolean
| null
| undefined
| object
| symbol
| void
| ((...args: []) => any)
| never;

View file

@ -5,17 +5,19 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type {Thunk, ToThunkFn, TrlAsyncFn, TrlFn} from '../types';
import type { Thunk, ToThunkFn, TrlAsyncFn, TrlFn } from '../types';
export const uuidV4 = function () {
return 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[x]/g, function (c) {
const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
const r = (Math.random() * 16) | 0,
v = c == 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
};
export const arrayRemove = function <T>(array: T[], predicate: (item: T, index: number, array: T[]) => boolean): T[] {
let i = -1, len = array ? array.length : 0;
let i = -1,
len = array ? array.length : 0;
const result = [];
while (++i < len) {
@ -30,49 +32,48 @@ export const arrayRemove = function <T>(array: T[], predicate: (item: T, index:
return result;
};
export const THUNK_SYMBOL = Symbol('thunk')
export const THUNK_SYMBOL = Symbol('thunk');
export const isThunk = (fnOrValue: any) => {
return typeof fnOrValue === 'function' && fnOrValue.__THUNK__ === THUNK_SYMBOL
}
return typeof fnOrValue === 'function' && fnOrValue.__THUNK__ === THUNK_SYMBOL;
};
export const toThunk = (fn: ToThunkFn): Thunk => {
const thunk = () => fn()
thunk.__THUNK__ = THUNK_SYMBOL
return thunk
}
const thunk = () => fn();
thunk.__THUNK__ = THUNK_SYMBOL;
return thunk;
};
export const trampoline = (fn: TrlFn) => {
const cont = (...args: [...Parameters<TrlFn>]) => toThunk(() => fn(...args))
const cont = (...args: [...Parameters<TrlFn>]) => toThunk(() => fn(...args));
return Object.assign(
(...args: [...Parameters<TrlFn>]) => {
let result = fn(...args)
let result = fn(...args);
while (isThunk(result) && typeof result === 'function') {
result = result()
result = result();
}
return result
return result;
},
{cont}
)
}
{ cont }
);
};
export const trampolineAsync = (fn: TrlAsyncFn) => {
const cont = (...args: [...Parameters<TrlAsyncFn>]) => toThunk(() => fn(...args))
const cont = (...args: [...Parameters<TrlAsyncFn>]) => toThunk(() => fn(...args));
return Object.assign(
async (...args: [...Parameters<TrlAsyncFn>]) => {
let result = await fn(...args)
let result = await fn(...args);
while (isThunk(result) && typeof result === 'function') {
result = await result()
result = await result();
}
return result
return result;
},
{cont}
)
}
{ cont }
);
};

View file

@ -3,7 +3,6 @@
"declaration": true,
"outDir": "./dist",
"module": "CommonJS",
// "target": "CommonJS",
"target": "ES6",
"lib": [
"esnext",

View file

@ -7,7 +7,7 @@ module.exports = [
target: 'web',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
path: path.resolve(__dirname, 'lib'),
library: 'dataStructureTyped',
libraryTarget: 'window',
},