mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
[binary-tree] Dynamically infer traversal method return values based on callback function results.
This commit is contained in:
parent
e45854d3f4
commit
8df45c5c52
36
package-lock.json
generated
36
package-lock.json
generated
|
@ -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": {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
export class TreeMap {
|
||||
}
|
||||
export class TreeMap {}
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
export class TreeSet {
|
||||
}
|
||||
export class TreeSet {}
|
||||
|
|
|
@ -490,7 +490,7 @@ export class SinglyLinkedList<E = any> {
|
|||
return count;
|
||||
}
|
||||
|
||||
* [Symbol.iterator]() {
|
||||
*[Symbol.iterator]() {
|
||||
let current = this.head;
|
||||
|
||||
while (current) {
|
||||
|
|
|
@ -14,7 +14,7 @@ export class MatrixNTI2D<V = any> {
|
|||
* given initial value or 0 if not provided.
|
||||
* @param options - An object containing the following properties:
|
||||
*/
|
||||
constructor(options: { row: number; col: number; initialVal?: V }) {
|
||||
constructor(options: {row: number; col: number; initialVal?: V}) {
|
||||
const {row, col, initialVal} = options;
|
||||
this._matrix = new Array(row).fill(undefined).map(() => new Array(col).fill(initialVal || 0));
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ export class Vector2D {
|
|||
public x: number = 0,
|
||||
public y: number = 0,
|
||||
public w: number = 1 // needed for matrix multiplication
|
||||
) {
|
||||
}
|
||||
) {}
|
||||
|
||||
/**
|
||||
* The function checks if the x and y values of a point are both zero.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>>;
|
||||
|
||||
|
|
|
@ -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[][];
|
||||
|
|
|
@ -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>>;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export type ToThunkFn = () => ReturnType<TrlFn>;
|
||||
export type Thunk = () => ReturnType<ToThunkFn> & { __THUNK__: symbol };
|
||||
export type Thunk = () => ReturnType<ToThunkFn> & {__THUNK__: symbol};
|
||||
export type TrlFn = (...args: any[]) => any;
|
||||
export type TrlAsyncFn = (...args: any[]) => any;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export type KeyValueObject = { [key: string]: any };
|
||||
export type KeyValueObject = {[key: string]: any};
|
||||
|
||||
export type KeyValueObjectWithKey = { [key: string]: any; key: string | number | symbol };
|
||||
export type KeyValueObjectWithKey = {[key: string]: any; key: string | number | symbol};
|
||||
|
||||
export type NonNumberNonObjectButDefined = string | boolean | symbol | null;
|
||||
|
||||
|
|
|
@ -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});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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});
|
||||
|
||||
|
|
|
@ -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});
|
||||
|
|
|
@ -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'});
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in a new issue