[binary-tree] Dynamically infer traversal method return values based on callback function results.

This commit is contained in:
Revone 2023-10-25 21:09:11 +08:00
parent e45854d3f4
commit 8df45c5c52
34 changed files with 145 additions and 108 deletions

36
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "data-structure-typed",
"version": "1.38.1",
"version": "1.38.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "data-structure-typed",
"version": "1.38.1",
"version": "1.38.2",
"license": "MIT",
"devDependencies": {
"@types/benchmark": "^2.1.3",
@ -15,17 +15,17 @@
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"auto-changelog": "^2.4.0",
"avl-tree-typed": "^1.38.1",
"avl-tree-typed": "^1.38.2",
"benchmark": "^2.1.4",
"binary-tree-typed": "^1.38.1",
"bst-typed": "^1.38.1",
"binary-tree-typed": "^1.38.2",
"bst-typed": "^1.38.2",
"dependency-cruiser": "^14.1.0",
"eslint": "^8.50.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"heap-typed": "^1.38.1",
"heap-typed": "^1.38.2",
"istanbul-badges-readme": "^1.8.5",
"jest": "^29.7.0",
"prettier": "^3.0.3",
@ -2728,9 +2728,9 @@
}
},
"node_modules/avl-tree-typed": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.38.1.tgz",
"integrity": "sha512-owzl0/cOijCKDyL8RAR+8Q2ibtqA+datgKQEbs1qNpCvMgYBtaytIgwyR68jYD+u7QGTXWYdO288H6NiKI0eTA==",
"version": "1.38.2",
"resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.38.2.tgz",
"integrity": "sha512-2P1DPzdnTuvENa6bGA7vqglC+Ae8GndRSX4H5JeB4V5ZVoiWFpSDL2lO4kRJJYbceL+hemx4Ge/MriGYKgXIfQ==",
"dev": true
},
"node_modules/babel-jest": {
@ -2924,9 +2924,9 @@
}
},
"node_modules/binary-tree-typed": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.38.1.tgz",
"integrity": "sha512-h4dBfVSaqUPfpVRHI7ZWUv3BSFYF9VtzoRu5X2rIq4se89QX+1cQTirQ7bCG0mDLJ9A4GfmEVMvQvvmVhorBEQ==",
"version": "1.38.2",
"resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.38.2.tgz",
"integrity": "sha512-odemWypyURZVq3qdegpaQDFydmt3sZA3uLHbcav3bBbnPj9WuMSIbOeOs21Nrj/yJHk1GrmlFRbPjYrrDXfdaw==",
"dev": true
},
"node_modules/brace-expansion": {
@ -3005,9 +3005,9 @@
}
},
"node_modules/bst-typed": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.38.1.tgz",
"integrity": "sha512-jNBmdOaSAApSx5iYo5ijunp3rtATcTmNOVnRiasCqKzSYTLfCJiGqIoXkDYMIFWK7hlgbAsVJkzTLciKf4RjcQ==",
"version": "1.38.2",
"resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.38.2.tgz",
"integrity": "sha512-BcTSvIbi8m5kEqzlS++YYlg2IgKhuqsX1mu200BLGq4d327vsQq9hY8TneuL54N4KAr4McR2GqpkDaHXQ3eTbw==",
"dev": true
},
"node_modules/buffer-from": {
@ -4756,9 +4756,9 @@
}
},
"node_modules/heap-typed": {
"version": "1.38.1",
"resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.38.1.tgz",
"integrity": "sha512-PvLlO5lSds9zOOX4GvVS2mgZfLk0f7Ev+++hYkGrlCqpcCGDsXVn+B0k/Jel0mkTXIK3zVkev2if7Cxsmk1pEQ==",
"version": "1.38.2",
"resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.38.2.tgz",
"integrity": "sha512-GVNHQlbQkuuZMpMBj8fvekI8ClHst3s8W1qozLragMLD/ndb+acumWCXeypR9gwgjDTneqOW6fAgpUMDDKOn9Q==",
"dev": true
},
"node_modules/html-escaper": {

View file

@ -61,17 +61,17 @@
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"auto-changelog": "^2.4.0",
"avl-tree-typed": "^1.38.1",
"avl-tree-typed": "^1.38.2",
"benchmark": "^2.1.4",
"binary-tree-typed": "^1.38.1",
"bst-typed": "^1.38.1",
"binary-tree-typed": "^1.38.2",
"bst-typed": "^1.38.2",
"dependency-cruiser": "^14.1.0",
"eslint": "^8.50.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"heap-typed": "^1.38.1",
"heap-typed": "^1.38.2",
"istanbul-badges-readme": "^1.8.5",
"jest": "^29.7.0",
"prettier": "^3.0.3",

View file

@ -152,7 +152,7 @@ export class AVLTree<N extends AVLTreeNode<N['val'], N> = AVLTreeNode> extends B
// Balance Restoration: If a balance issue is discovered after inserting a node, it requires balance restoration operations. Balance restoration includes four basic cases where rotation operations need to be performed to fix the balance:
switch (
this._balanceFactor(A) // second O(1)
) {
) {
case -2:
if (A && A.left) {
if (this._balanceFactor(A.left) <= 0) {

View file

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

View file

@ -407,7 +407,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
return -1;
}
const stack: { node: N; depth: number }[] = [{node: beginRoot, depth: 0}];
const stack: {node: N; depth: number}[] = [{node: beginRoot, depth: 0}];
let maxHeight = 0;
while (stack.length > 0) {
@ -512,9 +512,9 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* traverse the binary tree. It can have two possible values:
* @returns The function `getNodes` returns an array of nodes (`N[]`).
*/
getNodes(
getNodes<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
nodeProperty: BinaryTreeNodeKey | N,
callback: MapCallback<N> = this._defaultCallbackByKey,
callback: C = this._defaultCallbackByKey as C,
onlyOne = false,
beginRoot: N | null = this.root,
iterationType = this.iterationType
@ -570,9 +570,9 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* performed when searching for nodes in the binary tree. It can have one of the following values:
* @returns a boolean value.
*/
has(
has<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
nodeProperty: BinaryTreeNodeKey | N,
callback: MapCallback<N> = this._defaultCallbackByKey,
callback: C = this._defaultCallbackByKey as C,
beginRoot = this.root,
iterationType = this.iterationType
): boolean {
@ -595,9 +595,9 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* performed when searching for a node in the binary tree. It can have one of the following values:
* @returns either the found node (of type N) or null if no node is found.
*/
get(
get<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
nodeProperty: BinaryTreeNodeKey | N,
callback: MapCallback<N> = this._defaultCallbackByKey,
callback: C = this._defaultCallbackByKey as C,
beginRoot = this.root,
iterationType = this.iterationType
): N | null {
@ -761,11 +761,11 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* performed on the binary tree. It can have two possible values:
* @returns The function `subTreeTraverse` returns an array of `MapCallbackReturn<N>`.
*/
subTreeTraverse(
callback: MapCallback<N> = this._defaultCallbackByKey,
subTreeTraverse<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
callback: C = this._defaultCallbackByKey as C,
beginRoot: N | BinaryTreeNodeKey | null = this.root,
iterationType = this.iterationType
): MapCallbackReturn<N>[] {
): ReturnType<C>[] {
if (typeof beginRoot === 'number') beginRoot = this.get(beginRoot);
const ans: MapCallbackReturn<N>[] = [];
@ -808,12 +808,12 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* iteration used in the depth-first search algorithm. It can have two possible values:
* @returns The function `dfs` returns an array of `MapCallbackReturn<N>` values.
*/
dfs(
callback: MapCallback<N> = this._defaultCallbackByKey,
dfs<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
callback: C = this._defaultCallbackByKey as C,
pattern: DFSOrderPattern = 'in',
beginRoot: N | null = this.root,
iterationType: IterationType = IterationType.ITERATIVE
): MapCallbackReturn<N>[] {
): ReturnType<C>[] {
if (!beginRoot) return [];
const ans: MapCallbackReturn<N>[] = [];
if (iterationType === IterationType.RECURSIVE) {
@ -842,7 +842,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], 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();
@ -896,12 +896,12 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* in the breadth-first search (BFS) algorithm. It can have two possible values:
* @returns The function `bfs` returns an array of `BFSCallbackReturn<N>[]`.
*/
bfs(
callback: BFSCallback<N> = this._defaultCallbackByKey,
bfs<C extends BFSCallback<N> = BFSCallback<N, BinaryTreeNodeKey>>(
callback: C = this._defaultCallbackByKey as C,
withLevel: boolean = false,
beginRoot: N | null = this.root,
iterationType = this.iterationType
): BFSCallbackReturn<N>[] {
): ReturnType<C>[] {
if (!beginRoot) return [];
const ans: BFSCallbackReturn<N>[] = [];
@ -964,11 +964,11 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* `beginRoot` is `null`, an empty array will be returned.
* @returns The `morris` function returns an array of `MapCallbackReturn<N>` values.
*/
morris(
callback: MapCallback<N> = this._defaultCallbackByKey,
morris<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
callback: C = this._defaultCallbackByKey as C,
pattern: DFSOrderPattern = 'in',
beginRoot: N | null = this.root
): MapCallbackReturn<N>[] {
): ReturnType<C>[] {
if (beginRoot === null) return [];
const ans: MapCallbackReturn<N>[] = [];
@ -1078,7 +1078,7 @@ export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode>
* This is because the purpose of the Morris algorithm is to save space rather than permanently alter the tree's shape.
*/
protected _defaultCallbackByKey: MapCallback<N> = node => node.key;
protected _defaultCallbackByKey: (node: N) => number = node => node.key;
/**
* The function `_addTo` adds a new node to a binary tree if there is an available position.

View file

@ -238,9 +238,9 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* @returns either the first node that matches the given nodeProperty and callback, or null if no
* matching node is found.
*/
override get(
override get<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
nodeProperty: BinaryTreeNodeKey | N,
callback: MapCallback<N> = this._defaultCallbackByKey,
callback: C = this._defaultCallbackByKey as C,
beginRoot = this.root,
iterationType = this.iterationType
): N | null {
@ -289,9 +289,9 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* traverse the binary tree. It can have one of the following values:
* @returns an array of nodes (N[]).
*/
override getNodes(
override getNodes<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
nodeProperty: BinaryTreeNodeKey | N,
callback: MapCallback<N> = this._defaultCallbackByKey,
callback: C = this._defaultCallbackByKey as C,
onlyOne = false,
beginRoot: N | null = this.root,
iterationType = this.iterationType
@ -363,12 +363,12 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
* done recursively or iteratively. It can have two possible values:
* @returns The function `lesserOrGreaterTraverse` returns an array of `MapCallbackReturn<N>`.
*/
lesserOrGreaterTraverse(
callback: MapCallback<N> = this._defaultCallbackByKey,
lesserOrGreaterTraverse<C extends MapCallback<N> = MapCallback<N, BinaryTreeNodeKey>>(
callback: C = this._defaultCallbackByKey as C,
lesserOrGreater: CP = CP.lt,
targetNode: N | BinaryTreeNodeKey | null = this.root,
iterationType = this.iterationType
): MapCallbackReturn<N> {
): ReturnType<C>[] {
if (typeof targetNode === 'number') targetNode = this.get(targetNode);
const ans: MapCallbackReturn<N>[] = [];
if (!targetNode) return ans;

View file

@ -37,7 +37,8 @@ export class TreeMultisetNode<
*/
export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultisetNode>
extends AVLTree<N>
implements IBinaryTree<N> {
implements IBinaryTree<N>
{
/**
* The constructor function for a TreeMultiset class in TypeScript, which extends another class and sets an option to
* merge duplicated values.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -490,7 +490,7 @@ export class SinglyLinkedList<E = any> {
return count;
}
* [Symbol.iterator]() {
*[Symbol.iterator]() {
let current = this.head;
while (current) {

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
import {BinaryTreeNode} from '../../../data-structures';
import PropertyKeysOf = jest.PropertyKeysOf;
/**
* Enum representing different loop types.
@ -24,7 +25,7 @@ export enum FamilyPosition {
export type BinaryTreeNodeKey = number;
export type BFSCallback<N> = (node: N, level?: number) => any;
export type BFSCallback<N, D = any> = (node: N, level?: number) => D;
export type BFSCallbackReturn<N> = ReturnType<BFSCallback<N>>;

View file

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

View file

@ -2,7 +2,7 @@ export type Comparator<T> = (a: T, b: T) => number;
export type DFSOrderPattern = 'pre' | 'in' | 'post';
export type MapCallback<N> = (node: N) => any;
export type MapCallback<N, D = any> = (node: N) => D;
export type MapCallbackReturn<N> = ReturnType<MapCallback<N>>;

View file

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

View file

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

View file

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

View file

@ -38,8 +38,7 @@ describe('AVL Tree Test', () => {
expect(dfs[dfs.length - 1].key).toBe(16);
tree.perfectlyBalance();
const bfs: AVLTreeNode<number>[] = [];
tree.bfs(node => bfs.push(node));
const bfs = tree.bfs(node => node);
expect(tree.isPerfectlyBalanced()).toBe(true);
expect(bfs[0].key).toBe(8);
expect(bfs[bfs.length - 1].key).toBe(16);
@ -98,8 +97,7 @@ describe('AVL Tree Test', () => {
expect(tree.getHeight()).toBe(1);
expect(tree.isAVLBalanced()).toBe(true);
const lastBFSIds = new Array<number>();
tree.bfs(node => lastBFSIds.push(node.key));
const lastBFSIds = tree.bfs();
expect(lastBFSIds[0]).toBe(12);
expect(lastBFSIds[1]).toBe(2);
expect(lastBFSIds[2]).toBe(16);
@ -111,3 +109,22 @@ describe('AVL Tree Test', () => {
expect(lastBFSNodes[2].key).toBe(16);
});
});
describe('AVLTree APIs test', () => {
const avl = new AVLTree<AVLTreeNode<{id: number; text: string}>>();
beforeEach(() => {
avl.clear();
});
it('add', () => {
avl.add(1);
const node2 = new AVLTreeNode(2);
avl.add(node2);
const node3 = new AVLTreeNode(3, {id: 3, text: 'text3'});
avl.add(node3);
avl.add(node3, {id: 3, text: 'text33'});
const bfsRes = avl.bfs(node => node.key, false);
expect(bfsRes[0]).toBe(2);
});
});

View file

@ -1,4 +1,4 @@
import {BinaryTree, BinaryTreeNode} from '../../../../src';
import {AVLTree, AVLTreeNode, BinaryTree, BinaryTreeNode} from '../../../../src';
describe('BinaryTreeNode', () => {
it('should create an instance of BinaryTreeNode', () => {
@ -194,3 +194,22 @@ describe('BinaryTree Morris Traversal', () => {
expect(node1?.right).toBe(node3);
});
});
describe('BinaryTree APIs test', () => {
const avl = new AVLTree<AVLTreeNode<{id: number; text: string}>>();
beforeEach(() => {
avl.clear();
});
it('add', () => {
avl.add(1);
const node2 = new AVLTreeNode(2);
avl.add(node2);
const node3 = new AVLTreeNode(3, {id: 3, text: 'text3'});
avl.add(node3);
avl.add(node3, {id: 3, text: 'text33'});
const bfsRes = avl.bfs(node => node);
expect(bfsRes[0]?.key).toBe(2);
});
});

View file

@ -189,7 +189,7 @@ describe('BST operations test', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<BSTNode<{ key: number; keyA: number }>>();
const objBST = new BST<BSTNode<{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);

View file

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

View file

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

View file

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

View file

@ -3,7 +3,7 @@ import {bigO, magnitude} from '../../../utils';
describe('DoublyLinkedList Operation Test', () => {
let list: DoublyLinkedList<number>;
let objectList: DoublyLinkedList<{ keyA: number }>;
let objectList: DoublyLinkedList<{keyA: number}>;
beforeEach(() => {
list = new DoublyLinkedList();

View file

@ -3,10 +3,10 @@ import {bigO, magnitude} from '../../../utils';
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', () => {

View file

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

View file

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