mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
style: Try to synchronize Prettier with the coding style of the IDE.
This commit is contained in:
parent
1064ad4a58
commit
8f1f6d6f52
|
@ -43,8 +43,8 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
],
|
||||
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
||||
"object-curly-spacing": ["error", "always"]
|
||||
"brace-style": ["error", "1tbs", {"allowSingleLine": true}],
|
||||
"object-curly-spacing": ["error", "never"]
|
||||
},
|
||||
"settings": {
|
||||
"import/parsers": {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
module.exports = {
|
||||
"arrowParens": "avoid",
|
||||
"bracketSpacing": true,
|
||||
"bracketSpacing": false,
|
||||
"htmlWhitespaceSensitivity": "css",
|
||||
"insertPragma": false,
|
||||
"bracketSameLine": true,
|
||||
"bracketSameLine": false,
|
||||
"jsxSingleQuote": true,
|
||||
"printWidth": 120,
|
||||
"proseWrap": "preserve",
|
||||
|
|
|
@ -209,7 +209,7 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
// Balance Restoration: If a balance issue is discovered after inserting a node, it requires balance restoration operations. Balance restoration includes four basic cases where rotation operations need to be performed to fix the balance:
|
||||
switch (
|
||||
this._balanceFactor(A) // second O(1)
|
||||
) {
|
||||
) {
|
||||
case -2:
|
||||
if (A && A.left) {
|
||||
if (this._balanceFactor(A.left) <= 0) {
|
||||
|
|
|
@ -17,7 +17,7 @@ export class BinaryIndexedTree {
|
|||
* @param - - `frequency`: The default frequency value. It is optional and has a default
|
||||
* value of 0.
|
||||
*/
|
||||
constructor({frequency = 0, max}: { frequency?: number; max: number }) {
|
||||
constructor({frequency = 0, max}: {frequency?: number; max: number}) {
|
||||
this._freq = frequency;
|
||||
this._max = max;
|
||||
this._freqMap = {0: 0};
|
||||
|
|
|
@ -107,8 +107,7 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
|
|||
* Represents a binary tree data structure.
|
||||
* @template N - The type of the binary tree's nodes.
|
||||
*/
|
||||
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>>
|
||||
implements IBinaryTree<V, N> {
|
||||
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>> implements IBinaryTree<V, N> {
|
||||
iterationType: IterationType = IterationType.ITERATIVE;
|
||||
|
||||
/**
|
||||
|
@ -301,7 +300,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
): BiTreeDeleteResult<N>[] {
|
||||
const deletedResult: BiTreeDeleteResult<N>[] = [];
|
||||
if (!this.root) return deletedResult;
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
||||
callback = (node => node) as C;
|
||||
|
||||
const curr = this.getNode(identifier, callback);
|
||||
if (!curr) return deletedResult;
|
||||
|
@ -330,14 +330,12 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
||||
orgCurrent = this._swap(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
this._size = this.size - 1;
|
||||
|
||||
|
@ -383,7 +381,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n)
|
||||
|
@ -412,7 +409,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
|
||||
return _getMaxHeight(beginRoot);
|
||||
} else {
|
||||
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) {
|
||||
|
@ -539,7 +536,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* Space Complexity: O(log n).
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n)
|
||||
* Space Complexity: O(log n).
|
||||
|
@ -572,7 +568,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): N[] {
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
||||
callback = (node => node) as C;
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
|
||||
|
@ -660,7 +657,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): boolean {
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
||||
callback = (node => node) as C;
|
||||
|
||||
return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
|
||||
}
|
||||
|
@ -718,7 +716,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): N | null | undefined {
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
||||
callback = (node => node) as C;
|
||||
|
||||
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
|
||||
}
|
||||
|
@ -836,7 +835,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): V | undefined {
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
|
||||
callback = (node => node) as C;
|
||||
|
||||
return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
|
||||
}
|
||||
|
@ -1165,7 +1165,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
isNodeOrNull(node: any): node is (N | null) {
|
||||
isNodeOrNull(node: any): node is N | null {
|
||||
return this.isRealNode(node) || node === null;
|
||||
}
|
||||
|
||||
|
@ -1238,7 +1238,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
iterationType: IterationType = IterationType.ITERATIVE,
|
||||
includeNull = false
|
||||
): ReturnType<C>[] {
|
||||
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
const ans: ReturnType<C>[] = [];
|
||||
|
@ -1285,7 +1284,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
_traverse(beginRoot);
|
||||
} else {
|
||||
// 0: visit, 1: print
|
||||
const stack: { opt: 0 | 1; node: N | null | undefined }[] = [{opt: 0, node: beginRoot}];
|
||||
const stack: {opt: 0 | 1; node: N | null | undefined}[] = [{opt: 0, node: beginRoot}];
|
||||
|
||||
while (stack.length > 0) {
|
||||
const cur = stack.pop();
|
||||
|
@ -1454,7 +1453,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* Space complexity: O(n)
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
|
@ -1523,8 +1521,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return levelsNodes;
|
||||
}
|
||||
|
||||
getPredecessor(node: N): N
|
||||
|
||||
getPredecessor(node: N): N;
|
||||
|
||||
/**
|
||||
* The function `getPredecessor` returns the predecessor node of a given node in a binary tree.
|
||||
|
@ -1549,7 +1546,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The function `getSuccessor` returns the next node in a binary tree given a current node.
|
||||
* @param {BTNKey | N | null} [x] - The parameter `x` can be of type `BTNKey`, `N`, or `null`.
|
||||
|
@ -1681,7 +1677,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return ans;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The above function is an iterator for a binary tree that can be used to traverse the tree in
|
||||
* either an iterative or recursive manner.
|
||||
|
@ -1691,7 +1686,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* @returns The `*[Symbol.iterator]` method returns a generator object that yields the keys of the
|
||||
* binary tree nodes in a specific order.
|
||||
*/
|
||||
* [Symbol.iterator](node = this.root): Generator<BTNKey, void, undefined> {
|
||||
*[Symbol.iterator](node = this.root): Generator<BTNKey, void, undefined> {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
@ -1817,7 +1812,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return destNode;
|
||||
}
|
||||
return undefined;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,7 +41,6 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
|
|||
this._left = v;
|
||||
}
|
||||
|
||||
|
||||
protected override _right?: N;
|
||||
|
||||
/**
|
||||
|
@ -63,10 +62,7 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
|
|||
}
|
||||
}
|
||||
|
||||
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>>
|
||||
extends BinaryTree<V, N>
|
||||
implements IBinaryTree<V, N> {
|
||||
|
||||
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>> extends BinaryTree<V, N> implements IBinaryTree<V, N> {
|
||||
/**
|
||||
* The constructor function initializes a binary search tree with an optional comparator function.
|
||||
* @param {BSTOptions} [options] - An optional object that contains additional configuration options
|
||||
|
@ -109,7 +105,6 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
* Space Complexity: O(1) - Constant space is used.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).
|
||||
* Space Complexity: O(1) - Constant space is used.
|
||||
|
@ -230,9 +225,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
}
|
||||
|
||||
const inserted: (N | undefined)[] = [];
|
||||
const combinedArr: [BTNKey | N, V][] = keysOrNodes.map(
|
||||
(value: BTNKey | N, index) => [value, data?.[index]] as [BTNKey | N, V]
|
||||
);
|
||||
const combinedArr: [BTNKey | N, V][] = keysOrNodes.map((value: BTNKey | N, index) => [value, data?.[index]] as [BTNKey | N, V]);
|
||||
|
||||
let sorted = [];
|
||||
|
||||
|
@ -244,7 +237,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
const _isBinaryTreeKeyOrNullTuple = (arr: [BTNKey | N, V][]): arr is [BTNKey, V][] => {
|
||||
for (const [keyOrNode] of arr) if (this.isNodeKey(keyOrNode)) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let sortedKeysOrNodes: (number | N | undefined)[] = [],
|
||||
sortedData: (V | undefined)[] | undefined = [];
|
||||
|
@ -580,7 +573,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
if (l <= r) {
|
||||
const m = l + Math.floor((r - l) / 2);
|
||||
const midNode = sorted[m];
|
||||
debugger
|
||||
debugger;
|
||||
this.add(midNode.key, midNode.value);
|
||||
stack.push([m + 1, r]);
|
||||
stack.push([l, m - 1]);
|
||||
|
@ -672,5 +665,4 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
else if (compared < 0) return CP.lt;
|
||||
else return CP.eq;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,18 +6,10 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import {
|
||||
BiTreeDeleteResult,
|
||||
BTNCallback,
|
||||
BTNKey,
|
||||
IterationType,
|
||||
RBTNColor,
|
||||
RBTreeOptions,
|
||||
RedBlackTreeNodeNested
|
||||
} from '../../types';
|
||||
import {BST, BSTNode} from "./bst";
|
||||
import {IBinaryTree} from "../../interfaces";
|
||||
import {BinaryTreeNode} from "./binary-tree";
|
||||
import {BiTreeDeleteResult, BTNCallback, BTNKey, IterationType, RBTNColor, RBTreeOptions, RedBlackTreeNodeNested} from '../../types';
|
||||
import {BST, BSTNode} from './bst';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
import {BinaryTreeNode} from './binary-tree';
|
||||
|
||||
export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNodeNested<V>> extends BSTNode<V, N> {
|
||||
color: RBTNColor;
|
||||
|
@ -38,7 +30,6 @@ export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBla
|
|||
export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNode<V, RedBlackTreeNodeNested<V>>>
|
||||
extends BST<V, N>
|
||||
implements IBinaryTree<V, N> {
|
||||
|
||||
NIL: N = new RedBlackTreeNode<V>(NaN) as unknown as N;
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,10 +10,7 @@ import {BiTreeDeleteResult, BTNCallback, CP, FamilyPosition, IterationType} from
|
|||
import {IBinaryTree} from '../../interfaces';
|
||||
import {AVLTree, AVLTreeNode} from './avl-tree';
|
||||
|
||||
export class TreeMultimapNode<
|
||||
V = any,
|
||||
N extends TreeMultimapNode<V, N> = TreeMultimapNodeNested<V>
|
||||
> extends AVLTreeNode<V, N> {
|
||||
export class TreeMultimapNode<V = any, N extends TreeMultimapNode<V, N> = TreeMultimapNodeNested<V>> extends AVLTreeNode<V, N> {
|
||||
count: number;
|
||||
|
||||
/**
|
||||
|
@ -284,7 +281,8 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
if (!curr) return deletedResult;
|
||||
|
||||
const parent: N | undefined = curr?.parent ? curr.parent : undefined;
|
||||
let needBalanced: N | undefined = undefined, orgCurrent: N | undefined = curr;
|
||||
let needBalanced: N | undefined = undefined,
|
||||
orgCurrent: N | undefined = curr;
|
||||
|
||||
if (curr.count > 1 && !ignoreCount) {
|
||||
curr.count--;
|
||||
|
@ -418,4 +416,4 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -300,7 +300,7 @@ export abstract class AbstractGraph<
|
|||
return [];
|
||||
}
|
||||
|
||||
const stack: { vertex: VO; path: VO[] }[] = [];
|
||||
const stack: {vertex: VO; path: VO[]}[] = [];
|
||||
stack.push({vertex: vertex1, path: [vertex1]});
|
||||
|
||||
while (stack.length > 0) {
|
||||
|
@ -514,12 +514,7 @@ export abstract class AbstractGraph<
|
|||
* 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<VO>`.
|
||||
*/
|
||||
dijkstraWithoutHeap(
|
||||
src: VO | VertexKey,
|
||||
dest?: VO | VertexKey | null,
|
||||
getMinDist?: boolean,
|
||||
genPaths?: boolean
|
||||
): DijkstraResult<VO> {
|
||||
dijkstraWithoutHeap(src: VO | VertexKey, dest?: VO | VertexKey | null, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<VO> {
|
||||
if (getMinDist === undefined) getMinDist = false;
|
||||
if (genPaths === undefined) genPaths = false;
|
||||
|
||||
|
@ -614,14 +609,14 @@ export abstract class AbstractGraph<
|
|||
}
|
||||
|
||||
getMinDist &&
|
||||
distMap.forEach((d, v) => {
|
||||
if (v !== srcVertex) {
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
if (genPaths) minDest = v;
|
||||
distMap.forEach((d, v) => {
|
||||
if (v !== srcVertex) {
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
if (genPaths) minDest = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
genPaths && getPaths(minDest);
|
||||
|
||||
|
@ -662,12 +657,7 @@ export abstract class AbstractGraph<
|
|||
* shortest paths from the source vertex to all other vertices in the graph. If `genPaths
|
||||
* @returns The function `dijkstra` returns an object of type `DijkstraResult<VO>`.
|
||||
*/
|
||||
dijkstra(
|
||||
src: VO | VertexKey,
|
||||
dest?: VO | VertexKey | null,
|
||||
getMinDist?: boolean,
|
||||
genPaths?: boolean
|
||||
): DijkstraResult<VO> {
|
||||
dijkstra(src: VO | VertexKey, dest?: VO | VertexKey | null, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<VO> {
|
||||
if (getMinDist === undefined) getMinDist = false;
|
||||
if (genPaths === undefined) genPaths = false;
|
||||
|
||||
|
@ -691,7 +681,7 @@ export abstract class AbstractGraph<
|
|||
if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);
|
||||
}
|
||||
|
||||
const heap = new PriorityQueue<{ key: number; value: VO }>({comparator: (a, b) => a.key - b.key});
|
||||
const heap = new PriorityQueue<{key: number; value: VO}>({comparator: (a, b) => a.key - b.key});
|
||||
heap.add({key: 0, value: srcVertex});
|
||||
|
||||
distMap.set(srcVertex, 0);
|
||||
|
@ -923,7 +913,7 @@ export abstract class AbstractGraph<
|
|||
* `predecessor` property is a 2D array of vertices (or `null`) representing the predecessor vertices in the shortest
|
||||
* path between vertices in the
|
||||
*/
|
||||
floydWarshall(): { costs: number[][]; predecessor: (VO | null)[][] } {
|
||||
floydWarshall(): {costs: number[][]; predecessor: (VO | null)[][]} {
|
||||
const idAndVertices = [...this._vertices];
|
||||
const n = idAndVertices.length;
|
||||
|
||||
|
@ -992,12 +982,7 @@ export abstract class AbstractGraph<
|
|||
* are arrays of vertices that form cycles within the SCCs.
|
||||
* @returns The function `tarjan` returns an object with the following properties:
|
||||
*/
|
||||
tarjan(
|
||||
needCutVertexes: boolean = false,
|
||||
needBridges: boolean = false,
|
||||
needSCCs: boolean = true,
|
||||
needCycles: boolean = false
|
||||
) {
|
||||
tarjan(needCutVertexes: boolean = false, needBridges: boolean = false, needSCCs: boolean = true, needCycles: boolean = false) {
|
||||
// !! in undirected graph we will not let child visit parent when dfs
|
||||
// !! articulation point(in dfs search tree not in graph): (cur !== root && cur.has(child)) && (low(child) >= dfn(cur)) || (cur === root && cur.children() >= 2)
|
||||
// !! bridge: low(child) > dfn(cur)
|
||||
|
|
|
@ -45,12 +45,7 @@ export class DirectedEdge<E = any> extends AbstractEdge<E> {
|
|||
}
|
||||
}
|
||||
|
||||
export class DirectedGraph<
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends DirectedVertex<V> = DirectedVertex<V>,
|
||||
EO extends DirectedEdge<E> = DirectedEdge<E>
|
||||
>
|
||||
export class DirectedGraph<V = any, E = any, VO extends DirectedVertex<V> = DirectedVertex<V>, EO extends DirectedEdge<E> = DirectedEdge<E>>
|
||||
extends AbstractGraph<V, E, VO, EO>
|
||||
implements IGraph<V, E, VO, EO> {
|
||||
/**
|
||||
|
@ -590,4 +585,4 @@ export class DirectedGraph<
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,12 +40,12 @@ export class MapEdge<E = any> extends DirectedEdge<E> {
|
|||
}
|
||||
}
|
||||
|
||||
export class MapGraph<
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends MapVertex<V> = MapVertex<V>,
|
||||
EO extends MapEdge<E> = MapEdge<E>
|
||||
> extends DirectedGraph<V, E, VO, EO> {
|
||||
export class MapGraph<V = any, E = any, VO extends MapVertex<V> = MapVertex<V>, EO extends MapEdge<E> = MapEdge<E>> extends DirectedGraph<
|
||||
V,
|
||||
E,
|
||||
VO,
|
||||
EO
|
||||
> {
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -43,11 +43,11 @@ export class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
|||
}
|
||||
|
||||
export class UndirectedGraph<
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends UndirectedVertex<V> = UndirectedVertex<V>,
|
||||
EO extends UndirectedEdge<E> = UndirectedEdge<E>
|
||||
>
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends UndirectedVertex<V> = UndirectedVertex<V>,
|
||||
EO extends UndirectedEdge<E> = UndirectedEdge<E>
|
||||
>
|
||||
extends AbstractGraph<V, E, VO, EO>
|
||||
implements IGraph<V, E, VO, EO> {
|
||||
/**
|
||||
|
|
|
@ -133,7 +133,7 @@ export class HashMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
* entries(): IterableIterator<[K, V]> {
|
||||
*entries(): IterableIterator<[K, V]> {
|
||||
for (const bucket of this.table) {
|
||||
if (bucket) {
|
||||
for (const [key, value] of bucket) {
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
export class TreeMap {
|
||||
}
|
||||
export class TreeMap {}
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
export class TreeSet {
|
||||
}
|
||||
export class TreeSet {}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import type {Comparator, DFSOrderPattern} from '../../types';
|
||||
|
||||
export class Heap<E = any> {
|
||||
constructor(options: { comparator: Comparator<E>; nodes?: E[] }) {
|
||||
constructor(options: {comparator: Comparator<E>; nodes?: E[]}) {
|
||||
this._comparator = options.comparator;
|
||||
if (options.nodes && options.nodes.length > 0) {
|
||||
this._nodes = options.nodes;
|
||||
|
@ -48,7 +48,7 @@ export class Heap<E = any> {
|
|||
* @returns A new Heap instance.
|
||||
* @param options
|
||||
*/
|
||||
static heapify<E>(options: { nodes: E[]; comparator: Comparator<E> }): Heap<E> {
|
||||
static heapify<E>(options: {nodes: E[]; comparator: Comparator<E>}): Heap<E> {
|
||||
return new Heap<E>(options);
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,6 @@ export class FibonacciHeap<E> {
|
|||
return this.push(element);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
|
@ -473,7 +472,6 @@ export class FibonacciHeap<E> {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
|
@ -743,10 +741,7 @@ export class FibonacciHeap<E> {
|
|||
protected consolidate(): void {
|
||||
const A: (FibonacciHeapNode<E> | undefined)[] = new Array(this.size);
|
||||
const nodes = this.consumeLinkedList(this.root);
|
||||
let x: FibonacciHeapNode<E> | undefined,
|
||||
y: FibonacciHeapNode<E> | undefined,
|
||||
d: number,
|
||||
t: FibonacciHeapNode<E> | undefined;
|
||||
let x: FibonacciHeapNode<E> | undefined, y: FibonacciHeapNode<E> | undefined, d: number, t: FibonacciHeapNode<E> | undefined;
|
||||
|
||||
for (const node of nodes) {
|
||||
x = node;
|
||||
|
|
|
@ -11,7 +11,7 @@ import type {Comparator} from '../../types';
|
|||
|
||||
export class MaxHeap<E = any> extends Heap<E> {
|
||||
constructor(
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -11,7 +11,7 @@ import type {Comparator} from '../../types';
|
|||
|
||||
export class MinHeap<E = any> extends Heap<E> {
|
||||
constructor(
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -826,7 +826,7 @@ export class DoublyLinkedList<E = any> {
|
|||
/**
|
||||
* The function returns an iterator that iterates over the values of a linked list.
|
||||
*/
|
||||
* [Symbol.iterator]() {
|
||||
*[Symbol.iterator]() {
|
||||
let current = this.head;
|
||||
|
||||
while (current) {
|
||||
|
|
|
@ -773,7 +773,7 @@ export class SinglyLinkedList<E = any> {
|
|||
/**
|
||||
* The function returns an iterator that iterates over the values of a linked list.
|
||||
*/
|
||||
* [Symbol.iterator]() {
|
||||
*[Symbol.iterator]() {
|
||||
let current = this.head;
|
||||
|
||||
while (current) {
|
||||
|
|
|
@ -14,7 +14,7 @@ export class MatrixNTI2D<V = any> {
|
|||
* given initial value or 0 if not provided.
|
||||
* @param options - An object containing the following properties:
|
||||
*/
|
||||
constructor(options: { row: number; col: number; initialVal?: V }) {
|
||||
constructor(options: {row: number; col: number; initialVal?: V}) {
|
||||
const {row, col, initialVal} = options;
|
||||
this._matrix = new Array(row).fill(undefined).map(() => new Array(col).fill(initialVal || 0));
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ export class Vector2D {
|
|||
public x: number = 0,
|
||||
public y: number = 0,
|
||||
public w: number = 1 // needed for matrix multiplication
|
||||
) {
|
||||
}
|
||||
) {}
|
||||
|
||||
/**
|
||||
* The function checks if the x and y values of a point are both zero.
|
||||
|
|
|
@ -10,7 +10,7 @@ import type {Comparator} from '../../types';
|
|||
|
||||
export class MaxPriorityQueue<E = any> extends PriorityQueue<E> {
|
||||
constructor(
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -10,7 +10,7 @@ import type {Comparator} from '../../types';
|
|||
|
||||
export class MinPriorityQueue<E = any> extends PriorityQueue<E> {
|
||||
constructor(
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -10,7 +10,7 @@ import {Heap} from '../heap';
|
|||
import {Comparator} from '../../types';
|
||||
|
||||
export class PriorityQueue<E = any> extends Heap<E> {
|
||||
constructor(options: { comparator: Comparator<E>; nodes?: E[] }) {
|
||||
constructor(options: {comparator: Comparator<E>; nodes?: E[]}) {
|
||||
super(options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@ import {DoublyLinkedList} from '../linked-list';
|
|||
|
||||
// O(n) time complexity of obtaining the value
|
||||
// O(1) time complexity of adding at the beginning and the end
|
||||
export class Deque<E = any> extends DoublyLinkedList<E> {
|
||||
}
|
||||
export class Deque<E = any> extends DoublyLinkedList<E> {}
|
||||
|
||||
// O(1) time complexity of obtaining the value
|
||||
// O(n) time complexity of adding at the beginning and the end
|
||||
|
@ -20,9 +19,9 @@ export class ObjectDeque<E = number> {
|
|||
if (capacity !== undefined) this._capacity = capacity;
|
||||
}
|
||||
|
||||
protected _nodes: { [key: number]: E } = {};
|
||||
protected _nodes: {[key: number]: E} = {};
|
||||
|
||||
get nodes(): { [p: number]: E } {
|
||||
get nodes(): {[p: number]: E} {
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
|
|
|
@ -300,7 +300,7 @@ export class Queue<E = any> {
|
|||
return new Queue(this.nodes.slice(this.offset));
|
||||
}
|
||||
|
||||
* [Symbol.iterator]() {
|
||||
*[Symbol.iterator]() {
|
||||
for (const item of this.nodes) {
|
||||
yield item;
|
||||
}
|
||||
|
|
|
@ -342,4 +342,4 @@ export class Trie {
|
|||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export type Direction = 'up' | 'right' | 'down' | 'left';
|
||||
|
||||
export type Turning = { [key in Direction]: Direction };
|
||||
export type Turning = {[key in Direction]: Direction};
|
||||
|
||||
export type NavigatorParams<T = any> = {
|
||||
matrix: T[][];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export type ToThunkFn = () => ReturnType<TrlFn>;
|
||||
export type Thunk = () => ReturnType<ToThunkFn> & { __THUNK__: symbol };
|
||||
export type Thunk = () => ReturnType<ToThunkFn> & {__THUNK__: symbol};
|
||||
export type TrlFn = (...args: any[]) => any;
|
||||
export type TrlAsyncFn = (...args: any[]) => any;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export type KeyValueObject = { [key: string]: any };
|
||||
export type KeyValueObject = {[key: string]: any};
|
||||
|
||||
export type KeyValueObjectWithKey = { [key: string]: any; key: string | number | symbol };
|
||||
export type KeyValueObjectWithKey = {[key: string]: any; key: string | number | symbol};
|
||||
|
||||
export type NonNumberNonObjectButDefined = string | boolean | symbol | null;
|
||||
|
||||
|
@ -16,20 +16,6 @@ export type ObjectWithNumberKey = {
|
|||
key: number;
|
||||
};
|
||||
|
||||
export type RestrictValByKey =
|
||||
| NonNumberNonObjectButDefined
|
||||
| ObjectWithoutKey
|
||||
| ObjectWithNonNumberKey
|
||||
| ObjectWithNumberKey;
|
||||
export type RestrictValByKey = NonNumberNonObjectButDefined | ObjectWithoutKey | ObjectWithNonNumberKey | ObjectWithNumberKey;
|
||||
|
||||
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;
|
||||
|
|
|
@ -183,7 +183,7 @@ describe('Individual package BST operations test', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
|
|
|
@ -2,7 +2,7 @@ import {RedBlackTree} from '../../../../src';
|
|||
import * as Benchmark from 'benchmark';
|
||||
import {getRandomIntArray, magnitude} from '../../../utils';
|
||||
import {OrderedMap} from 'js-sdsl';
|
||||
import {isCompetitor} from "../../../config";
|
||||
import {isCompetitor} from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const rbTree = new RedBlackTree();
|
||||
|
@ -10,32 +10,31 @@ const {HUNDRED_THOUSAND} = magnitude;
|
|||
const arr = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
|
||||
const competitor = new OrderedMap<number, number>();
|
||||
|
||||
suite
|
||||
.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
|
||||
rbTree.clear();
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
rbTree.add(arr[i]);
|
||||
}
|
||||
});
|
||||
|
||||
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
|
||||
rbTree.clear();
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
rbTree.add(arr[i]);
|
||||
}
|
||||
});
|
||||
|
||||
if (isCompetitor) {
|
||||
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} competitor add`, () => {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
competitor.setElement(arr[i], arr[i]);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete randomly`, () => {
|
||||
rbTree.clear();
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
rbTree.add(arr[i]);
|
||||
}
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
rbTree.delete(arr[i]);
|
||||
}
|
||||
})
|
||||
suite
|
||||
.add(`${HUNDRED_THOUSAND.toLocaleString()} add & delete randomly`, () => {
|
||||
rbTree.clear();
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
rbTree.add(arr[i]);
|
||||
}
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
rbTree.delete(arr[i]);
|
||||
}
|
||||
})
|
||||
.add(`${HUNDRED_THOUSAND.toLocaleString()} getNode`, () => {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
rbTree.getNode(arr[i]);
|
||||
|
|
|
@ -2,28 +2,26 @@ import {HashMap} from '../../../../src';
|
|||
import {HashMap as CHashMap} from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from "../../../config";
|
||||
import {isCompetitor} from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {TEN_THOUSAND} = magnitude;
|
||||
|
||||
suite
|
||||
.add(`${TEN_THOUSAND.toLocaleString()} set`, () => {
|
||||
const hm = new HashMap<number, number>();
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} set`, () => {
|
||||
const hm = new HashMap<number, number>();
|
||||
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
hm.set(i, i);
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
hm.set(i, i);
|
||||
}
|
||||
});
|
||||
if (isCompetitor) {
|
||||
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} competitor set`, () => {
|
||||
const hm = new CHashMap<number, number>();
|
||||
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
hm.setElement(i, i);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} set & get`, () => {
|
||||
const hm = new HashMap<number, number>();
|
||||
|
@ -34,8 +32,7 @@ suite.add(`${TEN_THOUSAND.toLocaleString()} set & get`, () => {
|
|||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
hm.get(i);
|
||||
}
|
||||
})
|
||||
;
|
||||
});
|
||||
if (isCompetitor) {
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} competitor set & get`, () => {
|
||||
const hm = new CHashMap<number, number>();
|
||||
|
@ -46,6 +43,6 @@ if (isCompetitor) {
|
|||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
hm.getElementByKey(i);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
export {suite};
|
||||
|
|
|
@ -2,19 +2,18 @@ import {DoublyLinkedList, DoublyLinkedListNode} from '../../../../src';
|
|||
import {LinkList as CLinkedList} from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from "../../../config";
|
||||
import {isCompetitor} from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {LINEAR} = magnitude;
|
||||
|
||||
suite
|
||||
.add(`${LINEAR.toLocaleString()} unshift`, () => {
|
||||
const list = new DoublyLinkedList<number>();
|
||||
suite.add(`${LINEAR.toLocaleString()} unshift`, () => {
|
||||
const list = new DoublyLinkedList<number>();
|
||||
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
list.unshift(i);
|
||||
}
|
||||
})
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
list.unshift(i);
|
||||
}
|
||||
});
|
||||
if (isCompetitor) {
|
||||
suite.add(`${LINEAR.toLocaleString()} competitor unshift`, () => {
|
||||
const list = new CLinkedList<number>();
|
||||
|
@ -22,18 +21,19 @@ if (isCompetitor) {
|
|||
for (let i = 0; i < LINEAR; i++) {
|
||||
list.pushFront(i);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
suite.add(`${LINEAR.toLocaleString()} unshift & shift`, () => {
|
||||
const list = new DoublyLinkedList<number>();
|
||||
suite
|
||||
.add(`${LINEAR.toLocaleString()} unshift & shift`, () => {
|
||||
const list = new DoublyLinkedList<number>();
|
||||
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
list.unshift(i);
|
||||
}
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
list.shift();
|
||||
}
|
||||
})
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
list.unshift(i);
|
||||
}
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
list.shift();
|
||||
}
|
||||
})
|
||||
.add(`${LINEAR.toLocaleString()} insertBefore`, () => {
|
||||
const doublyList = new DoublyLinkedList<number>();
|
||||
let midNode: DoublyLinkedListNode | null = null;
|
||||
|
|
|
@ -6,9 +6,7 @@ const suite = new Benchmark.Suite();
|
|||
const {TEN_THOUSAND} = magnitude;
|
||||
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} refill & poll`, () => {
|
||||
const nodes = Array.from(
|
||||
new Set<number>(Array.from(new Array(TEN_THOUSAND), () => Math.floor(Math.random() * TEN_THOUSAND * 100)))
|
||||
);
|
||||
const nodes = Array.from(new Set<number>(Array.from(new Array(TEN_THOUSAND), () => Math.floor(Math.random() * TEN_THOUSAND * 100))));
|
||||
const maxPQ = new MaxPriorityQueue<number>();
|
||||
maxPQ.refill(nodes);
|
||||
while (maxPQ.size > 0) {
|
||||
|
|
|
@ -2,23 +2,22 @@ import {PriorityQueue as CPriorityQueue} from 'js-sdsl';
|
|||
import {PriorityQueue} from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from "../../../config";
|
||||
import {isCompetitor} from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {TEN_THOUSAND} = magnitude;
|
||||
|
||||
suite
|
||||
.add(`${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
|
||||
const pq = new PriorityQueue<number>({comparator: (a, b) => b - a});
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
|
||||
const pq = new PriorityQueue<number>({comparator: (a, b) => b - a});
|
||||
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
pq.add(i);
|
||||
}
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
pq.add(i);
|
||||
}
|
||||
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
pq.pop();
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
pq.pop();
|
||||
}
|
||||
});
|
||||
if (isCompetitor) {
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} competitor add & pop`, () => {
|
||||
const pq = new CPriorityQueue<number>();
|
||||
|
@ -31,7 +30,6 @@ if (isCompetitor) {
|
|||
pq.pop();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export {suite};
|
||||
|
|
|
@ -2,25 +2,24 @@ import {Deque} from '../../../../src';
|
|||
import {Deque as CDeque} from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from "../../../config";
|
||||
import {isCompetitor} from '../../../config';
|
||||
|
||||
export const suite = new Benchmark.Suite();
|
||||
const {LINEAR} = magnitude;
|
||||
|
||||
suite
|
||||
.add(`${LINEAR.toLocaleString()} push`, () => {
|
||||
const deque = new Deque<number>();
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
deque.push(i);
|
||||
}
|
||||
})
|
||||
suite.add(`${LINEAR.toLocaleString()} push`, () => {
|
||||
const deque = new Deque<number>();
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
deque.push(i);
|
||||
}
|
||||
});
|
||||
if (isCompetitor) {
|
||||
suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
|
||||
const deque = new CDeque<number>();
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
deque.pushBack(i);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
suite.add(`${LINEAR.toLocaleString()} shift`, () => {
|
||||
const deque = new Deque<number>();
|
||||
|
|
|
@ -2,19 +2,18 @@ import {Queue} from '../../../../src';
|
|||
import {Queue as CQueue} from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from "../../../config";
|
||||
import {isCompetitor} from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {LINEAR} = magnitude;
|
||||
|
||||
suite
|
||||
.add(`${LINEAR.toLocaleString()} push`, () => {
|
||||
const queue = new Queue<number>();
|
||||
suite.add(`${LINEAR.toLocaleString()} push`, () => {
|
||||
const queue = new Queue<number>();
|
||||
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
queue.push(i);
|
||||
}
|
||||
})
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
queue.push(i);
|
||||
}
|
||||
});
|
||||
if (isCompetitor) {
|
||||
suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
|
||||
const queue = new CQueue<number>();
|
||||
|
@ -22,7 +21,7 @@ if (isCompetitor) {
|
|||
for (let i = 0; i < LINEAR; i++) {
|
||||
queue.push(i);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
suite.add(`${LINEAR.toLocaleString()} push & shift`, () => {
|
||||
const queue = new Queue<number>();
|
||||
|
|
|
@ -2,19 +2,18 @@ import {Stack} from '../../../../src';
|
|||
import {Stack as CStack} from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from "../../../config";
|
||||
import {isCompetitor} from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {LINEAR} = magnitude;
|
||||
|
||||
suite
|
||||
.add(`${LINEAR.toLocaleString()} push`, () => {
|
||||
const stack = new Stack<number>();
|
||||
suite.add(`${LINEAR.toLocaleString()} push`, () => {
|
||||
const stack = new Stack<number>();
|
||||
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
stack.push(i);
|
||||
}
|
||||
})
|
||||
for (let i = 0; i < LINEAR; i++) {
|
||||
stack.push(i);
|
||||
}
|
||||
});
|
||||
if (isCompetitor) {
|
||||
suite.add(`${LINEAR.toLocaleString()} competitor push`, () => {
|
||||
const queue = new CStack<number>();
|
||||
|
@ -22,7 +21,7 @@ if (isCompetitor) {
|
|||
for (let i = 0; i < LINEAR; i++) {
|
||||
queue.push(i);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
suite.add(`${LINEAR.toLocaleString()} push & pop`, () => {
|
||||
const queue = new Stack<number>();
|
||||
|
@ -33,7 +32,7 @@ suite.add(`${LINEAR.toLocaleString()} push & pop`, () => {
|
|||
for (let i = 0; i < LINEAR; i++) {
|
||||
queue.pop();
|
||||
}
|
||||
})
|
||||
});
|
||||
if (isCompetitor) {
|
||||
suite.add(`${LINEAR.toLocaleString()} competitor push & pop`, () => {
|
||||
const queue = new CStack<number>();
|
||||
|
@ -44,7 +43,7 @@ if (isCompetitor) {
|
|||
for (let i = 0; i < LINEAR; i++) {
|
||||
queue.pop();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
export {suite};
|
||||
|
|
|
@ -11,7 +11,7 @@ const reportDistPath = path.join(parentDirectory, 'benchmark');
|
|||
const testDir = path.join(__dirname, 'data-structures');
|
||||
const testFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
|
||||
|
||||
const report: { [key: string]: any } = {};
|
||||
const report: {[key: string]: any} = {};
|
||||
|
||||
let completedCount = 0;
|
||||
|
||||
|
@ -173,9 +173,7 @@ performanceTests.forEach(item => {
|
|||
console.log(
|
||||
// `Files: ${GREEN}${testFileCount}${END} `,
|
||||
// `Suites: ${GREEN}${performanceTests.length}${END} `,
|
||||
`Suites Progress: ${isDone ? GREEN : YELLOW}${completedCount}${END}/${isDone ? GREEN : YELLOW}${
|
||||
performanceTests.length
|
||||
}${END}`,
|
||||
`Suites Progress: ${isDone ? GREEN : YELLOW}${completedCount}${END}/${isDone ? GREEN : YELLOW}${performanceTests.length}${END}`,
|
||||
`Time: ${isTimeWarn ? YELLOW : GREEN}${runTime}s${END}`
|
||||
);
|
||||
if (isDone) {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import * as Benchmark from 'benchmark';
|
||||
|
||||
export type PerformanceTest = { testName: string; suite: Benchmark.Suite; file: string };
|
||||
export type PerformanceTest = {testName: string; suite: Benchmark.Suite; file: string};
|
||||
|
|
|
@ -1 +1 @@
|
|||
export type Json2htmlOptions = { plainHtml?: boolean } & Partial<{ [key: string]: any }>;
|
||||
export type Json2htmlOptions = {plainHtml?: boolean} & Partial<{[key: string]: any}>;
|
||||
|
|
|
@ -219,7 +219,7 @@ describe('AVL Tree Test recursively', () => {
|
|||
});
|
||||
|
||||
describe('AVLTree APIs test', () => {
|
||||
const avl = new AVLTree<{ id: number; text: string }>();
|
||||
const avl = new AVLTree<{id: number; text: string}>();
|
||||
beforeEach(() => {
|
||||
avl.clear();
|
||||
});
|
||||
|
@ -268,7 +268,7 @@ describe('AVLTree', () => {
|
|||
});
|
||||
|
||||
describe('BinaryTree APIs test', () => {
|
||||
const avl = new AVLTree<{ id: number; text: string }>();
|
||||
const avl = new AVLTree<{id: number; text: string}>();
|
||||
beforeEach(() => {
|
||||
avl.clear();
|
||||
});
|
||||
|
@ -285,5 +285,4 @@ describe('AVLTree', () => {
|
|||
expect(bfsRes[0]?.key).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {BinaryTree, BinaryTreeNode, IterationType} from '../../../../src';
|
||||
import {getRandomIntArray} from "../../../utils";
|
||||
import {FamilyPosition} from "binary-tree-typed";
|
||||
import {getRandomIntArray} from '../../../utils';
|
||||
import {FamilyPosition} from 'binary-tree-typed';
|
||||
// import {isDebugTest} from '../../../config';
|
||||
|
||||
// const isDebug = isDebugTest;
|
||||
|
@ -72,7 +72,6 @@ describe('BinaryTreeNode', () => {
|
|||
expect(leftChild.familyPosition).toBe('ROOT_LEFT');
|
||||
rightChild.left = new BinaryTreeNode<number>(5);
|
||||
expect(rightChild.familyPosition).toBe('ROOT_RIGHT');
|
||||
|
||||
});
|
||||
|
||||
it('should determine only right child family position correctly', () => {
|
||||
|
@ -106,8 +105,8 @@ describe('BinaryTree', () => {
|
|||
});
|
||||
|
||||
it('should delete nodes', () => {
|
||||
expect(tree.getHeight(tree.root, IterationType.ITERATIVE)).toBe(-1)
|
||||
expect(tree.getMinHeight()).toBe(-1)
|
||||
expect(tree.getHeight(tree.root, IterationType.ITERATIVE)).toBe(-1);
|
||||
expect(tree.getMinHeight()).toBe(-1);
|
||||
const node = tree.add(1);
|
||||
expect(tree.size).toBe(1);
|
||||
|
||||
|
@ -117,7 +116,6 @@ describe('BinaryTree', () => {
|
|||
tree.add(rightChild);
|
||||
const root = tree.root;
|
||||
|
||||
|
||||
expect(leftChild.familyPosition).toBe('LEFT');
|
||||
tree.add(null);
|
||||
tree.add(new BinaryTreeNode<number>(4));
|
||||
|
@ -128,15 +126,14 @@ describe('BinaryTree', () => {
|
|||
expect(rightChild.familyPosition).toBe('ROOT_RIGHT');
|
||||
|
||||
tree.delete(new BinaryTreeNode<number>(200));
|
||||
tree.delete(rightChild)
|
||||
tree.delete(rightChild);
|
||||
|
||||
if (node) {
|
||||
const result = tree.delete(node);
|
||||
expect(result).toHaveLength(1);
|
||||
expect(tree.size).toBe(3);
|
||||
expect(tree.getMinHeight(tree.root, IterationType.RECURSIVE)).toBe(1)
|
||||
expect(tree.getMinHeight(tree.root, IterationType.RECURSIVE)).toBe(1);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
it('should add and find nodes', () => {
|
||||
|
@ -155,11 +152,10 @@ describe('BinaryTree', () => {
|
|||
expect(tree.has('3', node => node.value?.toString())).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should be a balance tree after malicious manipulation', () => {
|
||||
tree.add(3);
|
||||
tree.add(12);
|
||||
tree.addMany(getRandomIntArray(100, 1, 100))
|
||||
tree.addMany(getRandomIntArray(100, 1, 100));
|
||||
tree.add(10);
|
||||
|
||||
expect(tree.isPerfectlyBalanced()).toBe(true);
|
||||
|
@ -238,20 +234,16 @@ describe('BinaryTree', () => {
|
|||
|
||||
expect(tree.isSubtreeBST(tree.getNode(4), IterationType.RECURSIVE)).toBe(true);
|
||||
expect(tree.isSubtreeBST(tree.getNode(4), IterationType.ITERATIVE)).toBe(true);
|
||||
expect(tree.getNodes(2, undefined, false, null)).toEqual([])
|
||||
expect(tree.getNodes(tree.getNodeByKey(2), undefined, false, tree.root)).toEqual([tree.getNodeByKey(2)])
|
||||
expect(tree.getNodes(2, undefined, false, null)).toEqual([]);
|
||||
expect(tree.getNodes(tree.getNodeByKey(2), undefined, false, tree.root)).toEqual([tree.getNodeByKey(2)]);
|
||||
});
|
||||
|
||||
it('should subTreeTraverse', () => {
|
||||
tree.addMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
|
||||
expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.ITERATIVE)).toEqual([6, 3, 7]);
|
||||
expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.RECURSIVE)).toEqual([6, 3, 7]);
|
||||
expect(
|
||||
tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.ITERATIVE, true)
|
||||
).toEqual([6, 3, 7, null]);
|
||||
expect(
|
||||
tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.RECURSIVE, true)
|
||||
).toEqual([6, 3, 7, null]);
|
||||
expect(tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.ITERATIVE, true)).toEqual([6, 3, 7, null]);
|
||||
expect(tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.RECURSIVE, true)).toEqual([6, 3, 7, null]);
|
||||
});
|
||||
|
||||
it('should clear the tree', () => {
|
||||
|
@ -323,45 +315,81 @@ describe('BinaryTree traversals', () => {
|
|||
|
||||
const arr = [35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55];
|
||||
tree.refill(arr);
|
||||
expect(
|
||||
tree.bfs(node => node, tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null))
|
||||
).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]);
|
||||
expect(
|
||||
tree.bfs(node => node, tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null))
|
||||
).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]);
|
||||
expect(
|
||||
tree.bfs(node => node, tree.root, IterationType.ITERATIVE).map(node => (node === null ? null : node.key))
|
||||
).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
||||
expect(
|
||||
tree.bfs(node => node, tree.root, IterationType.RECURSIVE).map(node => (node === null ? null : node.key))
|
||||
).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
||||
expect(tree.bfs(node => node, tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null))).toEqual([
|
||||
35,
|
||||
20,
|
||||
40,
|
||||
15,
|
||||
29,
|
||||
null,
|
||||
50,
|
||||
null,
|
||||
16,
|
||||
28,
|
||||
30,
|
||||
45,
|
||||
55
|
||||
]);
|
||||
expect(tree.bfs(node => node, tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null))).toEqual([
|
||||
35,
|
||||
20,
|
||||
40,
|
||||
15,
|
||||
29,
|
||||
null,
|
||||
50,
|
||||
null,
|
||||
16,
|
||||
28,
|
||||
30,
|
||||
45,
|
||||
55
|
||||
]);
|
||||
expect(tree.bfs(node => node, tree.root, IterationType.ITERATIVE).map(node => (node === null ? null : node.key))).toEqual([
|
||||
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
||||
]);
|
||||
expect(tree.bfs(node => node, tree.root, IterationType.RECURSIVE).map(node => (node === null ? null : node.key))).toEqual([
|
||||
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
||||
]);
|
||||
|
||||
expect(tree.dfs(node => node.key, 'pre')).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
|
||||
expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55
|
||||
expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
|
||||
expect(tree.dfs(node => node, 'pre', tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null))).toEqual([
|
||||
35,
|
||||
20,
|
||||
15,
|
||||
null,
|
||||
16,
|
||||
29,
|
||||
28,
|
||||
30,
|
||||
40,
|
||||
null,
|
||||
50,
|
||||
45,
|
||||
55
|
||||
]);
|
||||
expect(tree.dfs(node => node, 'pre', tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null))).toEqual([
|
||||
35,
|
||||
20,
|
||||
15,
|
||||
null,
|
||||
16,
|
||||
29,
|
||||
28,
|
||||
30,
|
||||
40,
|
||||
null,
|
||||
50,
|
||||
45,
|
||||
55
|
||||
]);
|
||||
expect(
|
||||
tree
|
||||
.dfs(node => node, 'pre', tree.root, IterationType.ITERATIVE, true)
|
||||
.map(node => (node ? node.key : null))
|
||||
).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]);
|
||||
expect(
|
||||
tree
|
||||
.dfs(node => node, 'pre', tree.root, IterationType.RECURSIVE, true)
|
||||
.map(node => (node ? node.key : null))
|
||||
).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]);
|
||||
|
||||
expect(tree.dfs(node => node.key, 'in')).toEqual([15, 16, 20, 28, 29, 30, 35, 40, 45, 50, 55]);
|
||||
expect(tree.dfs(node => node.key, 'post')).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
|
||||
expect(tree.dfs(node => node.key, 'post', tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35
|
||||
]);
|
||||
expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
||||
]);
|
||||
expect(tree.bfs(node => node.key, tree.root, IterationType.ITERATIVE)).toEqual([
|
||||
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
||||
]);
|
||||
expect(tree.dfs(node => node.key, 'post', tree.root, IterationType.RECURSIVE)).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
|
||||
expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
||||
expect(tree.bfs(node => node.key, tree.root, IterationType.ITERATIVE)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
||||
|
||||
expect(tree.listLevels(node => node.key)).toEqual([[35], [20, 40], [15, 29, 50], [16, 28, 30, 45, 55]]);
|
||||
|
||||
|
@ -532,13 +560,7 @@ describe('BinaryTree', () => {
|
|||
expect(nodes.length).toBe(1);
|
||||
expect(nodes[0].key).toBe(3);
|
||||
|
||||
const nodesRec = tree.getNodes(
|
||||
'B',
|
||||
(node: BinaryTreeNode<string>) => node.value,
|
||||
false,
|
||||
tree.root,
|
||||
IterationType.RECURSIVE
|
||||
);
|
||||
const nodesRec = tree.getNodes('B', (node: BinaryTreeNode<string>) => node.value, false, tree.root, IterationType.RECURSIVE);
|
||||
|
||||
expect(nodesRec.length).toBe(1);
|
||||
expect(nodesRec[0].key).toBe(3);
|
||||
|
|
|
@ -189,7 +189,7 @@ describe('BST operations test', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
|
@ -260,7 +260,7 @@ describe('BST operations test', () => {
|
|||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
objBST.bfs(node => bfsNodesAfterBalanced.push(node));
|
||||
expect(bfsNodesAfterBalanced[0].key).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
@ -385,7 +385,7 @@ describe('BST operations test', () => {
|
|||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
objBST.bfs(node => bfsNodes.push(node));
|
||||
expect(bfsNodes[0].key).toBe(2);
|
||||
expect(bfsNodes[1].key).toBe(12);
|
||||
|
@ -580,7 +580,7 @@ describe('BST operations test recursively', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
|
@ -652,7 +652,7 @@ describe('BST operations test recursively', () => {
|
|||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
objBST.bfs(node => bfsNodesAfterBalanced.push(node));
|
||||
expect(bfsNodesAfterBalanced[0].key).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
@ -777,7 +777,7 @@ describe('BST operations test recursively', () => {
|
|||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
objBST.bfs(node => bfsNodes.push(node));
|
||||
expect(bfsNodes[0].key).toBe(2);
|
||||
expect(bfsNodes[1].key).toBe(12);
|
||||
|
@ -843,11 +843,7 @@ describe('BST Performance test', function () {
|
|||
bst.addMany([4, 2, 6, 1, 3, 5, 7]);
|
||||
expect(bst.subTreeTraverse(node => node.key, bst.getNode(6), IterationType.ITERATIVE)).toEqual([6, 5, 7]);
|
||||
expect(bst.subTreeTraverse(node => node.key, bst.getNode(6), IterationType.RECURSIVE)).toEqual([6, 5, 7]);
|
||||
expect(
|
||||
bst.subTreeTraverse(node => (node?.key ?? undefined), bst.getNode(6), IterationType.ITERATIVE, true)
|
||||
).toEqual([6, 5, 7]);
|
||||
expect(
|
||||
bst.subTreeTraverse(node => (node?.key ?? undefined), bst.getNode(6), IterationType.RECURSIVE, true)
|
||||
).toEqual([6, 5, 7]);
|
||||
expect(bst.subTreeTraverse(node => node?.key ?? undefined, bst.getNode(6), IterationType.ITERATIVE, true)).toEqual([6, 5, 7]);
|
||||
expect(bst.subTreeTraverse(node => node?.key ?? undefined, bst.getNode(6), IterationType.RECURSIVE, true)).toEqual([6, 5, 7]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('Overall BinaryTree Test', () => {
|
|||
bfsIDs[0] === 11; // true
|
||||
expect(bfsIDs[0]).toBe(11);
|
||||
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {IterationType, RBTNColor, RedBlackTree, RedBlackTreeNode} from '../../../../src';
|
||||
import {getRandomInt, getRandomIntArray, magnitude} from '../../../utils';
|
||||
import {isDebugTest} from '../../../config';
|
||||
import {OrderedMap} from "js-sdsl";
|
||||
import {OrderedMap} from 'js-sdsl';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
|
||||
|
@ -421,14 +421,10 @@ describe('RedBlackTree', () => {
|
|||
isDebug && tree.print();
|
||||
|
||||
expect(tree.dfs()).toEqual([
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 22, 23, 25, 28, 33, 50, 110, 111,
|
||||
155, 225
|
||||
])
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 22, 23, 25, 28, 33, 50, 110, 111, 155, 225
|
||||
]);
|
||||
|
||||
expect(tree.isBST()).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('should fix the tree after insertion and deletion', () => {
|
||||
|
@ -441,20 +437,14 @@ describe('RedBlackTree', () => {
|
|||
|
||||
expect(tree.size).toBe(51);
|
||||
expect(tree.isBST()).toBe(true);
|
||||
expect(tree.dfs(n => n.key, "in", tree.root, IterationType.ITERATIVE)).toEqual([
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
|
||||
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
||||
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
|
||||
93, 94, 95, 96, 97, 98, 99
|
||||
])
|
||||
expect(tree.dfs(n => n.key, "in", tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
|
||||
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
||||
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
|
||||
93, 94, 95, 96, 97, 98, 99
|
||||
])
|
||||
expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.ITERATIVE)).toEqual([
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
||||
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
||||
]);
|
||||
expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
||||
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
||||
]);
|
||||
});
|
||||
|
||||
it('should fix the tree after large scale insertion and deletion', () => {
|
||||
|
@ -467,12 +457,12 @@ describe('RedBlackTree', () => {
|
|||
|
||||
expect(tree.size).toBe(0);
|
||||
expect(tree.isBST()).toBe(true);
|
||||
expect(tree.dfs(n => n.key, "in", tree.root, IterationType.ITERATIVE)).toEqual([])
|
||||
expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.ITERATIVE)).toEqual([]);
|
||||
|
||||
tree.clear();
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
tree.add(getRandomInt(-100, 1000))
|
||||
tree.delete(getRandomInt(-100, 1000))
|
||||
tree.add(getRandomInt(-100, 1000));
|
||||
tree.delete(getRandomInt(-100, 1000));
|
||||
}
|
||||
|
||||
// TODO there is a bug when dfs the tree with NIL node
|
||||
|
@ -482,7 +472,6 @@ describe('RedBlackTree', () => {
|
|||
const arr = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
|
||||
const competitor = new OrderedMap<number, number>();
|
||||
|
||||
|
||||
it('should fix the tree after large scale insertion and deletion', () => {
|
||||
tree.clear();
|
||||
const tS = performance.now();
|
||||
|
@ -497,6 +486,5 @@ describe('RedBlackTree', () => {
|
|||
competitor.setElement(arr[i], arr[i]);
|
||||
}
|
||||
console.log(performance.now() - cS);
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -207,7 +207,7 @@ describe('TreeMultimap operations test', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objTreeMultimap = new TreeMultimap<{ key: number; keyA: number }>();
|
||||
const objTreeMultimap = new TreeMultimap<{key: number; keyA: number}>();
|
||||
expect(objTreeMultimap).toBeInstanceOf(TreeMultimap);
|
||||
objTreeMultimap.add(11, {key: 11, keyA: 11});
|
||||
objTreeMultimap.add(3, {key: 3, keyA: 3});
|
||||
|
@ -447,7 +447,7 @@ describe('TreeMultimap operations test recursively', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objTreeMultimap = new TreeMultimap<{ key: number; keyA: number }>();
|
||||
const objTreeMultimap = new TreeMultimap<{key: number; keyA: number}>();
|
||||
expect(objTreeMultimap).toBeInstanceOf(TreeMultimap);
|
||||
objTreeMultimap.add(11, {key: 11, keyA: 11});
|
||||
objTreeMultimap.add(3, {key: 3, keyA: 3});
|
||||
|
|
|
@ -22,12 +22,12 @@ class MyEdge<E = any> extends AbstractEdge<E> {
|
|||
}
|
||||
}
|
||||
|
||||
class MyGraph<
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends MyVertex<V> = MyVertex<V>,
|
||||
EO extends MyEdge<E> = MyEdge<E>
|
||||
> extends AbstractGraph<V, E, VO, EO> {
|
||||
class MyGraph<V = any, E = any, VO extends MyVertex<V> = MyVertex<V>, EO extends MyEdge<E> = MyEdge<E>> extends AbstractGraph<
|
||||
V,
|
||||
E,
|
||||
VO,
|
||||
EO
|
||||
> {
|
||||
createVertex(key: VertexKey, value?: V): VO {
|
||||
return new MyVertex(key, value) as VO;
|
||||
}
|
||||
|
@ -74,8 +74,7 @@ class MyGraph<
|
|||
describe('AbstractGraph Operation Test', () => {
|
||||
const myGraph: MyGraph<number, string> = new MyGraph<number, string>();
|
||||
|
||||
beforeEach(() => {
|
||||
});
|
||||
beforeEach(() => {});
|
||||
it('should edge cases', function () {
|
||||
myGraph.addVertex('A', 1);
|
||||
myGraph.addVertex('B', 2);
|
||||
|
|
|
@ -126,12 +126,12 @@ class MyEdge<E = any> extends DirectedEdge<E> {
|
|||
}
|
||||
}
|
||||
|
||||
class MyDirectedGraph<
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends MyVertex<V> = MyVertex<V>,
|
||||
EO extends MyEdge<E> = MyEdge<E>
|
||||
> extends DirectedGraph<V, E, VO, EO> {
|
||||
class MyDirectedGraph<V = any, E = any, VO extends MyVertex<V> = MyVertex<V>, EO extends MyEdge<E> = MyEdge<E>> extends DirectedGraph<
|
||||
V,
|
||||
E,
|
||||
VO,
|
||||
EO
|
||||
> {
|
||||
createVertex(key: VertexKey, value: V): VO {
|
||||
return new MyVertex(key, value) as VO;
|
||||
}
|
||||
|
@ -351,29 +351,9 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
|
|||
expect(costs[2]).toEqual([3, 15, 38, 17, 35, Infinity, 64, Infinity, 22]);
|
||||
expect(costs[3]).toEqual([123, 135, 120, 137, 155, Infinity, 47, Infinity, 126]);
|
||||
expect(costs[4]).toEqual([133, 145, 130, 147, 165, Infinity, 57, Infinity, 136]);
|
||||
expect(costs[5]).toEqual([
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity
|
||||
]);
|
||||
expect(costs[5]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
||||
expect(costs[6]).toEqual([76, 88, 73, 90, 108, Infinity, 137, Infinity, 79]);
|
||||
expect(costs[7]).toEqual([
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity
|
||||
]);
|
||||
expect(costs[7]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
||||
expect(costs[8]).toEqual([173, 185, 170, 187, 205, Infinity, 97, Infinity, 176]);
|
||||
|
||||
expect(predecessor).toBeInstanceOf(Array);
|
||||
|
|
|
@ -150,7 +150,7 @@ describe('UndirectedGraph', () => {
|
|||
});
|
||||
|
||||
it('should getAllPathsBetween work well in 66 vertexes 97 edges graph', () => {
|
||||
const graph = new UndirectedGraph<{ name: string }, number>();
|
||||
const graph = new UndirectedGraph<{name: string}, number>();
|
||||
for (const v of saltyVertexes) {
|
||||
graph.addVertex(v.name, v);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ describe('Heap Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should object heap work well', function () {
|
||||
const minHeap = new MinHeap<{ a: string; key: number }>({comparator: (a, b) => a.key - b.key});
|
||||
const minHeap = new MinHeap<{a: string; key: number}>({comparator: (a, b) => a.key - b.key});
|
||||
minHeap.add({key: 1, a: 'a1'});
|
||||
minHeap.add({key: 6, a: 'a6'});
|
||||
minHeap.add({key: 2, a: 'a2'});
|
||||
|
@ -37,7 +37,7 @@ describe('Heap Operation Test', () => {
|
|||
i++;
|
||||
}
|
||||
|
||||
const maxHeap = new MaxHeap<{ key: number; a: string }>({comparator: (a, b) => b.key - a.key});
|
||||
const maxHeap = new MaxHeap<{key: number; a: string}>({comparator: (a, b) => b.key - a.key});
|
||||
maxHeap.add({key: 1, a: 'a1'});
|
||||
maxHeap.add({key: 6, a: 'a6'});
|
||||
maxHeap.add({key: 5, a: 'a5'});
|
||||
|
@ -45,14 +45,7 @@ describe('Heap Operation Test', () => {
|
|||
maxHeap.add({key: 0, a: 'a0'});
|
||||
maxHeap.add({key: 9, a: 'a9'});
|
||||
expect(maxHeap.peek()).toEqual({a: 'a9', key: 9});
|
||||
expect(maxHeap.toArray().map(item => ({a: item.a}))).toEqual([
|
||||
{a: 'a9'},
|
||||
{a: 'a2'},
|
||||
{a: 'a6'},
|
||||
{a: 'a1'},
|
||||
{a: 'a0'},
|
||||
{a: 'a5'}
|
||||
]);
|
||||
expect(maxHeap.toArray().map(item => ({a: item.a}))).toEqual([{a: 'a9'}, {a: 'a2'}, {a: 'a6'}, {a: 'a1'}, {a: 'a0'}, {a: 'a5'}]);
|
||||
const maxExpectPolled = [{a: 'a9'}, {a: 'a6'}, {a: 'a5'}, {a: 'a2'}, {a: 'a1'}, {a: 'a0'}];
|
||||
let maxI = 0;
|
||||
while (maxHeap.size > 0) {
|
||||
|
|
|
@ -60,7 +60,7 @@ describe('DoublyLinkedList Operation Test', () => {
|
|||
|
||||
describe('DoublyLinkedList Operation Test', () => {
|
||||
let list: DoublyLinkedList<number>;
|
||||
let objectList: DoublyLinkedList<{ keyA: number }>;
|
||||
let objectList: DoublyLinkedList<{keyA: number}>;
|
||||
|
||||
beforeEach(() => {
|
||||
list = new DoublyLinkedList();
|
||||
|
|
|
@ -11,10 +11,10 @@ describe('SinglyLinkedListNode', () => {
|
|||
|
||||
describe('SinglyLinkedList Operation Test', () => {
|
||||
let list: SinglyLinkedList<number>;
|
||||
let objectList: SinglyLinkedList<{ keyA: number }>;
|
||||
let objectList: SinglyLinkedList<{keyA: number}>;
|
||||
beforeEach(() => {
|
||||
list = new SinglyLinkedList<number>();
|
||||
objectList = new SinglyLinkedList<{ keyA: number }>();
|
||||
objectList = new SinglyLinkedList<{keyA: number}>();
|
||||
});
|
||||
|
||||
describe('push', () => {
|
||||
|
|
|
@ -16,7 +16,7 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should add elements and maintain heap property in a object MaxPriorityQueue', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<{ keyA: number }>({comparator: (a, b) => b.keyA - a.keyA});
|
||||
const priorityQueue = new MaxPriorityQueue<{keyA: number}>({comparator: (a, b) => b.keyA - a.keyA});
|
||||
priorityQueue.refill([{keyA: 5}, {keyA: 3}, {keyA: 1}]);
|
||||
priorityQueue.add({keyA: 7});
|
||||
|
||||
|
@ -63,7 +63,7 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
|
||||
it('should correctly heapify an object array', () => {
|
||||
const nodes = [{keyA: 5}, {keyA: 3}, {keyA: 7}, {keyA: 1}];
|
||||
const maxPQ = MaxPriorityQueue.heapify<{ keyA: number }>({nodes: nodes, comparator: (a, b) => b.keyA - a.keyA});
|
||||
const maxPQ = MaxPriorityQueue.heapify<{keyA: number}>({nodes: nodes, comparator: (a, b) => b.keyA - a.keyA});
|
||||
|
||||
expect(maxPQ.poll()?.keyA).toBe(7);
|
||||
expect(maxPQ.poll()?.keyA).toBe(5);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {PriorityQueue} from '../../../../src';
|
||||
import {PriorityQueue as CPriorityQueue} from 'js-sdsl';
|
||||
import {isDebugTest} from "../../../config";
|
||||
import {isDebugTest} from '../../../config';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
describe('PriorityQueue Operation Test', () => {
|
||||
|
@ -13,9 +13,9 @@ describe('PriorityQueue Operation Test', () => {
|
|||
minPQ.poll();
|
||||
expect(minPQ.toArray()).toEqual([4, 5, 6]);
|
||||
expect(minPQ.peek()).toBe(4);
|
||||
expect(PriorityQueue.heapify({nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10], comparator: (a, b) => a - b}).toArray()).toEqual(
|
||||
[1, 2, 3, 5, 6, 7, 8, 9, 10]
|
||||
);
|
||||
expect(PriorityQueue.heapify({nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10], comparator: (a, b) => a - b}).toArray()).toEqual([
|
||||
1, 2, 3, 5, 6, 7, 8, 9, 10
|
||||
]);
|
||||
});
|
||||
|
||||
it('should Max PriorityQueue poll, peek, heapify, toArray work well', function () {
|
||||
|
@ -27,9 +27,9 @@ describe('PriorityQueue Operation Test', () => {
|
|||
maxPriorityQueue.poll();
|
||||
expect(maxPriorityQueue.toArray()).toEqual([3, 2, 1]);
|
||||
expect(maxPriorityQueue.peek()).toBe(3);
|
||||
expect(PriorityQueue.heapify({nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10], comparator: (a, b) => a - b}).toArray()).toEqual(
|
||||
[1, 2, 3, 5, 6, 7, 8, 9, 10]
|
||||
);
|
||||
expect(PriorityQueue.heapify({nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10], comparator: (a, b) => a - b}).toArray()).toEqual([
|
||||
1, 2, 3, 5, 6, 7, 8, 9, 10
|
||||
]);
|
||||
});
|
||||
|
||||
it('should PriorityQueue clone, sort, getNodes, dfs work well', function () {
|
||||
|
|
|
@ -32,7 +32,7 @@ export const bigO = {
|
|||
|
||||
function findPotentialN(input: any): number {
|
||||
let longestArray: any[] = [];
|
||||
let mostProperties: { [key: string]: any } = {};
|
||||
let mostProperties: {[key: string]: any} = {};
|
||||
|
||||
function recurse(obj: any) {
|
||||
if (Array.isArray(obj)) {
|
||||
|
|
|
@ -14,9 +14,7 @@ function makeLabelDiv(options: any, level: number, keyName: string | number, dat
|
|||
return `<div class='index'><span class='json-to-html-label'>${keyName} </span></div>`;
|
||||
} else if (typeof keyName === 'string') {
|
||||
if (datatype === 'array') {
|
||||
return `<div class='collapsible level${level}' ${toggleJS(
|
||||
options
|
||||
)}><span class='json-to-html-label'>${keyName}</span></div>`;
|
||||
return `<div class='collapsible level${level}' ${toggleJS(options)}><span class='json-to-html-label'>${keyName}</span></div>`;
|
||||
} else if (datatype === 'object') {
|
||||
return `<div class='attribute collapsible level${level}' ${toggleJS(
|
||||
options
|
||||
|
@ -122,9 +120,7 @@ function _render(name: string, data: any, options: Json2htmlOptions, level: numb
|
|||
} else {
|
||||
subs =
|
||||
"<div class='altRows'>" +
|
||||
data
|
||||
.map((val: any, idx: number) => _render(idx.toString(), val, options, level + 1, idx % 2))
|
||||
.join("</div><div class='altRows'>") +
|
||||
data.map((val: any, idx: number) => _render(idx.toString(), val, options, level + 1, idx % 2)).join("</div><div class='altRows'>") +
|
||||
'</div>';
|
||||
}
|
||||
return `<div class="json-to-html-collapse clearfix ${altRow}">
|
||||
|
|
Loading…
Reference in a new issue