style: code base reformat

This commit is contained in:
Revone 2023-12-21 10:26:45 +08:00
parent bc000105d8
commit dc6ef95f78
58 changed files with 783 additions and 551 deletions

View file

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

View file

@ -1 +1 @@
export * from './iterable-base';
export * from './iterable-base';

View file

@ -1,7 +1,6 @@
import { ElementCallback, EntryCallback, ReduceElementCallback, ReduceEntryCallback } from "../../types";
import { ElementCallback, EntryCallback, ReduceElementCallback, ReduceEntryCallback } from '../../types';
export abstract class IterableEntryBase<K = any, V = any> {
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
@ -147,7 +146,7 @@ export abstract class IterableEntryBase<K = any, V = any> {
let index = 0;
for (const item of this) {
const [key, value] = item;
callbackfn.call(thisArg, value, key, index++, this)
callbackfn.call(thisArg, value, key, index++, this);
}
}
@ -176,7 +175,7 @@ export abstract class IterableEntryBase<K = any, V = any> {
let index = 0;
for (const item of this) {
const [key, value] = item;
accumulator = callbackfn(accumulator, value, key, index++, this)
accumulator = callbackfn(accumulator, value, key, index++, this);
}
return accumulator;
}
@ -193,14 +192,13 @@ export abstract class IterableEntryBase<K = any, V = any> {
* Space Complexity: O(n)
*/
print(): void {
console.log([...this])
console.log([...this]);
}
protected abstract _getIterator(...args: any[]): IterableIterator<[K, V]>;
}
export abstract class IterableElementBase<V> {
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
@ -310,7 +308,7 @@ export abstract class IterableElementBase<V> {
forEach(callbackfn: ElementCallback<V, void>, thisArg?: any): void {
let index = 0;
for (const item of this) {
callbackfn.call(thisArg, item as V, index++, this)
callbackfn.call(thisArg, item as V, index++, this);
}
}
@ -335,18 +333,17 @@ export abstract class IterableElementBase<V> {
let accumulator = initialValue;
let index = 0;
for (const item of this) {
accumulator = callbackfn(accumulator, item as V, index++, this)
accumulator = callbackfn(accumulator, item as V, index++, this);
}
return accumulator;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(n)
*/
print(): void {
console.log([...this])
console.log([...this]);
}
protected abstract _getIterator(...args: any[]): IterableIterator<V>;

View file

@ -18,7 +18,11 @@ import type {
} from '../../types';
import { IBinaryTree } from '../../interfaces';
export class AVLTreeNode<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNodeNested<K, V>> extends BSTNode<K, V, N> {
export class AVLTreeNode<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNodeNested<K, V>> extends BSTNode<
K,
V,
N
> {
height: number;
constructor(key: K, value?: V) {
@ -36,10 +40,14 @@ export class AVLTreeNode<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLT
* 6. Complex Insertions and Deletions: Due to rebalancing, these operations are more complex than in a regular BST.
* 7. Path Length: The path length from the root to any leaf is longer compared to an unbalanced BST, but shorter than a linear chain of nodes.
*/
export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>, TREE extends AVLTree<K, V, N, TREE> = AVLTree<K, V, N, AVLTreeNested<K, V, N>>>
export class AVLTree<
K = any,
V = any,
N extends AVLTreeNode<K, V, N> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>,
TREE extends AVLTree<K, V, N, TREE> = AVLTree<K, V, N, AVLTreeNested<K, V, N>>
>
extends BST<K, V, N, TREE>
implements IBinaryTree<K, V, N, TREE> {
/**
* The constructor function initializes an AVLTree object with optional elements and options.
* @param [elements] - The `elements` parameter is an optional iterable of `BTNExemplar<K, V, N>`
@ -77,7 +85,8 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
override createTree(options?: AVLTreeOptions<K>): TREE {
return new AVLTree<K, V, N, TREE>([], {
iterationType: this.iterationType,
variant: this.variant, ...options
variant: this.variant,
...options
}) as TREE;
}
@ -97,7 +106,7 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
* @returns a boolean value indicating whether the potentialKey is of type number or not.
*/
override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
return !(potentialKey instanceof AVLTreeNode)
return !(potentialKey instanceof AVLTreeNode);
}
/**
@ -105,7 +114,6 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
*/
/**
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
@ -159,7 +167,6 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
return deletedResults;
}
/**
* The `_swapProperties` function swaps the key, value, and height properties between two nodes in a binary
* tree.
@ -489,6 +496,6 @@ export class AVLTree<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeN
protected _replaceNode(oldNode: N, newNode: N): N {
newNode.height = oldNode.height;
return super._replaceNode(oldNode, newNode)
return super._replaceNode(oldNode, newNode);
}
}

View file

@ -24,14 +24,18 @@ import { FamilyPosition, IterationType } from '../../types';
import { IBinaryTree } from '../../interfaces';
import { trampoline } from '../../utils';
import { Queue } from '../queue';
import { IterableEntryBase } from "../base";
import { IterableEntryBase } from '../base';
/**
* Represents a node in a binary tree.
* @template V - The type of data stored in the node.
* @template N - The type of the family relationship in the binary tree.
*/
export class BinaryTreeNode<K = any, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>> {
export class BinaryTreeNode<
K = any,
V = any,
N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>
> {
key: K;
value?: V;
@ -97,10 +101,15 @@ export class BinaryTreeNode<K = any, V = any, N extends BinaryTreeNode<K, V, N>
* 5. Leaf Nodes: Nodes without children are leaves.
*/
export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>, TREE extends BinaryTree<K, V, N, TREE> = BinaryTree<K, V, N, BinaryTreeNested<K, V, N>>> extends IterableEntryBase<K, V | undefined>
export class BinaryTree<
K = any,
V = any,
N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>,
TREE extends BinaryTree<K, V, N, TREE> = BinaryTree<K, V, N, BinaryTreeNested<K, V, N>>
>
extends IterableEntryBase<K, V | undefined>
implements IBinaryTree<K, V, N, TREE> {
iterationType = IterationType.ITERATIVE
iterationType = IterationType.ITERATIVE;
/**
* The constructor function initializes a binary tree object with optional elements and options.
@ -128,7 +137,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
if (elements) this.addMany(elements);
}
protected _extractor = (key: K) => Number(key)
protected _extractor = (key: K) => Number(key);
get extractor() {
return this._extractor;
@ -287,7 +296,6 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
return undefined; // If the insertion position cannot be found, return undefined
}
/**
* Time Complexity: O(k log n) - O(k * n)
* Space Complexity: O(1)
@ -329,7 +337,6 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
return inserted;
}
/**
* Time Complexity: O(k * n) "n" is the number of nodes in the tree, and "k" is the number of keys to be inserted.
* Space Complexity: O(1)
@ -985,10 +992,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
* @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
* is no leftmost node, it returns `null` or `undefined` depending on the input.
*/
getLeftMost(
beginRoot: BTNKeyOrNode<K, N> = this.root,
iterationType = this.iterationType
): N | null | undefined {
getLeftMost(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): N | null | undefined {
beginRoot = this.ensureNode(beginRoot);
if (!beginRoot) return beginRoot;
@ -1031,10 +1035,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
* @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
* is no rightmost node, it returns `null` or `undefined`, depending on the input.
*/
getRightMost(
beginRoot: BTNKeyOrNode<K, N> = this.root,
iterationType = this.iterationType
): N | null | undefined {
getRightMost(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): N | null | undefined {
// TODO support get right most by passing key in
beginRoot = this.ensureNode(beginRoot);
if (!beginRoot) return beginRoot;
@ -1262,7 +1263,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
* @returns a boolean value indicating whether the potentialKey is of type number or not.
*/
isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
return !(potentialKey instanceof BinaryTreeNode)
return !(potentialKey instanceof BinaryTreeNode);
}
dfs<C extends BTNCallback<N>>(
@ -1637,7 +1638,6 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
* after the given node in the inorder traversal of the binary tree.
*/
getSuccessor(x?: K | N | null): N | null | undefined {
x = this.ensureNode(x);
if (!this.isRealNode(x)) return undefined;
@ -1858,11 +1858,14 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
beginRoot = this.ensureNode(beginRoot);
if (!beginRoot) return;
if (opts.isShowUndefined) console.log(`U for undefined
if (opts.isShowUndefined)
console.log(`U for undefined
`);
if (opts.isShowNull) console.log(`N for null
if (opts.isShowNull)
console.log(`N for null
`);
if (opts.isShowRedBlackNIL) console.log(`S for Sentinel Node
if (opts.isShowRedBlackNIL)
console.log(`S for Sentinel Node
`);
const display = (root: N | null | undefined): void => {
@ -1920,30 +1923,42 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
} else if (node !== null && node !== undefined) {
// Display logic of normal nodes
const key = node.key, line = isNaN(this.extractor(key)) ? 'S' : this.extractor(key).toString(),
const key = node.key,
line = isNaN(this.extractor(key)) ? 'S' : this.extractor(key).toString(),
width = line.length;
return _buildNodeDisplay(line, width, this._displayAux(node.left, options), this._displayAux(node.right, options))
return _buildNodeDisplay(
line,
width,
this._displayAux(node.left, options),
this._displayAux(node.right, options)
);
} else {
// For cases where none of the conditions are met, null, undefined, and NaN nodes are not displayed
const line = node === undefined ? 'U' : 'N', width = line.length;
const line = node === undefined ? 'U' : 'N',
width = line.length;
return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0])
return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0]);
}
function _buildNodeDisplay(line: string, width: number, left: NodeDisplayLayout, right: NodeDisplayLayout) {
const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
const firstLine = ' '.repeat(Math.max(0, leftMiddle + 1))
+ '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1))
+ line
+ '_'.repeat(Math.max(0, rightMiddle))
+ ' '.repeat(Math.max(0, rightWidth - rightMiddle));
const firstLine =
' '.repeat(Math.max(0, leftMiddle + 1)) +
'_'.repeat(Math.max(0, leftWidth - leftMiddle - 1)) +
line +
'_'.repeat(Math.max(0, rightMiddle)) +
' '.repeat(Math.max(0, rightWidth - rightMiddle));
const secondLine = (leftHeight > 0 ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1) : ' '.repeat(leftWidth))
+ ' '.repeat(width)
+ (rightHeight > 0 ? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1) : ' '.repeat(rightWidth));
const secondLine =
(leftHeight > 0
? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1)
: ' '.repeat(leftWidth)) +
' '.repeat(width) +
(rightHeight > 0
? ' '.repeat(rightMiddle) + '\\' + ' '.repeat(rightWidth - rightMiddle - 1)
: ' '.repeat(rightWidth));
const mergedLines = [firstLine, secondLine];
@ -1953,11 +1968,16 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
mergedLines.push(leftLine + ' '.repeat(width) + rightLine);
}
return <NodeDisplayLayout>[mergedLines, leftWidth + width + rightWidth, Math.max(leftHeight, rightHeight) + 2, leftWidth + Math.floor(width / 2)];
return <NodeDisplayLayout>[
mergedLines,
leftWidth + width + rightWidth,
Math.max(leftHeight, rightHeight) + 2,
leftWidth + Math.floor(width / 2)
];
}
}
protected _defaultOneParamCallback = (node: N | null | undefined) => node ? node.key : undefined;
protected _defaultOneParamCallback = (node: N | null | undefined) => (node ? node.key : undefined);
/**
* Swap the data of two nodes in the binary tree.

View file

@ -20,7 +20,11 @@ import { BinaryTree, BinaryTreeNode } from './binary-tree';
import { IBinaryTree } from '../../interfaces';
import { Queue } from '../queue';
export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<K, V, N> {
export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<
K,
V,
N
> {
override parent?: N;
constructor(key: K, value?: V) {
@ -80,11 +84,14 @@ export class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNeste
* 6. Balance Variability: Can become unbalanced; special types maintain balance.
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
*/
export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BSTNodeNested<K, V>>, TREE extends BST<K, V, N, TREE> = BST<K, V, N, BSTNested<K, V, N>>>
export class BST<
K = any,
V = any,
N extends BSTNode<K, V, N> = BSTNode<K, V, BSTNodeNested<K, V>>,
TREE extends BST<K, V, N, TREE> = BST<K, V, N, BSTNested<K, V, N>>
>
extends BinaryTree<K, V, N, TREE>
implements IBinaryTree<K, V, N, TREE> {
/**
* This is the constructor function for a binary search tree class in TypeScript, which initializes
* the tree with optional elements and options.
@ -114,7 +121,7 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
return this._root;
}
protected _variant = BSTVariant.MIN
protected _variant = BSTVariant.MIN;
get variant() {
return this._variant;
@ -142,7 +149,8 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
override createTree(options?: Partial<BSTOptions<K>>): TREE {
return new BST<K, V, N, TREE>([], {
iterationType: this.iterationType,
variant: this.variant, ...options
variant: this.variant,
...options
}) as TREE;
}
@ -155,7 +163,6 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
return exemplar instanceof BSTNode;
}
/**
* The function `exemplarToNode` takes an exemplar and returns a node if the exemplar is valid,
* otherwise it returns undefined.
@ -301,7 +308,7 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
const isRealBTNExemplar = (kve: BTNExemplar<K, V, N>): kve is BTNodePureExemplar<K, V, N> => {
if (kve === undefined || kve === null) return false;
return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
}
};
for (const kve of keysOrNodesOrEntries) {
isRealBTNExemplar(kve) && realBTNExemplars.push(kve);
@ -359,7 +366,6 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
return inserted;
}
/**
* Time Complexity: O(n log n) - Adding each element individually in a balanced tree.
* Space Complexity: O(n) - Additional space is required for the sorted array.
@ -398,7 +404,6 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
return current.key;
}
/**
* Time Complexity: O(log n) - Average case for a balanced tree.
* Space Complexity: O(1) - Constant space is used.
@ -450,7 +455,7 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
* @returns a boolean value indicating whether the potentialKey is of type number or not.
*/
override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
return !(potentialKey instanceof BSTNode)
return !(potentialKey instanceof BSTNode);
}
/**
@ -738,7 +743,6 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
return balanced;
}
protected _setRoot(v: N | undefined) {
if (v) {
v.parent = undefined;
@ -761,5 +765,4 @@ export class BST<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BS
return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq;
}
}

View file

@ -21,10 +21,11 @@ import {
import { BST, BSTNode } from './bst';
import { IBinaryTree } from '../../interfaces';
export class RedBlackTreeNode<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNodeNested<K, V>> extends BSTNode<
K, V,
N
> {
export class RedBlackTreeNode<
K = any,
V = any,
N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNodeNested<K, V>
> extends BSTNode<K, V, N> {
color: RBTNColor;
constructor(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK) {
@ -40,7 +41,12 @@ export class RedBlackTreeNode<K = any, V = any, N extends RedBlackTreeNode<K, V,
* 4. Red nodes must have black children.
* 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.
*/
export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>, TREE extends RedBlackTree<K, V, N, TREE> = RedBlackTree<K, V, N, RedBlackTreeNested<K, V, N>>>
export class RedBlackTree<
K = any,
V = any,
N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>,
TREE extends RedBlackTree<K, V, N, TREE> = RedBlackTree<K, V, N, RedBlackTreeNested<K, V, N>>
>
extends BST<K, V, N, TREE>
implements IBinaryTree<K, V, N, TREE> {
Sentinel: N = new RedBlackTreeNode<K, V>(NaN as K) as unknown as N;
@ -101,7 +107,8 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
override createTree(options?: RBTreeOptions<K>): TREE {
return new RedBlackTree<K, V, N, TREE>([], {
iterationType: this.iterationType,
variant: this.variant, ...options
variant: this.variant,
...options
}) as TREE;
}
@ -122,7 +129,7 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
* @returns a boolean value indicating whether the potentialKey is of type number or not.
*/
override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
return !(potentialKey instanceof RedBlackTreeNode)
return !(potentialKey instanceof RedBlackTreeNode);
}
/**
@ -191,12 +198,11 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
x = x?.right;
} else {
if (newNode !== x) {
this._replaceNode(x, newNode)
this._replaceNode(x, newNode);
}
return;
}
}
}
newNode.parent = y;
@ -649,6 +655,6 @@ export class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N>
protected _replaceNode(oldNode: N, newNode: N): N {
newNode.color = oldNode.color;
return super._replaceNode(oldNode, newNode)
return super._replaceNode(oldNode, newNode);
}
}

View file

@ -45,11 +45,14 @@ export class TreeMultimapNode<
/**
* The only distinction between a TreeMultimap and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.
*/
export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N> = TreeMultimapNode<K, V, TreeMultimapNodeNested<K, V>>,
TREE extends TreeMultimap<K, V, N, TREE> = TreeMultimap<K, V, N, TreeMultimapNested<K, V, N>>>
export class TreeMultimap<
K = any,
V = any,
N extends TreeMultimapNode<K, V, N> = TreeMultimapNode<K, V, TreeMultimapNodeNested<K, V>>,
TREE extends TreeMultimap<K, V, N, TREE> = TreeMultimap<K, V, N, TreeMultimapNested<K, V, N>>
>
extends AVLTree<K, V, N, TREE>
implements IBinaryTree<K, V, N, TREE> {
constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<TreeMultimapOptions<K>>) {
super([], options);
if (elements) this.addMany(elements);
@ -60,7 +63,7 @@ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N>
// TODO the _count is not accurate after nodes count modified
get count(): number {
let sum = 0;
this.subTreeTraverse(node => sum += node.count);
this.subTreeTraverse(node => (sum += node.count));
return sum;
}
@ -80,7 +83,8 @@ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N>
override createTree(options?: TreeMultimapOptions<K>): TREE {
return new TreeMultimap<K, V, N, TREE>([], {
iterationType: this.iterationType,
variant: this.variant, ...options
variant: this.variant,
...options
}) as TREE;
}
@ -101,7 +105,7 @@ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N>
* @returns a boolean value indicating whether the potentialKey is of type number or not.
*/
override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {
return !(potentialKey instanceof TreeMultimapNode)
return !(potentialKey instanceof TreeMultimapNode);
}
/**
@ -433,7 +437,7 @@ export class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N>
}
protected _replaceNode(oldNode: N, newNode: N): N {
newNode.count = oldNode.count + newNode.count
newNode.count = oldNode.count + newNode.count;
return super._replaceNode(oldNode, newNode);
}
}

View file

@ -7,7 +7,7 @@
*/
import type { DijkstraResult, EntryCallback, VertexKey } from '../../types';
import { uuidV4 } from '../../utils';
import { IterableEntryBase } from "../base";
import { IterableEntryBase } from '../base';
import { IGraph } from '../../interfaces';
import { Heap } from '../heap';
import { Queue } from '../queue';
@ -65,7 +65,9 @@ export abstract class AbstractGraph<
E = any,
VO extends AbstractVertex<V> = AbstractVertex<V>,
EO extends AbstractEdge<E> = AbstractEdge<E>
> extends IterableEntryBase<VertexKey, V | undefined> implements IGraph<V, E, VO, EO> {
>
extends IterableEntryBase<VertexKey, V | undefined>
implements IGraph<V, E, VO, EO> {
constructor() {
super();
}
@ -165,7 +167,7 @@ export abstract class AbstractGraph<
isVertexKey(potentialKey: any): potentialKey is VertexKey {
const potentialKeyType = typeof potentialKey;
return potentialKeyType === "string" || potentialKeyType === "number"
return potentialKeyType === 'string' || potentialKeyType === 'number';
}
/**
@ -662,7 +664,6 @@ export abstract class AbstractGraph<
getMinDist: boolean = false,
genPaths: boolean = false
): DijkstraResult<VO> {
let minDist = Infinity;
let minDest: VO | undefined = undefined;
let minPath: VO[] = [];
@ -1170,7 +1171,10 @@ export abstract class AbstractGraph<
const dfs = (vertex: VO, currentPath: VertexKey[], visited: Set<VO>) => {
if (visited.has(vertex)) {
if ((!isInclude2Cycle && currentPath.length > 2 || isInclude2Cycle && currentPath.length >= 2) && currentPath[0] === vertex.key) {
if (
((!isInclude2Cycle && currentPath.length > 2) || (isInclude2Cycle && currentPath.length >= 2)) &&
currentPath[0] === vertex.key
) {
cycles.push([...currentPath]);
}
return;
@ -1195,18 +1199,16 @@ export abstract class AbstractGraph<
const uniqueCycles = new Map<string, VertexKey[]>();
for (const cycle of cycles) {
const sorted = [...cycle].sort().toString()
const sorted = [...cycle].sort().toString();
if (uniqueCycles.has(sorted)) continue
if (uniqueCycles.has(sorted)) continue;
else {
uniqueCycles.set(sorted, cycle)
uniqueCycles.set(sorted, cycle);
}
}
// Convert the unique cycles back to an array
return [...uniqueCycles].map(cycleString =>
cycleString[1]
);
return [...uniqueCycles].map(cycleString => cycleString[1]);
}
/**

View file

@ -182,7 +182,6 @@ export class DirectedGraph<
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(E) where E is the number of edgeMap
* Space Complexity: O(1)
@ -248,7 +247,7 @@ export class DirectedGraph<
vertexKey = vertexOrKey;
} else {
vertex = vertexOrKey;
vertexKey = this._getVertexKey(vertexOrKey)
vertexKey = this._getVertexKey(vertexOrKey);
}
if (vertex) {
@ -600,7 +599,6 @@ export class DirectedGraph<
}
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)

View file

@ -84,7 +84,12 @@ export class MapGraph<
* @param {number} long - The `long` parameter represents the longitude coordinate of the vertex.
* @returns The method is returning a new instance of the `MapVertex` class, casted as type `VO`.
*/
override createVertex(key: VertexKey, value?: V, lat: number = this.originCoord[0], long: number = this.originCoord[1]): VO {
override createVertex(
key: VertexKey,
value?: V,
lat: number = this.originCoord[0],
long: number = this.originCoord[1]
): VO {
return new MapVertex(key, value, lat, long) as VO;
}

View file

@ -162,7 +162,6 @@ export class UndirectedGraph<
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(E), where E is the number of edgeMap incident to the given vertex.
* Space Complexity: O(1)
@ -192,7 +191,6 @@ export class UndirectedGraph<
if (oneSide && otherSide) {
return this.deleteEdgeBetween(oneSide, otherSide);
} else {
return;
}
@ -220,10 +218,10 @@ export class UndirectedGraph<
vertexKey = vertexOrKey;
} else {
vertex = vertexOrKey;
vertexKey = this._getVertexKey(vertexOrKey)
vertexKey = this._getVertexKey(vertexOrKey);
}
const neighbors = this.getNeighbors(vertexOrKey)
const neighbors = this.getNeighbors(vertexOrKey);
if (vertex) {
neighbors.forEach(neighbor => {
@ -234,9 +232,8 @@ export class UndirectedGraph<
});
this._edgeMap.set(neighbor, restEdges);
}
})
});
this._edgeMap.delete(vertex);
}
return this._vertexMap.delete(vertexKey);

View file

@ -27,9 +27,12 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* @param [options] - The `options` parameter is an optional object that can contain additional
* configuration options for the constructor. In this case, it has one property:
*/
constructor(elements: Iterable<[K, V]> = [], options?: {
hashFn: (key: K) => string
}) {
constructor(
elements: Iterable<[K, V]> = [],
options?: {
hashFn: (key: K) => string;
}
) {
super();
if (options) {
const { hashFn } = options;
@ -73,7 +76,6 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
this._size++;
}
this._objMap.set(key, value);
} else {
const strKey = this._getNoObjKey(key);
if (this._store[strKey] === undefined) {
@ -137,7 +139,7 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
delete(key: K): boolean {
if (this._isObjKey(key)) {
if (this._objMap.has(key)) {
this._size--
this._size--;
}
return this._objMap.delete(key);
@ -235,19 +237,19 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
protected _hashFn: (key: K) => string = (key: K) => String(key);
protected _isObjKey(key: any): key is (object | ((...args: any[]) => any)) {
protected _isObjKey(key: any): key is object | ((...args: any[]) => any) {
const keyType = typeof key;
return (keyType === 'object' || keyType === 'function') && key !== null
return (keyType === 'object' || keyType === 'function') && key !== null;
}
protected _getNoObjKey(key: K): string {
const keyType = typeof key;
let strKey: string;
if (keyType !== "string" && keyType !== "number" && keyType !== "symbol") {
if (keyType !== 'string' && keyType !== 'number' && keyType !== 'symbol') {
strKey = this._hashFn(key);
} else {
if (keyType === "number") {
if (keyType === 'number') {
// TODO numeric key should has its own hash
strKey = <string>key;
} else {
@ -264,7 +266,6 @@ export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
* 3. Time Complexity: Similar to HashMap, LinkedHashMap offers constant-time performance for get and put operations in most cases.
*/
export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};
protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();
protected _head: HashMapLinkedNode<K, V | undefined>;
@ -273,12 +274,13 @@ export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
protected _hashFn: (key: K) => string;
protected _objHashFn: (key: K) => object;
constructor(elements?: Iterable<[K, V]>, options: HashMapOptions<K> = {
hashFn: (key: K) => String(key),
objHashFn: (key: K) => (<object>key)
}) {
constructor(
elements?: Iterable<[K, V]>,
options: HashMapOptions<K> = {
hashFn: (key: K) => String(key),
objHashFn: (key: K) => <object>key
}
) {
super();
this._sentinel = <HashMapLinkedNode<K, V>>{};
this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;

View file

@ -31,13 +31,13 @@ export class Heap<E = any> extends IterableElementBase<E> {
} else {
return a - b;
}
}
};
if (options) {
this.options = options
this.options = options;
} else {
this.options = {
comparator: defaultComparator
}
};
}
if (elements) {
@ -225,7 +225,8 @@ export class Heap<E = any> extends IterableElementBase<E> {
// Auxiliary recursive function, traverses the binary heap according to the traversal order
const _dfs = (index: number) => {
const left = 2 * index + 1, right = left + 1;
const left = 2 * index + 1,
right = left + 1;
if (index < this.size) {
if (order === 'in') {
_dfs(left);
@ -380,7 +381,6 @@ export class Heap<E = any> extends IterableElementBase<E> {
* original Heap.
*/
map<T>(callback: ElementCallback<E, T>, comparator: Comparator<T>, thisArg?: any): Heap<T> {
const mappedHeap: Heap<T> = new Heap<T>([], { comparator: comparator });
let index = 0;
for (const el of this) {
@ -432,13 +432,10 @@ export class Heap<E = any> extends IterableElementBase<E> {
protected _sinkDown(index: number, halfLength: number): boolean {
const element = this.elements[index];
while (index < halfLength) {
let left = index << 1 | 1;
let left = (index << 1) | 1;
const right = left + 1;
let minItem = this.elements[left];
if (
right < this.elements.length &&
this.options.comparator(minItem, this.elements[right]) > 0
) {
if (right < this.elements.length && this.options.comparator(minItem, this.elements[right]) > 0) {
left = right;
minItem = this.elements[right];
}

View file

@ -29,7 +29,8 @@ export class MaxHeap<E = any> extends Heap<E> {
return b - a;
}
}
}) {
}
) {
super(elements, options);
}
}

View file

@ -29,7 +29,8 @@ export class MinHeap<E = any> extends Heap<E> {
return a - b;
}
}
}) {
}
) {
super(elements, options);
}
}

View file

@ -5,8 +5,8 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type { ElementCallback } from "../../types";
import { IterableElementBase } from "../base";
import type { ElementCallback } from '../../types';
import { IterableElementBase } from '../base';
export class SinglyLinkedListNode<E = any> {
value: E;
@ -715,7 +715,6 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
return filteredList;
}
/**
* Time Complexity: O(n), where n is the number of elements in the linked list.
* Space Complexity: O(n)

View file

@ -9,16 +9,17 @@ import type { PriorityQueueOptions } from '../../types';
import { PriorityQueue } from './priority-queue';
export class MinPriorityQueue<E = any> extends PriorityQueue<E> {
constructor(elements?: Iterable<E>,
options: PriorityQueueOptions<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');
} else {
return a - b;
}
}
}
constructor(
elements?: Iterable<E>,
options: PriorityQueueOptions<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');
} else {
return a - b;
}
}
}
) {
super(elements, options);
}

View file

@ -5,9 +5,9 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type { ElementCallback, IterableWithSizeOrLength } from "../../types";
import { IterableElementBase } from "../base";
import { calcMinUnitsRequired, rangeCheck } from "../../utils";
import type { ElementCallback, IterableWithSizeOrLength } from '../../types';
import { IterableElementBase } from '../base';
import { calcMinUnitsRequired, rangeCheck } from '../../utils';
/**
* 1. Operations at Both Ends: Supports adding and removing elements at both the front and back of the queue. This allows it to be used as a stack (last in, first out) and a queue (first in, first out).
@ -33,13 +33,15 @@ export class Deque<E> extends IterableElementBase<E> {
* @param bucketSize - The `bucketSize` parameter is the maximum number of elements that can be
* stored in each bucket. It determines the size of each bucket in the data structure.
*/
constructor(elements: IterableWithSizeOrLength<E> = [], bucketSize = (1 << 12)) {
constructor(elements: IterableWithSizeOrLength<E> = [], bucketSize = 1 << 12) {
super();
let _size: number;
if ('length' in elements) {
if (elements.length instanceof Function) _size = elements.length(); else _size = elements.length;
if (elements.length instanceof Function) _size = elements.length();
else _size = elements.length;
} else {
if (elements.size instanceof Function) _size = elements.size(); else _size = elements.size;
if (elements.size instanceof Function) _size = elements.size();
else _size = elements.size;
}
this._bucketSize = bucketSize;
@ -49,7 +51,7 @@ export class Deque<E> extends IterableElementBase<E> {
}
const needBucketNum = calcMinUnitsRequired(_size, this._bucketSize);
this._bucketFirst = this._bucketLast = (this._bucketCount >> 1) - (needBucketNum >> 1);
this._firstInBucket = this._lastInBucket = (this._bucketSize - _size % this._bucketSize) >> 1;
this._firstInBucket = this._lastInBucket = (this._bucketSize - (_size % this._bucketSize)) >> 1;
for (const element of elements) {
this.push(element);
@ -108,10 +110,7 @@ export class Deque<E> extends IterableElementBase<E> {
this._bucketLast = 0;
this._lastInBucket = 0;
}
if (
this._bucketLast === this._bucketFirst &&
this._lastInBucket === this._firstInBucket
) this._reallocate();
if (this._bucketLast === this._bucketFirst && this._lastInBucket === this._firstInBucket) this._reallocate();
}
this._size += 1;
this._buckets[this._bucketLast][this._lastInBucket] = element;
@ -175,10 +174,7 @@ export class Deque<E> extends IterableElementBase<E> {
this._bucketFirst = this._bucketCount - 1;
this._firstInBucket = this._bucketSize - 1;
}
if (
this._bucketFirst === this._bucketLast &&
this._firstInBucket === this._lastInBucket
) this._reallocate();
if (this._bucketFirst === this._bucketLast && this._firstInBucket === this._lastInBucket) this._reallocate();
}
this._size += 1;
this._buckets[this._bucketFirst][this._firstInBucket] = element;
@ -260,7 +256,6 @@ export class Deque<E> extends IterableElementBase<E> {
}
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
@ -278,14 +273,10 @@ export class Deque<E> extends IterableElementBase<E> {
*/
getAt(pos: number): E {
rangeCheck(pos, 0, this.size - 1);
const {
bucketIndex,
indexInBucket
} = this._getBucketAndPosition(pos);
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
return this._buckets[bucketIndex][indexInBucket]!;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
@ -303,10 +294,7 @@ export class Deque<E> extends IterableElementBase<E> {
*/
setAt(pos: number, element: E): boolean {
rangeCheck(pos, 0, this.size - 1);
const {
bucketIndex,
indexInBucket
} = this._getBucketAndPosition(pos);
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
this._buckets[bucketIndex][indexInBucket] = element;
return true;
}
@ -370,10 +358,7 @@ export class Deque<E> extends IterableElementBase<E> {
this.clear();
return 0;
}
const {
bucketIndex,
indexInBucket
} = this._getBucketAndPosition(pos);
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
this._bucketLast = bucketIndex;
this._lastInBucket = indexInBucket;
this._size = pos + 1;
@ -402,15 +387,9 @@ export class Deque<E> extends IterableElementBase<E> {
else if (pos === this.size - 1) this.pop();
else {
const length = this.size - 1;
let {
bucketIndex: curBucket,
indexInBucket: curPointer
} = this._getBucketAndPosition(pos);
let { bucketIndex: curBucket, indexInBucket: curPointer } = this._getBucketAndPosition(pos);
for (let i = pos; i < length; ++i) {
const {
bucketIndex: nextBucket,
indexInBucket: nextPointer
} = this._getBucketAndPosition(pos + 1);
const { bucketIndex: nextBucket, indexInBucket: nextPointer } = this._getBucketAndPosition(pos + 1);
this._buckets[curBucket][curPointer] = this._buckets[nextBucket][nextPointer];
curBucket = nextBucket;
curPointer = nextPointer;
@ -827,11 +806,11 @@ export class Deque<E> extends IterableElementBase<E> {
bucketIndex -= this._bucketCount;
}
indexInBucket = (overallIndex + 1) % this._bucketSize - 1;
indexInBucket = ((overallIndex + 1) % this._bucketSize) - 1;
if (indexInBucket < 0) {
indexInBucket = this._bucketSize - 1;
}
return { bucketIndex, indexInBucket };
}
}
}

View file

@ -4,7 +4,7 @@
* @class
*/
import type { ElementCallback } from '../../types';
import { IterableElementBase } from "../base";
import { IterableElementBase } from '../base';
import { SinglyLinkedList } from '../linked-list';
/**

View file

@ -5,10 +5,15 @@ import {
BinaryTreeNodeNested,
BinaryTreeOptions,
BTNCallback,
BTNExemplar,
BTNExemplar
} from '../types';
export interface IBinaryTree<K = number, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNodeNested<K, V>, TREE extends BinaryTree<K, V, N, TREE> = BinaryTreeNested<K, V, N>> {
export interface IBinaryTree<
K = number,
V = any,
N extends BinaryTreeNode<K, V, N> = BinaryTreeNodeNested<K, V>,
TREE extends BinaryTree<K, V, N, TREE> = BinaryTreeNested<K, V, N>
> {
createNode(key: K, value?: N['value']): N;
createTree(options?: Partial<BinaryTreeOptions<K>>): TREE;

View file

@ -1,6 +1,6 @@
export enum BSTVariant {
MIN = 'MIN',
MAX = 'MAX',
MAX = 'MAX'
}
export enum CP {
@ -46,15 +46,15 @@ export interface IterableWithLength<T> extends Iterable<T> {
length: number | ((...args: any[]) => number);
}
export type IterableWithSizeOrLength<T> = IterableWithSize<T> | IterableWithLength<T>
export type IterableWithSizeOrLength<T> = IterableWithSize<T> | IterableWithLength<T>;
export type BinaryTreePrintOptions = { isShowUndefined?: boolean, isShowNull?: boolean, isShowRedBlackNIL?: boolean }
export type BinaryTreePrintOptions = { isShowUndefined?: boolean; isShowNull?: boolean; isShowRedBlackNIL?: boolean };
export type BTNEntry<K, V> = [K | null | undefined, V | undefined];
export type BTNKeyOrNode<K, N> = K | null | undefined | N;
export type BTNExemplar<K, V, N> = BTNEntry<K, V> | BTNKeyOrNode<K, N>
export type BTNExemplar<K, V, N> = BTNEntry<K, V> | BTNKeyOrNode<K, N>;
export type BTNodePureKeyOrNode<K, N> = K | N;

View file

@ -1,6 +1,17 @@
import { IterableElementBase, IterableEntryBase } from "../../../data-structures";
import { IterableElementBase, IterableEntryBase } from '../../../data-structures';
export type EntryCallback<K, V, R> = (value: V, key: K, index: number, container: IterableEntryBase<K, V>) => R;
export type ElementCallback<V, R> = (element: V, index: number, container: IterableElementBase<V>) => R;
export type ReduceEntryCallback<K, V, R> = (accumulator: R, value: V, key: K, index: number, container: IterableEntryBase<K, V>) => R;
export type ReduceElementCallback<V, R> = (accumulator: R, element: V, index: number, container: IterableElementBase<V>) => R;
export type ReduceEntryCallback<K, V, R> = (
accumulator: R,
value: V,
key: K,
index: number,
container: IterableEntryBase<K, V>
) => R;
export type ReduceElementCallback<V, R> = (
accumulator: R,
element: V,
index: number,
container: IterableElementBase<V>
) => R;

View file

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

View file

@ -1,6 +1,7 @@
export type VertexKey = string | number;
export type DijkstraResult<V> = {
export type DijkstraResult<V> =
| {
distMap: Map<V, number>;
distPaths?: Map<V, V[]>;
preMap: Map<V, V | undefined>;
@ -8,4 +9,5 @@ export type DijkstraResult<V> = {
paths: V[][];
minDist: number;
minPath: V[];
} | undefined;
}
| undefined;

View file

@ -7,7 +7,7 @@ export type HashMapLinkedNode<K, V> = {
export type HashMapOptions<K> = {
hashFn: (key: K) => string;
objHashFn: (key: K) => object
}
objHashFn: (key: K) => object;
};
export type HashMapStoreItem<K, V> = { key: K, value: V };
export type HashMapStoreItem<K, V> = { key: K; value: V };

View file

@ -1,3 +1,3 @@
import { Comparator } from "../../common";
import { Comparator } from '../../common';
export type HeapOptions<T> = { comparator: Comparator<T> }
export type HeapOptions<T> = { comparator: Comparator<T> };

View file

@ -1,3 +1,3 @@
import { HeapOptions } from "../heap";
import { HeapOptions } from '../heap';
export type PriorityQueueOptions<T> = HeapOptions<T> & {}
export type PriorityQueueOptions<T> = HeapOptions<T> & {};

View file

@ -98,4 +98,5 @@ export const isWeakKey = (input: unknown): input is object => {
return (inputType === 'object' && input !== null) || inputType === 'function';
};
export const calcMinUnitsRequired = (totalQuantity: number, unitSize: number) => Math.floor((totalQuantity + unitSize - 1) / unitSize)
export const calcMinUnitsRequired = (totalQuantity: number, unitSize: number) =>
Math.floor((totalQuantity + unitSize - 1) / unitSize);

View file

@ -2,7 +2,24 @@ import { AVLTree, CP } from 'avl-tree-typed';
describe('AVL Tree Test', () => {
it('should perform various operations on a AVL Tree', () => {
const arr: [number, number][] = [[11, 11], [3, 3], [15, 15], [1, 1], [8, 8], [13, 13], [16, 16], [2, 2], [6, 6], [9, 9], [12, 12], [14, 14], [4, 4], [7, 7], [10, 10], [5, 5]];
const arr: [number, number][] = [
[11, 11],
[3, 3],
[15, 15],
[1, 1],
[8, 8],
[13, 13],
[16, 16],
[2, 2],
[6, 6],
[9, 9],
[12, 12],
[14, 14],
[4, 4],
[7, 7],
[10, 10],
[5, 5]
];
const tree = new AVLTree();
for (const i of arr) tree.add(i);

View file

@ -45,7 +45,7 @@ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & iterator`, () => {
rbTree.clear();
for (let i = 0; i < arr.length; i++) rbTree.add(arr[i]);
const entries = [...rbTree];
return entries.length === HUNDRED_THOUSAND
return entries.length === HUNDRED_THOUSAND;
});
export { suite };

View file

@ -22,25 +22,20 @@ const arrHundredThousand = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSA
suite
.add(`SRC PQ ${TEN_THOUSAND.toLocaleString()} add`, () => {
const pq = new SRCPriorityQueue<number>();
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
})
.add(`CJS PQ ${TEN_THOUSAND.toLocaleString()} add`, () => {
const pq = new CJSPriorityQueue<number>();
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
})
.add(`MJS PQ ${TEN_THOUSAND.toLocaleString()} add`, () => {
const pq = new MJSPriorityQueue<number>([], { comparator: (a, b) => b - a });
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
});
if (isCompetitor) {
suite.add(`CPT PQ ${TEN_THOUSAND.toLocaleString()} add`, () => {
const pq = new CPriorityQueue<number>();
for (let i = 0; i < TEN_THOUSAND; i++) pq.push(i);
});
@ -66,14 +61,14 @@ suite
for (let i = 0; i < TEN_THOUSAND; i++) pq.poll();
});
if (isCompetitor) {
suite.add(`CPT PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
const pq = new CPriorityQueue<number>();
suite
.add(`CPT PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
const pq = new CPriorityQueue<number>();
for (let i = 0; i < TEN_THOUSAND; i++) pq.push(i);
for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
})
for (let i = 0; i < TEN_THOUSAND; i++) pq.push(i);
for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
})
.add(`CPT OM ${HUNDRED_THOUSAND.toLocaleString()} add`, () => {
for (let i = 0; i < arrHundredThousand.length; i++) {
cOrderedMap.setElement(arrHundredThousand[i], arrHundredThousand[i]);

View file

@ -78,7 +78,6 @@ suite.add(`Native Set ${MILLION.toLocaleString()} add & has`, () => {
for (let i = 0; i < MILLION; i++) hs.add(i);
for (let i = 0; i < MILLION; i++) hs.has(i);
});
suite.add(`${MILLION.toLocaleString()} ObjKey set & get`, () => {
@ -86,7 +85,7 @@ suite.add(`${MILLION.toLocaleString()} ObjKey set & get`, () => {
const objKeys: [number, number][] = [];
for (let i = 0; i < MILLION; i++) {
const obj: [number, number] = [i, i];
objKeys.push(obj)
objKeys.push(obj);
hm.set(obj, i);
}
for (let i = 0; i < MILLION; i++) {
@ -99,7 +98,7 @@ suite.add(`Native Map ${MILLION.toLocaleString()} ObjKey set & get`, () => {
const objs: [number, number][] = [];
for (let i = 0; i < MILLION; i++) {
const obj: [number, number] = [i, i];
objs.push(obj)
objs.push(obj);
hm.set(obj, i);
}
for (let i = 0; i < MILLION; i++) {
@ -112,7 +111,7 @@ suite.add(`Native Set ${MILLION.toLocaleString()} ObjKey add & has`, () => {
const objs: [number, number][] = [];
for (let i = 0; i < MILLION; i++) {
const obj: [number, number] = [i, i];
objs.push(obj)
objs.push(obj);
hs.add(obj);
}
for (let i = 0; i < MILLION; i++) {

View file

@ -13,7 +13,6 @@ suite.add(`${MILLION.toLocaleString()} push`, () => {
for (let i = 0; i < MILLION; i++) list.push(i);
});
if (isCompetitor) {
suite.add(`CPT ${MILLION.toLocaleString()} push`, () => {
const list = new CLinkedList<number>();

View file

@ -19,14 +19,13 @@ if (isCompetitor) {
});
}
suite
.add(`${MILLION.toLocaleString()} push & pop`, () => {
const _deque = new Deque<number>();
suite.add(`${MILLION.toLocaleString()} push & pop`, () => {
const _deque = new Deque<number>();
for (let i = 0; i < MILLION; i++) _deque.push(i);
for (let i = 0; i < MILLION; i++) _deque.pop();
})
for (let i = 0; i < MILLION; i++) _deque.push(i);
for (let i = 0; i < MILLION; i++) _deque.pop();
})
.add(`${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => {
const _deque = new Deque<number>();

View file

@ -33,16 +33,17 @@ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => {
queue.shift();
}
});
suite.add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => {
const arr = new Array<number>();
suite
.add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => {
const arr = new Array<number>();
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
arr.push(i);
}
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
arr.shift();
}
})
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
arr.push(i);
}
for (let i = 0; i < HUNDRED_THOUSAND; i++) {
arr.shift();
}
})
.add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} push & pop`, () => {
const arr = new Array<number>();

View file

@ -5,20 +5,19 @@ import * as fastGlob from 'fast-glob';
import { Color, numberFix, render } from '../utils';
import { PerformanceTest } from './types';
const args = process.argv.slice(2);
const { GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW } = Color;
const getRelativePath = (file: string) => {
return path.relative(__dirname, file);
}
};
const coloredLabeled = (label: string, file: string) => {
const relativeFilePath = getRelativePath(file);
const directory = path.dirname(relativeFilePath);
const fileName = path.basename(relativeFilePath);
return `${BG_YELLOW} ${label} ${END} ${GRAY}${directory}/${END}${CYAN}${fileName}${END}`;
}
};
const parentDirectory = path.resolve(__dirname, '../..');
const reportDistPath = path.join(parentDirectory, 'benchmark');
@ -29,20 +28,19 @@ let testFiles: string[];
let isIndividual = false;
if (args.length > 0) {
console.log(`arguments: ${args.join(' ')}`)
console.log(`arguments: ${args.join(' ')}`);
testFiles = allFiles.filter(file =>
args.every(word => file.includes(word))
);
testFiles = allFiles.filter(file => args.every(word => file.includes(word)));
isIndividual = true;
console.log(`${testFiles.map(file => coloredLabeled('Matched', file)).join(`
`)}`);
console.log(
`${testFiles.map(file => coloredLabeled('Matched', file)).join(`
`)}`
);
} else {
isIndividual = false;
testFiles = allFiles;
}
const report: { [key: string]: any } = {};
let completedCount = 0;
@ -132,11 +130,12 @@ const composeReport = () => {
html += `</div>
</body>
</html>`;
if (!isIndividual) replaceMarkdownContent(
'[//]: # (No deletion!!! Start of Replace Section)', // Start tag
'[//]: # (No deletion!!! End of Replace Section)', // end identifier
htmlTables // New content to be inserted
);
if (!isIndividual)
replaceMarkdownContent(
'[//]: # (No deletion!!! Start of Replace Section)', // Start tag
'[//]: # (No deletion!!! End of Replace Section)', // end identifier
htmlTables // New content to be inserted
);
fs.writeFileSync(htmlFilePath, html);
console.log(`Performance ${BOLD}${GREEN}report${END} file generated in file://${BOLD}${GREEN}${htmlFilePath}${END}`);
};

View file

@ -318,13 +318,20 @@ describe('AVLTree iterative methods test', () => {
test('filter should return a new tree with filtered elements', () => {
const filteredTree = avl.filter((value, key) => key > 1);
expect(filteredTree.size).toBe(2);
expect([...filteredTree]).toEqual([[2, 'b'], [3, 'c']]);
expect([...filteredTree]).toEqual([
[2, 'b'],
[3, 'c']
]);
});
test('map should return a new tree with modified elements', () => {
const mappedTree = avl.map((value, key) => (key * 2).toString());
expect(mappedTree.size).toBe(3);
expect([...mappedTree]).toEqual([[1, '2'], [2, '4'], [3, '6']]);
expect([...mappedTree]).toEqual([
[1, '2'],
[2, '4'],
[3, '6']
]);
});
test('reduce should accumulate values', () => {
@ -339,7 +346,11 @@ describe('AVLTree iterative methods test', () => {
}
expect(entries.length).toBe(3);
expect(entries).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
expect(entries).toEqual([
[1, 'a'],
[2, 'b'],
[3, 'c']
]);
});
test('should clone work well', () => {

View file

@ -265,7 +265,22 @@ describe('BinaryTree', () => {
tree.clear();
tree.addMany([-10, -10, -10, 9, 9, 20, null, null, 15, 7, 8, null, 2, null, 6, null, null, 8, 8, 8]);
expect(tree.bfs(node => node ? node.key : null, undefined, undefined, true)).toEqual([-10, 9, 20, null, null, 15, 7, 8, null, 2, null, 6, null, null])
expect(tree.bfs(node => (node ? node.key : null), undefined, undefined, true)).toEqual([
-10,
9,
20,
null,
null,
15,
7,
8,
null,
2,
null,
6,
null,
null
]);
});
});
@ -525,18 +540,12 @@ describe('BinaryTree', () => {
tree.add([3, 'B']);
tree.add([7, 'C']);
const nodes = tree.getNodes('B', (node) => node.value);
const nodes = tree.getNodes('B', node => node.value);
expect(nodes.length).toBe(1);
expect(nodes[0].key).toBe(3);
const nodesRec = tree.getNodes(
'B',
(node) => node.value,
false,
tree.root,
IterationType.RECURSIVE
);
const nodesRec = tree.getNodes('B', node => node.value, false, tree.root, IterationType.RECURSIVE);
expect(nodesRec.length).toBe(1);
expect(nodesRec[0].key).toBe(3);
@ -548,9 +557,17 @@ describe('BinaryTree', () => {
tree.add([7, 'C']);
tree.iterationType = IterationType.ITERATIVE;
expect([...tree]).toEqual([[3, "B"], [5, "A"], [7, "C"]]);
expect([...tree]).toEqual([
[3, 'B'],
[5, 'A'],
[7, 'C']
]);
tree.iterationType = IterationType.RECURSIVE;
expect([...tree]).toEqual([[3, "B"], [5, "A"], [7, "C"]]);
expect([...tree]).toEqual([
[3, 'B'],
[5, 'A'],
[7, 'C']
]);
tree.iterationType = IterationType.ITERATIVE;
const result = tree.morris();
@ -600,13 +617,20 @@ describe('BinaryTree iterative methods test', () => {
test('filter should return a new tree with filtered elements', () => {
const filteredTree = binaryTree.filter((value, key) => key > 1);
expect(filteredTree.size).toBe(2);
expect([...filteredTree]).toEqual([[3, 'c'], [2, 'b']]);
expect([...filteredTree]).toEqual([
[3, 'c'],
[2, 'b']
]);
});
test('map should return a new tree with modified elements', () => {
const mappedTree = binaryTree.map((value, key) => (key * 2).toString());
expect(mappedTree.size).toBe(3);
expect([...mappedTree]).toEqual([[1, '2'], [2, '4'], [3, '6']]);
expect([...mappedTree]).toEqual([
[1, '2'],
[2, '4'],
[3, '6']
]);
});
test('reduce should accumulate values', () => {
@ -621,7 +645,11 @@ describe('BinaryTree iterative methods test', () => {
}
expect(entries.length).toBe(3);
expect(entries).toEqual([[2, 'b'], [1, 'a'], [3, 'c']]);
expect(entries).toEqual([
[2, 'b'],
[1, 'a'],
[3, 'c']
]);
});
test('should clone work well', () => {
@ -641,17 +669,24 @@ describe('BinaryTree iterative methods test', () => {
});
test('should iterative method return undefined when the node is null', () => {
const tree = new BinaryTree()
const tree = new BinaryTree();
tree.addMany([-10, -10, -10, 9, 9, 20, null, null, 15, 7, 8, null, 2, null, 6, null, null, 8, 8, 8]);
const bfsResult = tree.bfs(undefined, undefined, undefined, true);
expect(bfsResult).toEqual([
-10, 9,
20, undefined,
undefined, 15,
7, 8,
undefined, 2,
undefined, 6,
undefined, undefined
-10,
9,
20,
undefined,
undefined,
15,
7,
8,
undefined,
2,
undefined,
6,
undefined,
undefined
]);
})
});
});
});

View file

@ -9,7 +9,22 @@ describe('BST operations test', () => {
expect(bst).toBeInstanceOf(BST);
bst.add([11, 11]);
bst.add([3, 3]);
const idsAndValues: [number, number][] = [[15, 15], [1, 1], [8, 8], [13, 13], [16, 16], [2, 2], [6, 6], [9, 9], [12, 12], [14, 14], [4, 4], [7, 7], [10, 10], [5, 5]];
const idsAndValues: [number, number][] = [
[15, 15],
[1, 1],
[8, 8],
[13, 13],
[16, 16],
[2, 2],
[6, 6],
[9, 9],
[12, 12],
[14, 14],
[4, 4],
[7, 7],
[10, 10],
[5, 5]
];
bst.addMany(idsAndValues, undefined, false);
expect(bst.root).toBeInstanceOf(BSTNode);
@ -194,22 +209,26 @@ describe('BST operations test', () => {
objBST.add([11, { name: '11', age: 11 }]);
objBST.add([3, { name: '3', age: 3 }]);
objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], [
{ "name": "Alice", "age": 15 },
{ "name": "Bob", "age": 1 },
{ "name": "Charlie", "age": 8 },
{ "name": "David", "age": 13 },
{ "name": "Emma", "age": 16 },
{ "name": "Frank", "age": 2 },
{ "name": "Grace", "age": 6 },
{ "name": "Hannah", "age": 9 },
{ "name": "Isaac", "age": 12 },
{ "name": "Jack", "age": 14 },
{ "name": "Katie", "age": 4 },
{ "name": "Liam", "age": 7 },
{ "name": "Mia", "age": 10 },
{ "name": "Noah", "age": 5 }
], false);
objBST.addMany(
[15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5],
[
{ name: 'Alice', age: 15 },
{ name: 'Bob', age: 1 },
{ name: 'Charlie', age: 8 },
{ name: 'David', age: 13 },
{ name: 'Emma', age: 16 },
{ name: 'Frank', age: 2 },
{ name: 'Grace', age: 6 },
{ name: 'Hannah', age: 9 },
{ name: 'Isaac', age: 12 },
{ name: 'Jack', age: 14 },
{ name: 'Katie', age: 4 },
{ name: 'Liam', age: 7 },
{ name: 'Mia', age: 10 },
{ name: 'Noah', age: 5 }
],
false
);
expect(objBST.root).toBeInstanceOf(BSTNode);
@ -596,11 +615,7 @@ describe('BST operations test recursively', () => {
[5, { key: 5, keyA: 5 }]
];
objBST.addMany(
entries,
undefined,
false
);
objBST.addMany(entries, undefined, false);
expect(objBST.root).toBeInstanceOf(BSTNode);
@ -878,13 +893,20 @@ describe('BST iterative methods test', () => {
test('filter should return a new tree with filtered elements', () => {
const filteredTree = bst.filter((value, key) => key > 1);
expect(filteredTree.size).toBe(2);
expect([...filteredTree]).toEqual([[2, 'b'], [3, 'c']]);
expect([...filteredTree]).toEqual([
[2, 'b'],
[3, 'c']
]);
});
test('map should return a new tree with modified elements', () => {
const mappedTree = bst.map((value, key) => (key * 2).toString());
expect(mappedTree.size).toBe(3);
expect([...mappedTree]).toEqual([[1, '2'], [2, '4'], [3, '6']]);
expect([...mappedTree]).toEqual([
[1, '2'],
[2, '4'],
[3, '6']
]);
});
test('reduce should accumulate values', () => {
@ -899,7 +921,11 @@ describe('BST iterative methods test', () => {
}
expect(entries.length).toBe(3);
expect(entries).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
expect(entries).toEqual([
[1, 'a'],
[2, 'b'],
[3, 'c']
]);
});
test('should clone work well', () => {
@ -917,4 +943,4 @@ describe('BST iterative methods test', () => {
const values = bst.values();
expect([...values]).toEqual(['a', 'b', 'c']);
});
});
});

View file

@ -33,24 +33,22 @@ describe('Overall BinaryTree Test', () => {
objBST.add([11, { key: 11, keyA: 11 }]);
objBST.add([3, { key: 3, keyA: 3 }]);
objBST.addMany(
[
[15, { key: 15, keyA: 15 }],
[1, { key: 1, keyA: 1 }],
[8, { key: 8, keyA: 8 }],
[13, { key: 13, keyA: 13 }],
[16, { key: 16, keyA: 16 }],
[2, { key: 2, keyA: 2 }],
[6, { key: 6, keyA: 6 }],
[9, { key: 9, keyA: 9 }],
[12, { key: 12, keyA: 12 }],
[14, { key: 14, keyA: 14 }],
[4, { key: 4, keyA: 4 }],
[7, { key: 7, keyA: 7 }],
[10, { key: 10, keyA: 10 }],
[5, { key: 5, keyA: 5 }]
]
);
objBST.addMany([
[15, { key: 15, keyA: 15 }],
[1, { key: 1, keyA: 1 }],
[8, { key: 8, keyA: 8 }],
[13, { key: 13, keyA: 13 }],
[16, { key: 16, keyA: 16 }],
[2, { key: 2, keyA: 2 }],
[6, { key: 6, keyA: 6 }],
[9, { key: 9, keyA: 9 }],
[12, { key: 12, keyA: 12 }],
[14, { key: 14, keyA: 14 }],
[4, { key: 4, keyA: 4 }],
[7, { key: 7, keyA: 7 }],
[10, { key: 10, keyA: 10 }],
[5, { key: 5, keyA: 5 }]
]);
objBST.delete(11);

View file

@ -501,9 +501,9 @@ describe('RedBlackTree', () => {
expect(tree.isAVLBalanced()).toBe(true);
tree.clear();
tree.addMany([10, 20, 30, 40, 50, 60])
tree.addMany([10, 20, 30, 40, 50, 60]);
expect(tree.isAVLBalanced()).toBe(false);
})
});
});
describe('RedBlackTree iterative methods test', () => {
@ -537,13 +537,20 @@ describe('RedBlackTree iterative methods test', () => {
test('filter should return a new tree with filtered elements', () => {
const filteredTree = rbTree.filter((value, key) => key > 1);
expect(filteredTree.size).toBe(2);
expect([...filteredTree]).toEqual([[2, 'b'], [3, 'c']]);
expect([...filteredTree]).toEqual([
[2, 'b'],
[3, 'c']
]);
});
test('map should return a new tree with modified elements', () => {
const mappedTree = rbTree.map((value, key) => (key * 2).toString());
expect(mappedTree.size).toBe(3);
expect([...mappedTree]).toEqual([[1, '2'], [2, '4'], [3, '6']]);
expect([...mappedTree]).toEqual([
[1, '2'],
[2, '4'],
[3, '6']
]);
});
test('reduce should accumulate values', () => {
@ -558,6 +565,10 @@ describe('RedBlackTree iterative methods test', () => {
}
expect(entries.length).toBe(3);
expect(entries).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
expect(entries).toEqual([
[1, 'a'],
[2, 'b'],
[3, 'c']
]);
});
});
});

View file

@ -15,21 +15,30 @@ describe('TreeMultimap count', () => {
let tm: TreeMultimap<number>;
beforeEach(() => {
tm = new TreeMultimap<number>();
})
});
it('Should added isolated node count ', () => {
tm.addMany([[1, 1], [2, 2], [3, 3], [4, 4], [5, 5]]);
tm.addMany([
[1, 1],
[2, 2],
[3, 3],
[4, 4],
[5, 5]
]);
const newNode = new TreeMultimapNode(3, 33, 10);
tm.add(newNode);
expect(tm.count).toBe(15)
})
expect(tm.count).toBe(15);
});
it('Should count', () => {
tm.addMany([[1, 1], [2, 2], [3, 3]]);
tm.lesserOrGreaterTraverse(node => node.count += 2, CP.gt, 1);
expect(tm.count).toBe(7)
})
})
tm.addMany([
[1, 1],
[2, 2],
[3, 3]
]);
tm.lesserOrGreaterTraverse(node => (node.count += 2), CP.gt, 1);
expect(tm.count).toBe(7);
});
});
describe('TreeMultimap operations test1', () => {
it('should perform various operations on a Binary Search Tree with numeric values1', () => {
@ -256,7 +265,7 @@ describe('TreeMultimap operations test1', () => {
expect(objTreeMultimap).toBeInstanceOf(TreeMultimap);
objTreeMultimap.add([11, { key: 11, keyA: 11 }]);
objTreeMultimap.add([3, { key: 3, keyA: 3 }]);
const values: [number, { key: number, keyA: number }][] = [
const values: [number, { key: number; keyA: number }][] = [
[15, { key: 15, keyA: 15 }],
[1, { key: 1, keyA: 1 }],
[8, { key: 8, keyA: 8 }],
@ -273,9 +282,7 @@ describe('TreeMultimap operations test1', () => {
[5, { key: 5, keyA: 5 }]
];
objTreeMultimap.addMany(
values
);
objTreeMultimap.addMany(values);
expect(objTreeMultimap.root).toBeInstanceOf(TreeMultimapNode);
@ -529,9 +536,7 @@ describe('TreeMultimap operations test recursively1', () => {
[5, { key: 5, keyA: 5 }]
];
objTreeMultimap.addMany(
values
);
objTreeMultimap.addMany(values);
expect(objTreeMultimap.root).toBeInstanceOf(TreeMultimapNode);
@ -632,13 +637,20 @@ describe('TreeMultimap iterative methods test', () => {
test('filter should return a new tree with filtered elements', () => {
const filteredTree = treeMM.filter((value, key) => key > 1);
expect(filteredTree.size).toBe(2);
expect([...filteredTree]).toEqual([[2, 'b'], [3, 'c']]);
expect([...filteredTree]).toEqual([
[2, 'b'],
[3, 'c']
]);
});
test('map should return a new tree with modified elements', () => {
const mappedTree = treeMM.map((value, key) => (key * 2).toString());
expect(mappedTree.size).toBe(3);
expect([...mappedTree]).toEqual([[1, '2'], [2, '4'], [3, '6']]);
expect([...mappedTree]).toEqual([
[1, '2'],
[2, '4'],
[3, '6']
]);
});
test('reduce should accumulate values', () => {
@ -653,11 +665,15 @@ describe('TreeMultimap iterative methods test', () => {
}
expect(entries.length).toBe(3);
expect(entries).toEqual([[1, 'a'], [2, 'b'], [3, 'c']]);
expect(entries).toEqual([
[1, 'a'],
[2, 'b'],
[3, 'c']
]);
});
test('should clone work well', () => {
expect(treeMM.count).toBe(21)
expect(treeMM.count).toBe(21);
const cloned = treeMM.clone();
expect(cloned.root?.left?.key).toBe(1);
expect(cloned.root?.right?.value).toBe('c');

View file

@ -378,11 +378,61 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
expect(predecessor).toBeInstanceOf(Array);
expect(predecessor.length).toBe(9);
expect(predecessor[0]).toEqual([vertex2, undefined, vertex2, undefined, vertex3, undefined, vertex4, undefined, undefined]);
expect(predecessor[1]).toEqual([undefined, vertex1, undefined, vertex1, vertex3, undefined, vertex4, undefined, vertex1]);
expect(predecessor[5]).toEqual([undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]);
expect(predecessor[7]).toEqual([undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]);
expect(predecessor[8]).toEqual([vertex7, vertex7, vertex7, vertex7, vertex7, undefined, undefined, undefined, vertex7]);
expect(predecessor[0]).toEqual([
vertex2,
undefined,
vertex2,
undefined,
vertex3,
undefined,
vertex4,
undefined,
undefined
]);
expect(predecessor[1]).toEqual([
undefined,
vertex1,
undefined,
vertex1,
vertex3,
undefined,
vertex4,
undefined,
vertex1
]);
expect(predecessor[5]).toEqual([
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined
]);
expect(predecessor[7]).toEqual([
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined,
undefined
]);
expect(predecessor[8]).toEqual([
vertex7,
vertex7,
vertex7,
vertex7,
vertex7,
undefined,
undefined,
undefined,
vertex7
]);
}
const dijkstraRes12tt = myGraph.dijkstra(1, 2, true, true);
@ -622,7 +672,10 @@ describe('DirectedGraph iterative Methods', () => {
test('filter should return vertexMap that satisfy the condition', () => {
const filtered = graph.filter((value, vertex) => vertex === 'A' || vertex === 'B');
expect(filtered).toEqual([["A", undefined], ["B", undefined]]);
expect(filtered).toEqual([
['A', undefined],
['B', undefined]
]);
});
test('map should apply a function to each vertex and return a new array', () => {
@ -637,53 +690,53 @@ describe('DirectedGraph iterative Methods', () => {
test('Removing an edge of a DirectedGraph should delete additional edges', () => {
const dg = new DirectedGraph();
dg.addVertex('hello')
dg.addVertex('hi')
dg.addVertex('hey')
dg.addEdge('hello', 'hi')
dg.addEdge('hello', 'hey')
expect(dg.getEdge('hello', 'hi')?.src).toBe('hello')
expect(dg.getEdge('hello', 'hi')?.dest).toBe('hi')
expect(dg.getEdge('hello', 'hey')?.src).toBe('hello')
expect(dg.getEdge('hello', 'hey')?.dest).toBe('hey')
dg.deleteEdge('hello', 'hi')
expect(dg.getEdge('hello', 'hi')).toBe(undefined)
expect(dg.getEdge('hello', 'hey')).toBeInstanceOf(DirectedEdge)
expect(dg.incomingEdgesOf("Hi")).toEqual([])
dg.addVertex('hello');
dg.addVertex('hi');
dg.addVertex('hey');
dg.addEdge('hello', 'hi');
dg.addEdge('hello', 'hey');
expect(dg.getEdge('hello', 'hi')?.src).toBe('hello');
expect(dg.getEdge('hello', 'hi')?.dest).toBe('hi');
expect(dg.getEdge('hello', 'hey')?.src).toBe('hello');
expect(dg.getEdge('hello', 'hey')?.dest).toBe('hey');
dg.deleteEdge('hello', 'hi');
expect(dg.getEdge('hello', 'hi')).toBe(undefined);
expect(dg.getEdge('hello', 'hey')).toBeInstanceOf(DirectedEdge);
expect(dg.incomingEdgesOf('Hi')).toEqual([]);
});
test('Removing a vertex of a DirectedGraph should delete additional edges', () => {
const graph = new DirectedGraph();
graph.addVertex("Hello");
graph.addVertex("Hi");
graph.addVertex('Hello');
graph.addVertex('Hi');
graph.addEdge("Hello", "Hi");
graph.deleteVertex("Hello");
graph.addEdge('Hello', 'Hi');
graph.deleteVertex('Hello');
expect(graph.incomingEdgesOf("Hi")).toEqual([]);
})
expect(graph.incomingEdgesOf('Hi')).toEqual([]);
});
test('Removing a vertex from a DirectedGraph should remove its edges', () => {
const dg = new DirectedGraph();
dg.addVertex('hello')
dg.addVertex('world')
dg.addVertex('earth')
dg.addVertex('hello');
dg.addVertex('world');
dg.addVertex('earth');
dg.addEdge('hello', 'world')
dg.addEdge('hello', 'earth')
dg.addEdge('world', 'earth')
dg.addEdge('hello', 'world');
dg.addEdge('hello', 'earth');
dg.addEdge('world', 'earth');
expect(dg.getEdge('hello', 'world')?.src).toBe('hello');
expect(dg.edgeSet().length).toBe(3)
expect(dg.edgeSet()[0].dest).toBe('world')
expect(dg.edgeSet().length).toBe(3);
expect(dg.edgeSet()[0].dest).toBe('world');
dg.deleteVertex('hello')
expect(dg.edgeSet().length).toBe(1)
expect(dg.edgeSet()?.[0].src).toBe('world')
dg.deleteVertex('hello');
expect(dg.edgeSet().length).toBe(1);
expect(dg.edgeSet()?.[0].src).toBe('world');
expect(dg.getEdge('hello', 'world')).toBe(undefined);
})
});
});
describe('DirectedGraph getCycles', () => {
@ -702,8 +755,8 @@ describe('DirectedGraph getCycles', () => {
graph.addEdge('E', 'B');
const cycles = graph.getCycles();
expect(cycles.length).toBe(1);
expect(cycles[0]).toEqual(["B", "D", "E"]);
})
expect(cycles[0]).toEqual(['B', 'D', 'E']);
});
test('should simple cycles graph getCycles return correct result', () => {
const graph = new DirectedGraph();
@ -719,8 +772,11 @@ describe('DirectedGraph getCycles', () => {
graph.addEdge('A', 'D');
graph.addEdge('D', 'C');
const cycles = graph.getCycles();
expect(cycles.length).toBe(2)
expect(cycles).toEqual([["A", "B", "C"], ["A", "D", "C"]])
expect(cycles.length).toBe(2);
expect(cycles).toEqual([
['A', 'B', 'C'],
['A', 'D', 'C']
]);
});
test('should 3 cycles graph getCycles return correct result', () => {
@ -746,8 +802,11 @@ describe('DirectedGraph getCycles', () => {
graph.addEdge('G', 'A');
const cycles = graph.getCycles();
expect(cycles.length).toBe(3)
expect(cycles).toEqual([["A", "C", "G"], ["B", "D", "E"], ["B", "F", "E"]]);
expect(cycles.length).toBe(3);
expect(cycles).toEqual([
['A', 'C', 'G'],
['B', 'D', 'E'],
['B', 'F', 'E']
]);
});
})
});

View file

@ -176,53 +176,52 @@ describe('UndirectedGraph', () => {
test('Removing an edge of a UndirectedGraph should not delete additional edges', () => {
const dg = new UndirectedGraph();
dg.addVertex('hello')
dg.addVertex('hi')
dg.addVertex('hey')
dg.addEdge('hello', 'hi')
dg.addEdge('hello', 'hey')
expect(dg.getEdge('hello', 'hi')?.vertexMap[0]).toBe('hello')
expect(dg.getEdge('hello', 'hi')?.vertexMap[1]).toBe('hi')
expect(dg.getEdge('hello', 'hey')?.vertexMap[0]).toBe('hello')
expect(dg.getEdge('hello', 'hey')?.vertexMap[1]).toBe('hey')
dg.deleteEdge('hello', 'hi')
expect(dg.getEdge('hello', 'hi')).toBe(undefined)
expect(dg.getEdge('hello', 'hey')).toBeInstanceOf(UndirectedEdge)
dg.addVertex('hello');
dg.addVertex('hi');
dg.addVertex('hey');
dg.addEdge('hello', 'hi');
dg.addEdge('hello', 'hey');
expect(dg.getEdge('hello', 'hi')?.vertexMap[0]).toBe('hello');
expect(dg.getEdge('hello', 'hi')?.vertexMap[1]).toBe('hi');
expect(dg.getEdge('hello', 'hey')?.vertexMap[0]).toBe('hello');
expect(dg.getEdge('hello', 'hey')?.vertexMap[1]).toBe('hey');
dg.deleteEdge('hello', 'hi');
expect(dg.getEdge('hello', 'hi')).toBe(undefined);
expect(dg.getEdge('hello', 'hey')).toBeInstanceOf(UndirectedEdge);
});
test('Removing a vertex of a DirectedGraph should delete additional edges', () => {
const graph = new UndirectedGraph();
graph.addVertex("Hello");
graph.addVertex("Hi");
graph.addVertex('Hello');
graph.addVertex('Hi');
graph.addEdge("Hello", "Hi");
graph.deleteVertex("Hello");
graph.addEdge('Hello', 'Hi');
graph.deleteVertex('Hello');
expect(graph.edgesOf("Hi")).toEqual([]);
})
expect(graph.edgesOf('Hi')).toEqual([]);
});
test('Removing a vertex from a UndirectedGraph should remove its edges', () => {
const dg = new UndirectedGraph();
dg.addVertex('hello')
dg.addVertex('world')
dg.addVertex('earth')
dg.addVertex('hello');
dg.addVertex('world');
dg.addVertex('earth');
dg.addEdge('hello', 'world')
dg.addEdge('hello', 'earth')
dg.addEdge('world', 'earth')
dg.addEdge('hello', 'world');
dg.addEdge('hello', 'earth');
dg.addEdge('world', 'earth');
expect(dg.getEdge('hello', 'world')?.vertexMap[0]).toBe('hello');
expect(dg.edgeSet().length).toBe(3)
expect(dg.edgeSet()[0].vertexMap).toEqual(['hello', 'world'])
expect(dg.edgeSet().length).toBe(3);
expect(dg.edgeSet()[0].vertexMap).toEqual(['hello', 'world']);
dg.deleteVertex('hello')
expect(dg.edgeSet().length).toBe(1)
expect(dg.edgeSet()?.[0].vertexMap[0]).toBe('world')
dg.deleteVertex('hello');
expect(dg.edgeSet().length).toBe(1);
expect(dg.edgeSet()?.[0].vertexMap[0]).toBe('world');
expect(dg.getEdge('hello', 'world')).toBe(undefined);
})
});
});
describe('cycles, strongly connected components, bridges, articular points in UndirectedGraph', () => {
@ -258,8 +257,7 @@ describe('cycles, strongly connected components, bridges, articular points in Un
expect(lowMap.size).toBe(8);
});
it("Should return Infinity if dest is not found", () => {
it('Should return Infinity if dest is not found', () => {
const graph = new UndirectedGraph<string>();
for (let i = 0; i < 3; ++i) {
@ -291,8 +289,12 @@ describe('UndirectedGraph getCycles', () => {
graph.addEdge('E', 'B');
const cycles = graph.getCycles();
expect(cycles.length).toBe(3);
expect(cycles).toEqual([["A", "B", "D", "C"], ["A", "B", "E", "D", "C"], ["B", "D", "E"]]);
})
expect(cycles).toEqual([
['A', 'B', 'D', 'C'],
['A', 'B', 'E', 'D', 'C'],
['B', 'D', 'E']
]);
});
test('should simple cycles graph getCycles return correct result', () => {
const graph = new UndirectedGraph();
@ -308,8 +310,12 @@ describe('UndirectedGraph getCycles', () => {
graph.addEdge('A', 'D');
graph.addEdge('D', 'C');
const cycles = graph.getCycles();
expect(cycles.length).toBe(3)
expect(cycles).toEqual([["A", "B", "C"], ["A", "B", "C", "D"], ["A", "C", "D"]])
expect(cycles.length).toBe(3);
expect(cycles).toEqual([
['A', 'B', 'C'],
['A', 'B', 'C', 'D'],
['A', 'C', 'D']
]);
});
test('should 3 cycles graph getCycles return correct result', () => {
@ -335,7 +341,18 @@ describe('UndirectedGraph getCycles', () => {
graph.addEdge('G', 'A');
const cycles = graph.getCycles();
expect(cycles.length).toBe(10)
expect(cycles).toEqual([["A", "B", "D", "C"], ["A", "B", "D", "C", "G"], ["A", "B", "E", "D", "C"], ["A", "B", "E", "D", "C", "G"], ["A", "B", "F", "E", "D", "C"], ["A", "B", "F", "E", "D", "C", "G"], ["A", "C", "G"], ["B", "D", "E"], ["B", "D", "E", "F"], ["B", "E", "F"]]);
expect(cycles.length).toBe(10);
expect(cycles).toEqual([
['A', 'B', 'D', 'C'],
['A', 'B', 'D', 'C', 'G'],
['A', 'B', 'E', 'D', 'C'],
['A', 'B', 'E', 'D', 'C', 'G'],
['A', 'B', 'F', 'E', 'D', 'C'],
['A', 'B', 'F', 'E', 'D', 'C', 'G'],
['A', 'C', 'G'],
['B', 'D', 'E'],
['B', 'D', 'E', 'F'],
['B', 'E', 'F']
]);
});
})
});

View file

@ -54,7 +54,6 @@ describe('HashMap Test1', () => {
hashMap.set('one', 1);
hashMap.set('two', 2);
hashMap.set('three', 3);
});
it('should resize the table when load factor is exceeded', () => {
@ -181,7 +180,6 @@ describe('HashMap Test2', () => {
}
compareHashMaps(hashMap, stdMap);
});
});
describe('HashMap for coordinate object keys', () => {
@ -207,30 +205,39 @@ describe('HashMap for coordinate object keys', () => {
test('delete elements in hash map', () => {
for (let i = 0; i < 1000; i++) {
if (i === 500) expect(hashMap.size).toBe(500)
if (i === 500) expect(hashMap.size).toBe(500);
const codObj = codObjs[i];
if (codObj) hashMap.delete(codObj);
}
expect(hashMap.size).toBe(0);
});
});
describe('HashMap setMany, keys, values', () => {
const hm: HashMap<number, number> = new HashMap<number, number>();
beforeEach(() => {
hm.clear()
hm.setMany([[2, 2], [3, 3], [4, 4], [5, 5]])
hm.setMany([[2, 2], [3, 3], [4, 4], [6, 6]])
})
hm.clear();
hm.setMany([
[2, 2],
[3, 3],
[4, 4],
[5, 5]
]);
hm.setMany([
[2, 2],
[3, 3],
[4, 4],
[6, 6]
]);
});
test('keys', () => {
expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6])
expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6]);
});
test('values', () => {
expect([...hm.values()]).toEqual([2, 3, 4, 5, 6])
expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]);
});
});
@ -245,7 +252,7 @@ describe('HashMap HOF', () => {
});
test('every() returns true if all elements match the condition', () => {
expect(hashMap.every((value) => typeof value === 'string')).toBe(true);
expect(hashMap.every(value => typeof value === 'string')).toBe(true);
});
test('some() returns true if any element matches the condition', () => {
@ -259,7 +266,7 @@ describe('HashMap HOF', () => {
});
test('map() should transform each element', () => {
const newHashMap = hashMap.map((value) => value.toUpperCase());
const newHashMap = hashMap.map(value => value.toUpperCase());
expect(newHashMap.get('key1')).toBe('VALUE1');
});
@ -274,7 +281,6 @@ describe('HashMap HOF', () => {
});
});
describe('LinkedHashMap Test1', () => {
let hashMap: LinkedHashMap<string, number>;
@ -368,7 +374,6 @@ describe('LinkedHashMap Test1', () => {
// expect(hashMap.table[0].length).toBe(2);
});
// it('should handle number keys correctly', () => {
// const hm = new LinkedHashMap();
// hm.set(999, { a: '999Value' });
@ -529,50 +534,65 @@ describe('LinkedHashMap for coordinate object keys', () => {
test('delete elements in hash map', () => {
for (let i = 0; i < 1000; i++) {
if (i === 500) expect(hashMap.size).toBe(500)
if (i === 500) expect(hashMap.size).toBe(500);
const codObj = codObjs[i];
if (codObj) hashMap.delete(codObj);
}
expect(hashMap.size).toBe(0);
});
});
describe('LinkedHashMap setMany, keys, values', () => {
const hm: LinkedHashMap<number, number> = new LinkedHashMap<number, number>();
beforeEach(() => {
hm.clear()
hm.setMany([[2, 2], [3, 3], [4, 4], [5, 5]])
hm.setMany([[2, 2], [3, 3], [4, 4], [6, 6]])
})
hm.clear();
hm.setMany([
[2, 2],
[3, 3],
[4, 4],
[5, 5]
]);
hm.setMany([
[2, 2],
[3, 3],
[4, 4],
[6, 6]
]);
});
test('keys', () => {
expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6])
expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6]);
});
test('values', () => {
expect([...hm.values()]).toEqual([2, 3, 4, 5, 6])
expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]);
});
test('entries', () => {
expect([...hm.entries()]).toEqual([[2, 2], [3, 3], [4, 4], [5, 5], [6, 6]])
expect([...hm.entries()]).toEqual([
[2, 2],
[3, 3],
[4, 4],
[5, 5],
[6, 6]
]);
});
test('every', () => {
expect(hm.every(value => value > 4)).toBe(false)
expect(hm.every(value => value > 4)).toBe(false);
});
test('some', () => {
expect(hm.some(value => value > 6)).toBe(false)
expect(hm.some(value => value > 6)).toBe(false);
});
test('hasValue', () => {
expect(hm.hasValue(3)).toBe(true)
expect(hm.hasValue(7)).toBe(false)
expect(hm.hasValue(3)).toBe(true);
expect(hm.hasValue(7)).toBe(false);
});
test('print', () => {
hm.print();
});
});
});

View file

@ -185,7 +185,6 @@ describe('HashTable performance', function () {
});
});
describe('HashTable methods', () => {
let hashTable: HashTable<string, string>;
@ -215,7 +214,6 @@ describe('HashTable methods', () => {
// }
// });
test('filter should return a new HashTable with elements that satisfy the condition', () => {
const filtered = hashTable.filter(([key]) => key.endsWith('1') || key.endsWith('3'));
@ -237,6 +235,4 @@ describe('HashTable methods', () => {
expect(result).toBe('-value5-value7-value3-value4-value6-value0-value2-value8-value1-value9');
});
});

View file

@ -1,7 +1,6 @@
import { FibonacciHeap, MaxHeap, MinHeap } from '../../../../src';
import { logBigOMetricsWrap } from '../../../utils';
describe('Heap Operation Test', () => {
it('should numeric heap work well', function () {
const minNumHeap = new MinHeap<number>();

View file

@ -50,17 +50,15 @@ describe('MinHeap', () => {
expect(minHeap.isEmpty()).toBe(true);
});
const n = 100000;
it('should push & dfs', () => {
for (let i = 0; i < n; i++) {
minHeap.add(i);
}
expect(minHeap.dfs()[0]).toBe(0)
expect(minHeap.dfs()[999]).toBe(4126)
expect(minHeap.dfs()[0]).toBe(0);
expect(minHeap.dfs()[999]).toBe(4126);
});
});
describe('Heap iterative methods', () => {
@ -89,7 +87,10 @@ describe('Heap iterative methods', () => {
});
test('map method correctly maps elements', () => {
const result = heap.map(x => x / 10, (a: number, b: number) => a - b);
const result = heap.map(
x => x / 10,
(a: number, b: number) => a - b
);
expect([...result]).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
});

View file

@ -398,16 +398,15 @@ describe('DoublyLinkedList Operation Test', () => {
});
});
describe('iterable methods', () => {
it('should forEach, some, every, filter, map, reduce of the deque', () => {
const dl = new DoublyLinkedList<number>()
const dl = new DoublyLinkedList<number>();
dl.push(1);
dl.push(2);
dl.push(3);
const mockCallback = jest.fn();
dl.forEach((element) => {
dl.forEach(element => {
mockCallback(element);
});
@ -426,7 +425,7 @@ describe('iterable methods', () => {
});
test('values', () => {
const dl = new DoublyLinkedList<number>()
const dl = new DoublyLinkedList<number>();
dl.push(1);
dl.push(2);
dl.push(3);
@ -435,11 +434,11 @@ describe('iterable methods', () => {
dl.shift();
dl.pop();
dl.unshift(3);
expect([...dl.values()]).toEqual([3, 1])
})
expect([...dl.values()]).toEqual([3, 1]);
});
test('some', () => {
const dl = new DoublyLinkedList<number>()
const dl = new DoublyLinkedList<number>();
dl.push(1);
dl.push(2);
dl.push(3);
@ -448,7 +447,7 @@ describe('iterable methods', () => {
dl.shift();
dl.pop();
dl.unshift(3);
expect(dl.some(value => value > 1)).toBe(true)
expect(dl.some(value => value > 100)).toBe(false)
})
});
expect(dl.some(value => value > 1)).toBe(true);
expect(dl.some(value => value > 100)).toBe(false);
});
});

View file

@ -472,13 +472,12 @@ describe('SinglyLinkedList', () => {
});
});
describe('iterable methods', () => {
it('should forEach, some, every, filter, map, reduce of the deque', () => {
const sl = new SinglyLinkedList<number>([1, 2, 3])
const sl = new SinglyLinkedList<number>([1, 2, 3]);
const mockCallback = jest.fn();
sl.forEach((element) => {
sl.forEach(element => {
mockCallback(element);
});
@ -495,4 +494,4 @@ describe('iterable methods', () => {
expect([...sl.map(element => element * 2)]).toEqual([2, 4, 6]);
expect(sl.reduce((accumulator, element) => accumulator + element, 0)).toEqual(6);
});
});
});

View file

@ -63,7 +63,7 @@ describe('MaxPriorityQueue Operation Test', () => {
it('should correctly heapify an object array', () => {
const elements = [{ keyA: 5 }, { keyA: 3 }, { keyA: 7 }, { keyA: 1 }];
debugger
debugger;
const maxPQ = MaxPriorityQueue.heapify<{ keyA: number }>(elements, { comparator: (a, b) => b.keyA - a.keyA });
expect(maxPQ.poll()?.keyA).toBe(7);

View file

@ -31,7 +31,6 @@ describe('PriorityQueue Operation Test', () => {
expect(maxPriorityQueue.peek()).toBe(3);
expect(
PriorityQueue.heapify([3, 2, 1, 5, 6, 7, 8, 9, 10], {
comparator: (a, b) => a - b
}).toArray()
).toEqual([1, 3, 2, 5, 6, 7, 8, 9, 10]);

View file

@ -170,7 +170,6 @@ describe('Deque - Utility Operations', () => {
deque.print();
expect(consoleSpy).toHaveBeenCalledWith([1, 2]);
});
});
describe('Deque - Additional Operations', () => {
let deque: Deque<number>;
@ -229,7 +228,6 @@ describe('Deque - Additional Operations', () => {
expect(iterator.next().value).toBe(2);
expect(iterator.next().value).toBe(1);
});
});
describe('Deque - push Method', () => {
let deque: Deque<number>;
@ -264,7 +262,6 @@ describe('Deque - push Method', () => {
});
test('push should add an element and reallocate when last bucket and lastInBucket are at max', () => {
for (let i = 0; i < 100; i++) {
deque.push(i);
}
@ -303,8 +300,6 @@ describe('Deque - pop Method', () => {
const lastElement = deque.last;
expect(deque.pop()).toBe(lastElement);
}
});
});
describe('Deque - unshift Method', () => {
@ -368,6 +363,5 @@ describe('Deque - shift Method', () => {
const firstElement = deque.first;
expect(deque.shift()).toBe(firstElement);
}
});
});

View file

@ -241,4 +241,4 @@ describe('LinkedListQueue', () => {
queue.enqueue('B');
expect(queue.peek()).toBe('A');
});
});
});

View file

@ -66,7 +66,6 @@ describe('Stack', () => {
});
});
describe('Stack iterative methods', () => {
let stack: Stack<number>; // Declare a Stack instance
@ -88,7 +87,7 @@ describe('Stack iterative methods', () => {
test('should apply forEach to the stack', () => {
const result: number[] = [];
stack.forEach((element) => {
stack.forEach(element => {
result.push(element);
});
@ -96,14 +95,14 @@ describe('Stack iterative methods', () => {
});
test('should filter elements in the stack', () => {
const filteredStack = stack.filter((element) => element > 1);
const filteredStack = stack.filter(element => element > 1);
expect(filteredStack.size).toBe(2);
expect([...filteredStack]).toEqual([2, 3]);
});
test('should map elements in the stack', () => {
const mappedStack = stack.map((element) => element * 2);
const mappedStack = stack.map(element => element * 2);
expect(mappedStack.size).toBe(3);
expect([...mappedStack]).toEqual([2, 4, 6]);

View file

@ -17,122 +17,132 @@ import {
TreeMultimap,
Trie
} from '../../src';
import { isDebugTest } from "../config";
import { isDebugTest } from '../config';
const isDebug = isDebugTest;
const orgArr: number[] = [6, 1, 2, 7, 5, 3, 4, 9, 8];
const orgStrArr: string[] = [
"trie",
"trial",
"trick",
"trip",
"tree",
"trend",
"triangle",
"track",
"trace",
"transmit"
'trie',
'trial',
'trick',
'trip',
'tree',
'trend',
'triangle',
'track',
'trace',
'transmit'
];
const entries: [number, number][] = [
[6, 6],
[1, 1],
[2, 2],
[7, 7],
[5, 5],
[3, 3],
[4, 4],
[9, 9],
[8, 8]
];
const entries: [number, number][] = [[6, 6], [1, 1], [2, 2], [7, 7], [5, 5], [3, 3], [4, 4], [9, 9], [8, 8]];
describe('conversions', () => {
it('Array to Queue', () => {
const q = new Queue<number>(orgArr);
isDebug && q.print();
})
});
it('Array to Deque', () => {
const dq = new Deque<number>(orgArr);
isDebug && dq.print();
})
});
it('Array to SinglyLinkedList', () => {
const sl = new SinglyLinkedList<number>(orgArr);
isDebug && sl.print();
})
});
it('Array to DoublyLinkedList', () => {
const dl = new DoublyLinkedList<number>(orgArr);
isDebug && dl.print();
})
});
it('Array to Stack', () => {
const stack = new Stack<number>(orgArr);
isDebug && stack.print();
})
});
it('Array to MinHeap', () => {
const minHeap = new MinHeap<number>(orgArr);
isDebug && minHeap.print();
})
});
it('Array to MaxHeap', () => {
const maxHeap = new MaxHeap<number>(orgArr);
isDebug && maxHeap.print();
})
});
it('Array to MinPriorityQueue', () => {
const minPQ = new MinPriorityQueue<number>(orgArr);
isDebug && minPQ.print();
})
});
it('Array to MaxPriorityQueue', () => {
const maxPQ = new MaxPriorityQueue<number>(orgArr);
isDebug && maxPQ.print();
})
});
it('Entry Array to BinaryTree', () => {
const biTree = new BinaryTree<number>(entries);
isDebug && biTree.print();
})
});
it('Entry Array to BST', () => {
const bst = new BST<number>(entries);
expect(bst.size).toBe(9)
expect(bst.size).toBe(9);
isDebug && bst.print();
})
});
it('Entry Array to RedBlackTree', () => {
const rbTree = new RedBlackTree<number>(entries);
expect(rbTree.size).toBe(9)
expect(rbTree.size).toBe(9);
isDebug && rbTree.print();
})
});
it('Entry Array to AVLTree', () => {
const avl = new AVLTree<number>(entries);
expect(avl.size).toBe(9)
expect(avl.size).toBe(9);
isDebug && avl.print();
})
});
it('Entry Array to TreeMultimap', () => {
const treeMulti = new TreeMultimap<number>(entries);
expect(treeMulti.size).toBe(9)
expect(treeMulti.size).toBe(9);
isDebug && treeMulti.print();
})
});
it('HashMap to RedBlackTree', () => {
const hm = new HashMap(entries);
isDebug && hm.print()
isDebug && hm.print();
const rbTree = new RedBlackTree<number>(hm);
expect(rbTree.size).toBe(9)
expect(rbTree.size).toBe(9);
isDebug && rbTree.print();
})
});
it('PriorityQueue to BST', () => {
const pq = new MinPriorityQueue(orgArr);
isDebug && pq.print();
const bst = new BST<number>(pq);
expect(bst.size).toBe(9)
expect(bst.size).toBe(9);
isDebug && bst.print();
})
});
it('Deque to RedBlackTree', () => {
const dq = new Deque(orgArr);
isDebug && dq.print();
const rbTree = new RedBlackTree<number>(dq);
expect(rbTree.size).toBe(9)
expect(rbTree.size).toBe(9);
isDebug && rbTree.print();
})
});
it('Trie to Heap to Deque', () => {
const trie = new Trie(orgStrArr);
@ -146,11 +156,7 @@ describe('conversions', () => {
isDebug && dq.print();
const entries = dq.map((el, i) => <[number, string]>[i, el]);
const avl = new AVLTree<number, string>(entries);
expect(avl.size).toBe(10)
expect(avl.size).toBe(10);
isDebug && avl.print();
})
})
});
});

View file

@ -4,4 +4,4 @@ export const calcRunTime = (callback: (...args: any[]) => any) => {
const startTime = performance.now();
callback();
return performance.now() - startTime;
}
};