[project] generic naming standardized

This commit is contained in:
Revone 2023-09-26 13:50:40 +08:00
parent 89451d2c03
commit bd25485555
25 changed files with 559 additions and 624 deletions

416
README.md
View file

@ -5,6 +5,8 @@ Data Structures of Javascript & TypeScript.
A library that provides a variety of JavaScript and TypeScript data structures, as well as implementations of some
classic algorithms.
Do you envy languages like C++ with *std*, Python with *collections*, and Java with *java.util*? Well, no need to envy anymore! JavaScript and TypeScript now have *data-structure-typed*
![License](https://img.shields.io/badge/License-MIT-blue.svg)
![Language](https://img.shields.io/github/languages/top/zrwusa/data-structure-typed)
![GitHub release (latest by date)](https://img.shields.io/github/v/release/zrwusa/data-structure-typed)
@ -682,245 +684,183 @@ optimal approach to data structure design.
<table>
<thead>
<tr>
<th>Data Structure</th>
<th>C++ STL</th>
<th>java.util</th>
<th>Python collections</th>
<th>Data Structure Typed</th>
</tr>
<tr>
<th>Data Structure</th>
<th>C++ std</th>
<th>Data Structure Typed</th>
<th>java.util</th>
<th>Python collections</th>
</tr>
</thead>
<tbody>
<tr>
<td>Dynamic Array (ArrayList)</td>
<td>std::vector&lt;T&gt;</td>
<td>ArrayList&lt;E&gt;</td>
<td>list</td>
<td>Array</td>
</tr>
<tr>
<td>Linked List</td>
<td>std::list&lt;T&gt;</td>
<td>LinkedList&lt;E&gt;</td>
<td>deque</td>
<td>DoublyLinkedList</td>
</tr>
<tr>
<td>Set</td>
<td>std::set&lt;T&gt;</td>
<td>HashSet&lt;E&gt;</td>
<td>set</td>
<td>Set</td>
</tr>
<tr>
<td>Map</td>
<td>std::map&lt;K, V&gt;</td>
<td>HashMap&lt;K, V&gt;</td>
<td>dict</td>
<td>Map</td>
</tr>
<tr>
<td>Stack</td>
<td>std::stack&lt;T&gt;</td>
<td>Stack&lt;E&gt;</td>
<td>N/A</td>
<td>Stack</td>
</tr>
<tr>
<td>Queue</td>
<td>std::queue&lt;T&gt;</td>
<td>Queue&lt;E&gt;</td>
<td>N/A</td>
<td>Queue</td>
</tr>
<tr>
<td>Priority Queue</td>
<td>std::priority_queue&lt;T&gt;</td>
<td>PriorityQueue&lt;E&gt;</td>
<td>N/A</td>
<td>PriorityQueue</td>
</tr>
<tr>
<td>Hash Table</td>
<td>N/A</td>
<td>Hashtable</td>
<td>defaultdict</td>
<td>HashTable</td>
</tr>
<tr>
<td>Deque</td>
<td>std::deque&lt;T&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>Deque</td>
</tr>
<tr>
<td>Multiset</td>
<td>std::multiset&lt;T&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Multimap</td>
<td>std::multimap&lt;K, V&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Unordered Set</td>
<td>std::unordered_set&lt;T&gt;</td>
<td>HashSet&lt;E&gt;</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Unordered Multiset</td>
<td>std::unordered_multiset</td>
<td>N/A</td>
<td>Counter</td>
<td>N/A</td>
</tr>
<tr>
<td>Unordered Map</td>
<td>std::unordered_map&lt;K, V&gt;</td>
<td>HashMap&lt;K, V&gt;</td>
<td>defaultdict</td>
<td>N/A</td>
</tr>
<tr>
<td>Unordered Multimap</td>
<td>std::unordered_multimap&lt;K, V&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Bitset</td>
<td>std::bitset&lt;N&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Ordered Dictionary</td>
<td>N/A</td>
<td>N/A</td>
<td>OrderedDict</td>
<td>Map</td>
</tr>
<tr>
<td>Double-Ended Queue (Deque)</td>
<td>std::deque&lt;T&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>Deque</td>
</tr>
<tr>
<td>Linked Hash Set</td>
<td>N/A</td>
<td>LinkedHashSet&lt;E&gt;</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Linked Hash Map</td>
<td>N/A</td>
<td>LinkedHashMap&lt;K, V&gt;</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Sorted Set</td>
<td>N/A</td>
<td>TreeSet&lt;E&gt;</td>
<td>N/A</td>
<td>AVLTree, RBTree</td>
</tr>
<tr>
<td>Sorted Map</td>
<td>N/A</td>
<td>TreeMap&lt;K, V&gt;</td>
<td>N/A</td>
<td>AVLTree, RBTree</td>
</tr>
<tr>
<td>Tree Set</td>
<td>std::set</td>
<td>TreeSet&lt;E&gt;</td>
<td>N/A</td>
<td>AVLTree, RBTree</td>
</tr>
<tr>
<td>Tree Map</td>
<td>std::map&lt;K, V&gt;</td>
<td>TreeMap&lt;K, V&gt;</td>
<td>N/A</td>
<td>AVLTree, RBTree</td>
</tr>
<tr>
<td>Persistent Collections</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>unordered multiset</td>
<td>unordered multiset&lt;T&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Unordered Multimap</td>
<td>std::unordered_multimap&lt;K, V&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>N/A</td>
<td>LinkedBlockingQueue&lt;E&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>N/A</td>
<td>ConcurrentHashMap&lt;K, V&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>N/A</td>
<td>N/A</td>
<td>namedtuple</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>N/A</td>
<td>N/A</td>
<td>ChainMap</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>N/A</td>
<td>N/A</td>
<td>defaultdict</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>N/A</td>
<td>N/A</td>
<td>Counter</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Dynamic Array</td>
<td>std::vector&lt;T&gt;</td>
<td>Array&lt;E&gt;</td>
<td>ArrayList&lt;E&gt;</td>
<td>list</td>
</tr>
<tr>
<td>Linked List</td>
<td>std::list&lt;T&gt;</td>
<td>DoublyLinkedList&lt;E&gt;</td>
<td>LinkedList&lt;E&gt;</td>
<td>deque</td>
</tr>
<tr>
<td>Set</td>
<td>std::set&lt;T&gt;</td>
<td>Set</td>
<td>HashSet&lt;E&gt;</td>
<td>set</td>
</tr>
<tr>
<td>Map</td>
<td>std::map&lt;K, V&gt;</td>
<td>Map</td>
<td>HashMap&lt;K, V&gt;</td>
<td>dict</td>
</tr>
<tr>
<td>Unordered Map</td>
<td>std::unordered_map&lt;K, V&gt;</td>
<td>N/A</td>
<td>HashMap&lt;K, V&gt;</td>
<td>defaultdict</td>
</tr>
<tr>
<td>Unordered Set</td>
<td>std::unordered_set&lt;T&gt;</td>
<td>N/A</td>
<td>HashSet&lt;E&gt;</td>
<td>N/A</td>
</tr>
<tr>
<td>Queue</td>
<td>std::queue&lt;T&gt;</td>
<td>Queue</td>
<td>Queue&lt;E&gt;</td>
<td>N/A</td>
</tr>
<tr>
<td>Priority Queue</td>
<td>std::priority_queue&lt;T&gt;</td>
<td>PriorityQueue</td>
<td>PriorityQueue&lt;E&gt;</td>
<td>N/A</td>
</tr>
<tr>
<td>Stack</td>
<td>std::stack&lt;T&gt;</td>
<td>Stack</td>
<td>Stack&lt;E&gt;</td>
<td>N/A</td>
</tr>
<tr>
<td>Bitset</td>
<td>std::bitset&lt;N&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Deque</td>
<td>std::deque&lt;T&gt;</td>
<td>Deque</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Multiset</td>
<td>std::multiset&lt;T&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Multimap</td>
<td>std::multimap&lt;K, V&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Unordered Multiset</td>
<td>std::unordered_multiset</td>
<td>N/A</td>
<td>Counter</td>
<td>N/A</td>
</tr>
<tr>
<td>Ordered Dictionary</td>
<td>N/A</td>
<td>Map</td>
<td>N/A</td>
<td>OrderedDict</td>
</tr>
<tr>
<td>Double-Ended Queue (Deque)</td>
<td>std::deque&lt;T&gt;</td>
<td>Deque</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Linked Hash Set</td>
<td>N/A</td>
<td>N/A</td>
<td>LinkedHashSet&lt;E&gt;</td>
<td>N/A</td>
</tr>
<tr>
<td>Linked Hash Map</td>
<td>N/A</td>
<td>N/A</td>
<td>LinkedHashMap&lt;K, V&gt;</td>
<td>N/A</td>
</tr>
<tr>
<td>Sorted Set</td>
<td>N/A</td>
<td>AVLTree, RBTree</td>
<td>TreeSet&lt;E&gt;</td>
<td>N/A</td>
</tr>
<tr>
<td>Sorted Map</td>
<td>N/A</td>
<td>AVLTree, RBTree</td>
<td>TreeMap&lt;K, V&gt;</td>
<td>N/A</td>
</tr>
<tr>
<td>Tree Set</td>
<td>std::set</td>
<td>AVLTree, RBTree</td>
<td>TreeSet&lt;E&gt;</td>
<td>N/A</td>
</tr>
<tr>
<td>Persistent Collections</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>unordered multiset</td>
<td>unordered multiset&lt;T&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
<tr>
<td>Unordered Multimap</td>
<td>std::unordered_multimap&lt;K, V&gt;</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td>
</tr>
</tbody>
</table>

View file

@ -21,18 +21,18 @@ import {AbstractBinaryTreeOptions, FamilyPosition, LoopType} from '../../types';
import {IAbstractBinaryTree, IAbstractBinaryTreeNode} from '../../interfaces';
export abstract class AbstractBinaryTreeNode<
T = any,
NEIGHBOR extends AbstractBinaryTreeNode<T, NEIGHBOR> = AbstractBinaryTreeNodeNested<T>
> implements IAbstractBinaryTreeNode<T, NEIGHBOR>
V = any,
NEIGHBOR extends AbstractBinaryTreeNode<V, NEIGHBOR> = AbstractBinaryTreeNodeNested<V>
> implements IAbstractBinaryTreeNode<V, NEIGHBOR>
{
/**
* The constructor function initializes a BinaryTreeNode object with an id and an optional value.
* @param {BinaryTreeNodeId} id - The `id` parameter is of type `BinaryTreeNodeId` and represents the unique identifier
* of the binary tree node. It is used to distinguish one node from another in the binary tree.
* @param {T} [val] - The "val" parameter is an optional parameter of type T. It represents the value that will be
* @param {V} [val] - The "val" parameter is an optional parameter of type V. It represents the value that will be
* stored in the binary tree node. If no value is provided, it will be set to undefined.
*/
protected constructor(id: BinaryTreeNodeId, val?: T) {
protected constructor(id: BinaryTreeNodeId, val?: V) {
this._id = id;
this._val = val;
}
@ -47,13 +47,13 @@ export abstract class AbstractBinaryTreeNode<
this._id = v;
}
private _val: T | undefined;
private _val: V | undefined;
get val(): T | undefined {
get val(): V | undefined {
return this._val;
}
set val(value: T | undefined) {
set val(value: V | undefined) {
this._val = value;
}

View file

@ -9,11 +9,11 @@ import {BST, BSTNode} from './bst';
import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BinaryTreeNodeId} from '../../types';
import {IAVLTree, IAVLTreeNode} from '../../interfaces';
export class AVLTreeNode<T = any, NEIGHBOR extends AVLTreeNode<T, NEIGHBOR> = AVLTreeNodeNested<T>>
extends BSTNode<T, NEIGHBOR>
implements IAVLTreeNode<T, NEIGHBOR>
export class AVLTreeNode<V = any, NEIGHBOR extends AVLTreeNode<V, NEIGHBOR> = AVLTreeNodeNested<V>>
extends BSTNode<V, NEIGHBOR>
implements IAVLTreeNode<V, NEIGHBOR>
{
constructor(id: BinaryTreeNodeId, val?: T) {
constructor(id: BinaryTreeNodeId, val?: V) {
super(id, val);
}
}

View file

@ -10,11 +10,11 @@ import type {BinaryTreeNodeId, BinaryTreeNodeNested, BinaryTreeOptions} from '..
import {AbstractBinaryTree, AbstractBinaryTreeNode} from './abstract-binary-tree';
import {IBinaryTree, IBinaryTreeNode} from '../../interfaces';
export class BinaryTreeNode<T = any, NEIGHBOR extends BinaryTreeNode<T, NEIGHBOR> = BinaryTreeNodeNested<T>>
extends AbstractBinaryTreeNode<T, NEIGHBOR>
implements IBinaryTreeNode<T, NEIGHBOR>
export class BinaryTreeNode<V = any, NEIGHBOR extends BinaryTreeNode<V, NEIGHBOR> = BinaryTreeNodeNested<V>>
extends AbstractBinaryTreeNode<V, NEIGHBOR>
implements IBinaryTreeNode<V, NEIGHBOR>
{
constructor(id: BinaryTreeNodeId, val?: T) {
constructor(id: BinaryTreeNodeId, val?: V) {
super(id, val);
}
}

View file

@ -10,11 +10,11 @@ import {CP, LoopType} from '../../types';
import {BinaryTree, BinaryTreeNode} from './binary-tree';
import {IBST, IBSTNode} from '../../interfaces';
export class BSTNode<T = any, NEIGHBOR extends BSTNode<T, NEIGHBOR> = BSTNodeNested<T>>
extends BinaryTreeNode<T, NEIGHBOR>
implements IBSTNode<T, NEIGHBOR>
export class BSTNode<V = any, NEIGHBOR extends BSTNode<V, NEIGHBOR> = BSTNodeNested<V>>
extends BinaryTreeNode<V, NEIGHBOR>
implements IBSTNode<V, NEIGHBOR>
{
constructor(id: BinaryTreeNodeId, val?: T) {
constructor(id: BinaryTreeNodeId, val?: V) {
super(id, val);
}
}

View file

@ -2,13 +2,13 @@ import {BinaryTreeNodeId, RBColor, RBTreeNodeNested, RBTreeOptions} from '../../
import {IRBTree, IRBTreeNode} from '../../interfaces';
import {BST, BSTNode} from './bst';
export class RBTreeNode<T = any, NEIGHBOR extends RBTreeNode<T, NEIGHBOR> = RBTreeNodeNested<T>>
extends BSTNode<T, NEIGHBOR>
implements IRBTreeNode<T, NEIGHBOR>
export class RBTreeNode<V = any, NEIGHBOR extends RBTreeNode<V, NEIGHBOR> = RBTreeNodeNested<V>>
extends BSTNode<V, NEIGHBOR>
implements IRBTreeNode<V, NEIGHBOR>
{
private _color: RBColor;
constructor(id: BinaryTreeNodeId, val?: T) {
constructor(id: BinaryTreeNodeId, val?: V) {
super(id, val);
this._color = RBColor.RED;
}

View file

@ -10,21 +10,21 @@ import {BinaryTreeDeletedResult, CP, DFSOrderPattern, FamilyPosition, LoopType}
import {ITreeMultiset, ITreeMultisetNode} from '../../interfaces';
import {AVLTree, AVLTreeNode} from './avl-tree';
export class TreeMultisetNode<T = any, NEIGHBOR extends TreeMultisetNode<T, NEIGHBOR> = TreeMultisetNodeNested<T>>
extends AVLTreeNode<T, NEIGHBOR>
implements ITreeMultisetNode<T, NEIGHBOR>
export class TreeMultisetNode<V = any, NEIGHBOR extends TreeMultisetNode<V, NEIGHBOR> = TreeMultisetNodeNested<V>>
extends AVLTreeNode<V, NEIGHBOR>
implements ITreeMultisetNode<V, NEIGHBOR>
{
/**
* The constructor function initializes a BinaryTreeNode object with an id, value, and count.
* @param {BinaryTreeNodeId} id - The `id` parameter is of type `BinaryTreeNodeId` and represents the unique identifier
* of the binary tree node.
* @param {T} [val] - The `val` parameter is an optional parameter of type `T`. It represents the value of the binary
* @param {V} [val] - The `val` parameter is an optional parameter of type `V`. It represents the value of the binary
* tree node. If no value is provided, it will be `undefined`.
* @param {number} [count=1] - The `count` parameter is a number that represents the number of times a particular value
* occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`
* parameter when creating a new instance of the `BinaryTreeNode` class,
*/
constructor(id: BinaryTreeNodeId, val?: T, count = 1) {
constructor(id: BinaryTreeNodeId, val?: V, count = 1) {
super(id, val);
this._count = count;
}

View file

@ -1,5 +0,0 @@
// 操作 常见名称 Ada Java JavaScript C++ Python Perl PHP Ruby // 尾部插入 inject, snoc Append offerLast push push_back append push
array_push push // 头部插入 push, cons Prepend offerFirst unshift push_front appendleft unshift array_unshift unshift //
尾部删除 eject Delete_Last pollLast pop pop_back pop pop array_pop pop // 头部删除 pop Delete_First pollFirst shift pop_front
popleft shift array_shift shift // 查看尾部 Last_Element peekLast [length - 1] back [-1] $array[-1] end
last // 查看头部 First_Element peekFirst [0] front [0] $array[0] reset first

View file

@ -10,15 +10,15 @@ import {PriorityQueue} from '../priority-queue';
import type {DijkstraResult, VertexId} from '../../types';
import {IAbstractGraph} from '../../interfaces';
export abstract class AbstractVertex<T = any> {
export abstract class AbstractVertex<V = any> {
/**
* The function is a protected constructor that takes an id and an optional value as parameters.
* @param {VertexId} id - The `id` parameter is of type `VertexId` and represents the identifier of the vertex. It is
* used to uniquely identify the vertex object.
* @param {T} [val] - The parameter "val" is an optional parameter of type T. It is used to assign a value to the
* @param {V} [val] - The parameter "val" is an optional parameter of type V. It is used to assign a value to the
* vertex. If no value is provided, it will be set to undefined.
*/
protected constructor(id: VertexId, val?: T) {
protected constructor(id: VertexId, val?: V) {
this._id = id;
this._val = val;
}
@ -33,40 +33,40 @@ export abstract class AbstractVertex<T = any> {
this._id = v;
}
private _val: T | undefined;
private _val: V | undefined;
get val(): T | undefined {
get val(): V | undefined {
return this._val;
}
set val(value: T | undefined) {
set val(value: V | undefined) {
this._val = value;
}
}
export abstract class AbstractEdge<T = any> {
export abstract class AbstractEdge<V = any> {
/**
* The above function is a protected constructor that initializes the weight, value, and hash code properties of an
* object.
* @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the object. If
* a value is provided, it will be assigned to the `_weight` property. If no value is provided, the default value of 1
* will be assigned.
* @param {T} [val] - The `val` parameter is of type `T`, which means it can be any type. It is an optional parameter,
* @param {V} [val] - The `val` parameter is of type `V`, which means it can be any type. It is an optional parameter,
* meaning it can be omitted when creating an instance of the class.
*/
protected constructor(weight?: number, val?: T) {
protected constructor(weight?: number, val?: V) {
this._weight = weight !== undefined ? weight : 1;
this._val = val;
this._hashCode = uuidV4();
}
private _val: T | undefined;
private _val: V | undefined;
get val(): T | undefined {
get val(): V | undefined {
return this._val;
}
set val(value: T | undefined) {
set val(value: V | undefined) {
this._val = value;
}

View file

@ -10,20 +10,20 @@ import {AbstractEdge, AbstractGraph, AbstractVertex} from './abstract-graph';
import type {TopologicalStatus, VertexId} from '../../types';
import {IDirectedGraph} from '../../interfaces';
export class DirectedVertex<T = number> extends AbstractVertex<T> {
export class DirectedVertex<V = any> extends AbstractVertex<V> {
/**
* The constructor function initializes a vertex with an optional value.
* @param {VertexId} id - The `id` parameter is of type `VertexId` and represents the identifier of the vertex. It is
* used to uniquely identify the vertex within a graph or data structure.
* @param {T} [val] - The "val" parameter is an optional parameter of type T. It is used to initialize the value of the
* @param {V} [val] - The "val" parameter is an optional parameter of type V. It is used to initialize the value of the
* vertex. If no value is provided, the vertex will be initialized with a default value.
*/
constructor(id: VertexId, val?: T) {
constructor(id: VertexId, val?: V) {
super(id, val);
}
}
export class DirectedEdge<T = number> extends AbstractEdge<T> {
export class DirectedEdge<V = any> extends AbstractEdge<V> {
/**
* The constructor function initializes the source and destination vertices of an edge, along with an optional weight
* and value.
@ -32,10 +32,10 @@ export class DirectedEdge<T = number> extends AbstractEdge<T> {
* @param {VertexId} dest - The `dest` parameter represents the destination vertex of an edge. It is of type
* `VertexId`, which is likely a unique identifier for a vertex in a graph.
* @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge.
* @param {T} [val] - The `val` parameter is an optional parameter of type `T`. It represents the value associated with
* @param {V} [val] - The `val` parameter is an optional parameter of type `V`. It represents the value associated with
* the edge.
*/
constructor(src: VertexId, dest: VertexId, weight?: number, val?: T) {
constructor(src: VertexId, dest: VertexId, weight?: number, val?: V) {
super(weight, val);
this._src = src;
this._dest = dest;

View file

@ -1,7 +1,7 @@
import {MapGraphCoordinate, VertexId} from '../../types';
import {DirectedEdge, DirectedGraph, DirectedVertex} from './directed-graph';
export class MapVertex<T = any> extends DirectedVertex<T> {
export class MapVertex<V = any> extends DirectedVertex<V> {
/**
* The constructor function initializes an object with an id, latitude, longitude, and an optional value.
* @param {VertexId} id - The `id` parameter is of type `VertexId` and represents the identifier of the vertex.
@ -11,10 +11,10 @@ export class MapVertex<T = any> extends DirectedVertex<T> {
* @param {number} long - The "long" parameter represents the longitude of a location. Longitude is a geographic
* coordinate that specifies the east-west position of a point on the Earth's surface. It is measured in degrees, with
* values ranging from -180 to 180.
* @param {T} [val] - The "val" parameter is an optional value of type T. It is not required to be provided when
* @param {V} [val] - The "val" parameter is an optional value of type V. It is not required to be provided when
* creating an instance of the class.
*/
constructor(id: VertexId, lat: number, long: number, val?: T) {
constructor(id: VertexId, lat: number, long: number, val?: V) {
super(id, val);
this._lat = lat;
this._long = long;
@ -41,7 +41,7 @@ export class MapVertex<T = any> extends DirectedVertex<T> {
}
}
export class MapEdge<T = any> extends DirectedEdge<T> {
export class MapEdge<V = any> extends DirectedEdge<V> {
/**
* The constructor function initializes a new instance of a class with the given source, destination, weight, and
* value.
@ -49,10 +49,10 @@ export class MapEdge<T = any> extends DirectedEdge<T> {
* a graph.
* @param {VertexId} dest - The `dest` parameter is the identifier of the destination vertex for an edge.
* @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge.
* @param {T} [val] - The "val" parameter is an optional parameter of type T. It is used to store additional
* @param {V} [val] - The "val" parameter is an optional parameter of type V. It is used to store additional
* information or data associated with the edge.
*/
constructor(src: VertexId, dest: VertexId, weight?: number, val?: T) {
constructor(src: VertexId, dest: VertexId, weight?: number, val?: V) {
super(src, dest, weight, val);
}
}

View file

@ -10,20 +10,20 @@ import {AbstractEdge, AbstractGraph, AbstractVertex} from './abstract-graph';
import type {VertexId} from '../../types';
import {IUNDirectedGraph} from '../../interfaces';
export class UndirectedVertex<T = number> extends AbstractVertex<T> {
export class UndirectedVertex<V = any> extends AbstractVertex<V> {
/**
* The constructor function initializes a vertex with an optional value.
* @param {VertexId} id - The `id` parameter is of type `VertexId` and represents the identifier of the vertex. It is
* used to uniquely identify the vertex within a graph or network.
* @param {T} [val] - The "val" parameter is an optional parameter of type T. It is used to initialize the value of the
* @param {V} [val] - The "val" parameter is an optional parameter of type V. It is used to initialize the value of the
* vertex. If no value is provided, the vertex will be initialized with a default value.
*/
constructor(id: VertexId, val?: T) {
constructor(id: VertexId, val?: V) {
super(id, val);
}
}
export class UndirectedEdge<T = number> extends AbstractEdge<T> {
export class UndirectedEdge<V = number> extends AbstractEdge<V> {
/**
* The constructor function creates an instance of a class with two vertex IDs, an optional weight, and an optional
* value.
@ -31,10 +31,10 @@ export class UndirectedEdge<T = number> extends AbstractEdge<T> {
* @param {VertexId} v2 - The parameter `v2` is a `VertexId`, which represents the identifier of the second vertex in a
* graph edge.
* @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge.
* @param {T} [val] - The "val" parameter is an optional parameter of type T. It is used to store a value associated
* @param {V} [val] - The "val" parameter is an optional parameter of type V. It is used to store a value associated
* with the edge.
*/
constructor(v1: VertexId, v2: VertexId, weight?: number, val?: T) {
constructor(v1: VertexId, v2: VertexId, weight?: number, val?: V) {
super(weight, val);
this._vertices = [v1, v2];
}

View file

@ -8,15 +8,15 @@
import {PriorityQueue} from '../priority-queue';
import type {HeapOptions} from '../../types';
export class HeapItem<T = number> {
export class HeapItem<V = any> {
/**
* The constructor function initializes an instance of a class with a priority and a value.
* @param {number} priority - The `priority` parameter is a number that represents the priority of the value. It is
* optional and has a default value of `NaN`.
* @param {T | null} [val=null] - The `val` parameter is of type `T | null`, which means it can accept a value of type
* `T` or `null`.
* @param {V | null} [val=null] - The `val` parameter is of type `V | null`, which means it can accept a value of type
* `V` or `null`.
*/
constructor(priority: number = Number.MAX_SAFE_INTEGER, val: T | null = null) {
constructor(priority: number = Number.MAX_SAFE_INTEGER, val: V | null = null) {
this._val = val;
this._priority = priority;
}
@ -31,24 +31,24 @@ export class HeapItem<T = number> {
this._priority = value;
}
private _val: T | null;
private _val: V | null;
get val(): T | null {
get val(): V | null {
return this._val;
}
set val(value: T | null) {
set val(value: V | null) {
this._val = value;
}
}
export abstract class Heap<T = number> {
export abstract class Heap<V = number> {
/**
* The function is a constructor for a class that initializes a priority callback function based on the
* options provided.
* @param [options] - An optional object that contains configuration options for the Heap.
*/
protected constructor(options?: HeapOptions<T>) {
protected constructor(options?: HeapOptions<V>) {
if (options) {
const {priorityExtractor} = options;
if (priorityExtractor !== undefined && typeof priorityExtractor !== 'function') {
@ -60,13 +60,13 @@ export abstract class Heap<T = number> {
}
}
protected abstract _pq: PriorityQueue<HeapItem<T>>;
protected abstract _pq: PriorityQueue<HeapItem<V>>;
get pq() {
return this._pq;
}
protected _priorityExtractor: (val: T) => number;
protected _priorityExtractor: (val: V) => number;
get priorityExtractor() {
return this._priorityExtractor;
}
@ -87,30 +87,30 @@ export abstract class Heap<T = number> {
return this._pq.size < 1;
}
peek(isItem?: undefined): T | undefined;
peek(isItem: false): T | undefined;
peek(isItem: true): HeapItem<T> | null;
peek(isItem?: undefined): V | undefined;
peek(isItem: false): V | undefined;
peek(isItem: true): HeapItem<V> | null;
/**
* The `peek` function returns the top item in the priority queue without removing it.
* @returns The `peek()` method is returning either a `HeapItem<T>` object or `null`.Returns an val with the highest priority in the queue
* @returns The `peek()` method is returning either a `HeapItem<V>` object or `null`.Returns an val with the highest priority in the queue
*/
peek(isItem?: boolean): HeapItem<T> | null | T | undefined {
peek(isItem?: boolean): HeapItem<V> | null | V | undefined {
isItem = isItem ?? false;
const peeked = this._pq.peek();
return isItem ? peeked : peeked?.val;
}
peekLast(isItem?: undefined): T | undefined;
peekLast(isItem: false): T | undefined;
peekLast(isItem: true): HeapItem<T> | null;
peekLast(isItem?: undefined): V | undefined;
peekLast(isItem: false): V | undefined;
peekLast(isItem: true): HeapItem<V> | null;
/**
* The `peekLast` function returns the last item in the heap.
* @returns The method `peekLast()` returns either a `HeapItem<T>` object or `null`.Returns an val with the lowest priority in the queue
* @returns The method `peekLast()` returns either a `HeapItem<V>` object or `null`.Returns an val with the lowest priority in the queue
*/
peekLast(isItem?: boolean): HeapItem<T> | null | T | undefined {
peekLast(isItem?: boolean): HeapItem<V> | null | V | undefined {
isItem = isItem ?? false;
const leafItem = this._pq.leaf();
@ -119,7 +119,7 @@ export abstract class Heap<T = number> {
/**
* The `add` function adds an val to a priority queue with an optional priority value.
* @param {T} val - The `val` parameter represents the value that you want to add to the heap. It can be of any
* @param {V} val - The `val` parameter represents the value that you want to add to the heap. It can be of any
* type.
* @param {number} [priority] - The `priority` parameter is an optional number that represents the priority of the
* val being added to the heap. If the `val` parameter is a number, then the `priority` parameter is set to
@ -127,22 +127,22 @@ export abstract class Heap<T = number> {
* @returns The `add` method returns the instance of the `Heap` class.
* @throws {Error} if priority is not a valid number
*/
add(priority: number, val?: T): Heap<T> {
val = val === undefined ? (priority as unknown as T) : val;
this._pq.add(new HeapItem<T>(priority, val));
add(priority: number, val?: V): Heap<V> {
val = val === undefined ? (priority as unknown as V) : val;
this._pq.add(new HeapItem<V>(priority, val));
return this;
}
poll(isItem?: undefined): T | undefined;
poll(isItem: false): T | undefined;
poll(isItem: true): HeapItem<T> | null;
poll(isItem?: undefined): V | undefined;
poll(isItem: false): V | undefined;
poll(isItem: true): HeapItem<V> | null;
/**
* The `poll` function returns the top item from a priority queue or null if the queue is empty.Removes and returns an val with the highest priority in the queue
* @returns either a HeapItem<T> object or null.
* @returns either a HeapItem<V> object or null.
*/
poll(isItem?: boolean): HeapItem<T> | null | T | undefined {
poll(isItem?: boolean): HeapItem<V> | null | V | undefined {
isItem = isItem ?? false;
const top = this._pq.poll();
if (!top) {
@ -154,10 +154,10 @@ export abstract class Heap<T = number> {
/**
* The function checks if a given node or value exists in the priority queue.
* @param {T | HeapItem<T>} node - The parameter `node` can be of type `T` or `HeapItem<T>`.
* @param {V | HeapItem<V>} node - The parameter `node` can be of type `V` or `HeapItem<V>`.
* @returns a boolean value.
*/
has(node: T | HeapItem<T>): boolean {
has(node: V | HeapItem<V>): boolean {
if (node instanceof HeapItem) {
return this.pq.getNodes().includes(node);
} else {
@ -169,34 +169,34 @@ export abstract class Heap<T = number> {
}
}
toArray(isItem?: undefined): (T | undefined)[];
toArray(isItem: false): (T | undefined)[];
toArray(isItem: true): (HeapItem<T> | null)[];
toArray(isItem?: undefined): (V | undefined)[];
toArray(isItem: false): (V | undefined)[];
toArray(isItem: true): (HeapItem<V> | null)[];
/**
* The `toArray` function returns an array of `HeapItem<T>` objects.
* @returns An array of HeapItem<T> objects.Returns a sorted list of vals
* The `toArray` function returns an array of `HeapItem<V>` objects.
* @returns An array of HeapItem<V> objects.Returns a sorted list of vals
*/
toArray(isItem?: boolean): (HeapItem<T> | null | T | undefined)[] {
toArray(isItem?: boolean): (HeapItem<V> | null | V | undefined)[] {
isItem = isItem ?? false;
const itemArray = this._pq.toArray();
return isItem ? itemArray : itemArray.map(item => item.val);
}
sort(isItem?: undefined): (T | undefined)[];
sort(isItem: false): (T | undefined)[];
sort(isItem: true): (HeapItem<T> | null)[];
sort(isItem?: undefined): (V | undefined)[];
sort(isItem: false): (V | undefined)[];
sort(isItem: true): (HeapItem<V> | null)[];
/**
* The function sorts the elements in the priority queue and returns either the sorted items or their values depending
* on the value of the isItem parameter.
* @param {boolean} [isItem] - The `isItem` parameter is a boolean flag that indicates whether the sorted result should
* be an array of `HeapItem<T>` objects or an array of the values (`T`) of those objects. If `isItem` is `true`, the
* be an array of `HeapItem<V>` objects or an array of the values (`V`) of those objects. If `isItem` is `true`, the
* sorted result will be an array of `HeapItem
* @returns an array of either `HeapItem<T>`, `null`, `T`, or `undefined` values.
* @returns an array of either `HeapItem<V>`, `null`, `V`, or `undefined` values.
*/
sort(isItem?: boolean): (HeapItem<T> | null | T | undefined)[] {
sort(isItem?: boolean): (HeapItem<V> | null | V | undefined)[] {
isItem = isItem ?? false;
const sorted = this._pq.sort();

View file

@ -14,17 +14,17 @@ import type {HeapOptions} from '../../types';
* @class MaxHeap
* @extends Heap
*/
export class MaxHeap<T = number> extends Heap<T> {
protected _pq: PriorityQueue<HeapItem<T>>;
export class MaxHeap<V = any> extends Heap<V> {
protected _pq: PriorityQueue<HeapItem<V>>;
/**
* The constructor initializes a PriorityQueue with a custom comparator function.
* @param [options] - The `options` parameter is an optional object that can be passed to the constructor. It is of
* type `HeapOptions<T>`, which is a generic type that represents the options for the heap.
* type `HeapOptions<V>`, which is a generic type that represents the options for the heap.
*/
constructor(options?: HeapOptions<T>) {
constructor(options?: HeapOptions<V>) {
super(options);
this._pq = new PriorityQueue<HeapItem<T>>({
this._pq = new PriorityQueue<HeapItem<V>>({
comparator: (a, b) => b.priority - a.priority
});
}

View file

@ -14,18 +14,18 @@ import type {HeapOptions} from '../../types';
* @class MinHeap
* @extends Heap
*/
export class MinHeap<T = number> extends Heap<T> {
protected _pq: PriorityQueue<HeapItem<T>>;
export class MinHeap<V = any> extends Heap<V> {
protected _pq: PriorityQueue<HeapItem<V>>;
/**
* The constructor initializes a PriorityQueue with a comparator function that compares the priority of two HeapItem
* objects.
* @param [options] - The `options` parameter is an optional object that can be passed to the constructor. It is of
* type `HeapOptions<T>`, which is a generic type that represents the options for the heap.
* type `HeapOptions<V>`, which is a generic type that represents the options for the heap.
*/
constructor(options?: HeapOptions<T>) {
constructor(options?: HeapOptions<V>) {
super(options);
this._pq = new PriorityQueue<HeapItem<T>>({
this._pq = new PriorityQueue<HeapItem<V>>({
comparator: (a, b) => a.priority - b.priority
});
}

View file

@ -5,50 +5,50 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
export class DoublyLinkedListNode<T = number> {
export class DoublyLinkedListNode<E = any> {
/**
* The constructor function initializes the value, next, and previous properties of an object.
* @param {T} val - The "val" parameter is the value that will be stored in the node. It can be of any data type, as it
* is defined as a generic type "T".
* @param {E} val - The "val" parameter is the value that will be stored in the node. It can be of any data type, as it
* is defined as a generic type "E".
*/
constructor(val: T) {
constructor(val: E) {
this._val = val;
this._next = null;
this._prev = null;
}
private _val: T;
private _val: E;
get val(): T {
get val(): E {
return this._val;
}
set val(value: T) {
set val(value: E) {
this._val = value;
}
private _next: DoublyLinkedListNode<T> | null;
private _next: DoublyLinkedListNode<E> | null;
get next(): DoublyLinkedListNode<T> | null {
get next(): DoublyLinkedListNode<E> | null {
return this._next;
}
set next(value: DoublyLinkedListNode<T> | null) {
set next(value: DoublyLinkedListNode<E> | null) {
this._next = value;
}
private _prev: DoublyLinkedListNode<T> | null;
private _prev: DoublyLinkedListNode<E> | null;
get prev(): DoublyLinkedListNode<T> | null {
get prev(): DoublyLinkedListNode<E> | null {
return this._prev;
}
set prev(value: DoublyLinkedListNode<T> | null) {
set prev(value: DoublyLinkedListNode<E> | null) {
this._prev = value;
}
}
export class DoublyLinkedList<T = any> {
export class DoublyLinkedList<E = any> {
/**
* The constructor initializes the linked list with an empty head, tail, and length.
*/
@ -58,23 +58,23 @@ export class DoublyLinkedList<T = any> {
this._length = 0;
}
private _head: DoublyLinkedListNode<T> | null;
private _head: DoublyLinkedListNode<E> | null;
get head(): DoublyLinkedListNode<T> | null {
get head(): DoublyLinkedListNode<E> | null {
return this._head;
}
set head(value: DoublyLinkedListNode<T> | null) {
set head(value: DoublyLinkedListNode<E> | null) {
this._head = value;
}
private _tail: DoublyLinkedListNode<T> | null;
private _tail: DoublyLinkedListNode<E> | null;
get tail(): DoublyLinkedListNode<T> | null {
get tail(): DoublyLinkedListNode<E> | null {
return this._tail;
}
set tail(value: DoublyLinkedListNode<T> | null) {
set tail(value: DoublyLinkedListNode<E> | null) {
this._tail = value;
}
@ -87,11 +87,11 @@ export class DoublyLinkedList<T = any> {
/**
* The `fromArray` function creates a new instance of a DoublyLinkedList and populates it with the elements from the
* given array.
* @param {T[]} data - The `data` parameter is an array of elements of type `T`.
* @param {E[]} data - The `data` parameter is an array of elements of type `E`.
* @returns The `fromArray` function returns a DoublyLinkedList object.
*/
static fromArray<T>(data: T[]) {
const doublyLinkedList = new DoublyLinkedList<T>();
static fromArray<E>(data: E[]) {
const doublyLinkedList = new DoublyLinkedList<E>();
for (const item of data) {
doublyLinkedList.push(item);
}
@ -100,9 +100,9 @@ export class DoublyLinkedList<T = any> {
/**
* The push function adds a new node with the given value to the end of the doubly linked list.
* @param {T} val - The value to be added to the linked list.
* @param {E} val - The value to be added to the linked list.
*/
push(val: T): void {
push(val: E): void {
const newNode = new DoublyLinkedListNode(val);
if (!this.head) {
this.head = newNode;
@ -120,7 +120,7 @@ export class DoublyLinkedList<T = any> {
* @returns The method is returning the value of the removed node (removedNode.val) if the list is not empty. If the
* list is empty, it returns null.
*/
pop(): T | undefined {
pop(): E | undefined {
if (!this.tail) return undefined;
const removedNode = this.tail;
if (this.head === this.tail) {
@ -139,7 +139,7 @@ export class DoublyLinkedList<T = any> {
* @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked
* list.
*/
shift(): T | undefined {
shift(): E | undefined {
if (!this.head) return undefined;
const removedNode = this.head;
if (this.head === this.tail) {
@ -155,10 +155,10 @@ export class DoublyLinkedList<T = any> {
/**
* The unshift function adds a new node with the given value to the beginning of a doubly linked list.
* @param {T} val - The `val` parameter represents the value of the new node that will be added to the beginning of the
* @param {E} val - The `val` parameter represents the value of the new node that will be added to the beginning of the
* doubly linked list.
*/
unshift(val: T): void {
unshift(val: E): void {
const newNode = new DoublyLinkedListNode(val);
if (!this.head) {
this.head = newNode;
@ -178,7 +178,7 @@ export class DoublyLinkedList<T = any> {
* @returns The method is returning the value at the specified index in the linked list. If the index is out of bounds
* or the linked list is empty, it will return null.
*/
getAt(index: number): T | undefined {
getAt(index: number): E | undefined {
if (index < 0 || index >= this.length) return undefined;
let current = this.head;
for (let i = 0; i < index; i++) {
@ -192,10 +192,10 @@ export class DoublyLinkedList<T = any> {
* range.
* @param {number} index - The `index` parameter is a number that represents the position of the node we want to
* retrieve from the doubly linked list. It indicates the zero-based index of the node we want to access.
* @returns The method `getNodeAt(index: number)` returns a `DoublyLinkedListNode<T>` object if the index is within the
* @returns The method `getNodeAt(index: number)` returns a `DoublyLinkedListNode<E>` object if the index is within the
* valid range of the linked list, otherwise it returns `null`.
*/
getNodeAt(index: number): DoublyLinkedListNode<T> | null {
getNodeAt(index: number): DoublyLinkedListNode<E> | null {
if (index < 0 || index >= this.length) return null;
let current = this.head;
for (let i = 0; i < index; i++) {
@ -207,11 +207,11 @@ export class DoublyLinkedList<T = any> {
/**
* The function `findNodeByValue` searches for a node with a specific value in a doubly linked list and returns the
* node if found, otherwise it returns null.
* @param {T} val - The `val` parameter is the value that we want to search for in the doubly linked list.
* @returns The function `findNodeByValue` returns a `DoublyLinkedListNode<T>` if a node with the specified value `val`
* @param {E} val - The `val` parameter is the value that we want to search for in the doubly linked list.
* @returns The function `findNodeByValue` returns a `DoublyLinkedListNode<E>` if a node with the specified value `val`
* is found in the linked list. If no such node is found, it returns `null`.
*/
findNode(val: T): DoublyLinkedListNode<T> | null {
findNode(val: E): DoublyLinkedListNode<E> | null {
let current = this.head;
while (current) {
@ -228,12 +228,12 @@ export class DoublyLinkedList<T = any> {
* The `insert` function inserts a value at a specified index in a doubly linked list.
* @param {number} index - The index parameter represents the position at which the new value should be inserted in the
* DoublyLinkedList. It is of type number.
* @param {T} val - The `val` parameter represents the value that you want to insert into the Doubly Linked List at the
* @param {E} val - The `val` parameter represents the value that you want to insert into the Doubly Linked List at the
* specified index.
* @returns The `insert` method returns a boolean value. It returns `true` if the insertion is successful, and `false`
* if the index is out of bounds.
*/
insertAt(index: number, val: T): boolean {
insertAt(index: number, val: E): boolean {
if (index < 0 || index > this.length) return false;
if (index === 0) {
this.unshift(val);
@ -262,7 +262,7 @@ export class DoublyLinkedList<T = any> {
* @returns The method `deleteAt` returns the value of the node that was deleted, or `null` if the index is out of
* bounds.
*/
deleteAt(index: number): T | undefined {
deleteAt(index: number): E | undefined {
if (index < 0 || index >= this.length) return undefined;
if (index === 0) return this.shift();
if (index === this.length - 1) return this.pop();
@ -276,18 +276,18 @@ export class DoublyLinkedList<T = any> {
return removedNode!.val;
}
delete(valOrNode: T): boolean;
delete(valOrNode: DoublyLinkedListNode<T>): boolean;
delete(valOrNode: E): boolean;
delete(valOrNode: DoublyLinkedListNode<E>): boolean;
/**
* The `delete` function removes a node from a doubly linked list based on either the node itself or its value.
* @param {T | DoublyLinkedListNode<T>} valOrNode - The `valOrNode` parameter can accept either a value of type `T` or
* a `DoublyLinkedListNode<T>` object.
* @param {E | DoublyLinkedListNode<E>} valOrNode - The `valOrNode` parameter can accept either a value of type `E` or
* a `DoublyLinkedListNode<E>` object.
* @returns The `delete` method returns a boolean value. It returns `true` if the value or node was successfully
* deleted from the doubly linked list, and `false` if the value or node was not found in the list.
*/
delete(valOrNode: T | DoublyLinkedListNode<T>): boolean {
let node: DoublyLinkedListNode<T> | null;
delete(valOrNode: E | DoublyLinkedListNode<E>): boolean {
let node: DoublyLinkedListNode<E> | null;
if (valOrNode instanceof DoublyLinkedListNode) {
node = valOrNode;
@ -314,10 +314,10 @@ export class DoublyLinkedList<T = any> {
/**
* The `toArray` function converts a linked list into an array.
* @returns The `toArray()` method is returning an array of type `T[]`.
* @returns The `toArray()` method is returning an array of type `E[]`.
*/
toArray(): T[] {
const array: T[] = [];
toArray(): E[] {
const array: E[] = [];
let current = this.head;
while (current) {
array.push(current.val);
@ -337,12 +337,12 @@ export class DoublyLinkedList<T = any> {
/**
* The `find` function iterates through a linked list and returns the first element that satisfies a given condition.
* @param callback - A function that takes a value of type T as its parameter and returns a boolean value. This
* @param callback - A function that takes a value of type E as its parameter and returns a boolean value. This
* function is used to determine whether a particular value in the linked list satisfies a certain condition.
* @returns The method `find` returns the first element in the linked list that satisfies the condition specified by
* the callback function. If no element satisfies the condition, it returns `null`.
*/
find(callback: (val: T) => boolean): T | null {
find(callback: (val: E) => boolean): E | null {
let current = this.head;
while (current) {
if (callback(current.val)) {
@ -355,12 +355,12 @@ export class DoublyLinkedList<T = any> {
/**
* The function returns the index of the first occurrence of a given value in a linked list.
* @param {T} val - The parameter `val` is of type `T`, which means it can be any data type. It represents the value
* @param {E} val - The parameter `val` is of type `E`, which means it can be any data type. It represents the value
* that we are searching for in the linked list.
* @returns The method `indexOf` returns the index of the first occurrence of the specified value `val` in the linked
* list. If the value is not found, it returns -1.
*/
indexOf(val: T): number {
indexOf(val: E): number {
let index = 0;
let current = this.head;
while (current) {
@ -376,12 +376,12 @@ export class DoublyLinkedList<T = any> {
/**
* The `findLast` function iterates through a linked list from the last node to the first node and returns the last
* value that satisfies the given callback function, or null if no value satisfies the callback.
* @param callback - A function that takes a value of type T as its parameter and returns a boolean value. This
* @param callback - A function that takes a value of type E as its parameter and returns a boolean value. This
* function is used to determine whether a given value satisfies a certain condition.
* @returns The method `findLast` returns the last value in the linked list that satisfies the condition specified by
* the callback function. If no value satisfies the condition, it returns `null`.
*/
findLast(callback: (val: T) => boolean): T | null {
findLast(callback: (val: E) => boolean): E | null {
let current = this.tail;
while (current) {
if (callback(current.val)) {
@ -394,10 +394,10 @@ export class DoublyLinkedList<T = any> {
/**
* The `toArrayReverse` function converts a doubly linked list into an array in reverse order.
* @returns The `toArrayReverse()` function returns an array of type `T[]`.
* @returns The `toArrayReverse()` function returns an array of type `E[]`.
*/
toArrayReverse(): T[] {
const array: T[] = [];
toArrayReverse(): E[] {
const array: E[] = [];
let current = this.tail;
while (current) {
array.push(current.val);
@ -425,7 +425,7 @@ export class DoublyLinkedList<T = any> {
* represents the value of the current node in the linked list, and the index argument represents the index of the
* current node in the linked list.
*/
forEach(callback: (val: T, index: number) => void): void {
forEach(callback: (val: E, index: number) => void): void {
let current = this.head;
let index = 0;
while (current) {
@ -438,12 +438,12 @@ export class DoublyLinkedList<T = any> {
/**
* The `map` function takes a callback function and applies it to each element in the DoublyLinkedList, returning a new
* DoublyLinkedList with the transformed values.
* @param callback - The callback parameter is a function that takes a value of type T (the type of values stored in
* @param callback - The callback parameter is a function that takes a value of type E (the type of values stored in
* the original DoublyLinkedList) and returns a value of type U (the type of values that will be stored in the mapped
* DoublyLinkedList).
* @returns The `map` function is returning a new instance of `DoublyLinkedList<U>` that contains the mapped values.
*/
map<U>(callback: (val: T) => U): DoublyLinkedList<U> {
map<U>(callback: (val: E) => U): DoublyLinkedList<U> {
const mappedList = new DoublyLinkedList<U>();
let current = this.head;
while (current) {
@ -456,12 +456,12 @@ export class DoublyLinkedList<T = any> {
/**
* The `filter` function iterates through a DoublyLinkedList and returns a new DoublyLinkedList containing only the
* elements that satisfy the given callback function.
* @param callback - The `callback` parameter is a function that takes a value of type `T` and returns a boolean value.
* @param callback - The `callback` parameter is a function that takes a value of type `E` and returns a boolean value.
* It is used to determine whether a value should be included in the filtered list or not.
* @returns The filtered list, which is an instance of the DoublyLinkedList class.
*/
filter(callback: (val: T) => boolean): DoublyLinkedList<T> {
const filteredList = new DoublyLinkedList<T>();
filter(callback: (val: E) => boolean): DoublyLinkedList<E> {
const filteredList = new DoublyLinkedList<E>();
let current = this.head;
while (current) {
if (callback(current.val)) {
@ -482,7 +482,7 @@ export class DoublyLinkedList<T = any> {
* @returns The `reduce` method is returning the final value of the accumulator after iterating through all the
* elements in the linked list.
*/
reduce<U>(callback: (accumulator: U, val: T) => U, initialValue: U): U {
reduce<U>(callback: (accumulator: U, val: E) => U, initialValue: U): U {
let accumulator = initialValue;
let current = this.head;
while (current) {
@ -492,19 +492,19 @@ export class DoublyLinkedList<T = any> {
return accumulator;
}
insertAfter(existingValueOrNode: T, newValue: T): boolean;
insertAfter(existingValueOrNode: DoublyLinkedListNode<T>, newValue: T): boolean;
insertAfter(existingValueOrNode: E, newValue: E): boolean;
insertAfter(existingValueOrNode: DoublyLinkedListNode<E>, newValue: E): boolean;
/**
* The `insertAfter` function inserts a new node with a given value after an existing node in a doubly linked list.
* @param {T | DoublyLinkedListNode<T>} existingValueOrNode - The existing value or node in the doubly linked list
* @param {E | DoublyLinkedListNode<E>} existingValueOrNode - The existing value or node in the doubly linked list
* after which the new value will be inserted. It can be either the value of the existing node or the existing node
* itself.
* @param {T} newValue - The value that you want to insert into the doubly linked list.
* @param {E} newValue - The value that you want to insert into the doubly linked list.
* @returns The method returns a boolean value. It returns true if the insertion is successful, and false if the
* existing value or node is not found in the doubly linked list.
*/
insertAfter(existingValueOrNode: T | DoublyLinkedListNode<T>, newValue: T): boolean {
insertAfter(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {
let existingNode;
if (existingValueOrNode instanceof DoublyLinkedListNode) {
@ -531,20 +531,20 @@ export class DoublyLinkedList<T = any> {
return false;
}
insertBefore(existingValueOrNode: T, newValue: T): boolean;
insertBefore(existingValueOrNode: DoublyLinkedListNode<T>, newValue: T): boolean;
insertBefore(existingValueOrNode: E, newValue: E): boolean;
insertBefore(existingValueOrNode: DoublyLinkedListNode<E>, newValue: E): boolean;
/**
* The `insertBefore` function inserts a new value before an existing value or node in a doubly linked list.
* @param {T | DoublyLinkedListNode<T>} existingValueOrNode - The existing value or node in the doubly linked list
* @param {E | DoublyLinkedListNode<E>} existingValueOrNode - The existing value or node in the doubly linked list
* before which the new value will be inserted. It can be either the value of the existing node or the existing node
* itself.
* @param {T} newValue - The `newValue` parameter represents the value that you want to insert into the doubly linked
* @param {E} newValue - The `newValue` parameter represents the value that you want to insert into the doubly linked
* list.
* @returns The method returns a boolean value. It returns `true` if the insertion is successful, and `false` if the
* insertion fails.
*/
insertBefore(existingValueOrNode: T | DoublyLinkedListNode<T>, newValue: T): boolean {
insertBefore(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {
let existingNode;
if (existingValueOrNode instanceof DoublyLinkedListNode) {

View file

@ -5,39 +5,39 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
export class SinglyLinkedListNode<T = number> {
export class SinglyLinkedListNode<E = any> {
/**
* The constructor function initializes an instance of a class with a given value and sets the next property to null.
* @param {T} val - The "val" parameter is of type T, which means it can be any data type. It represents the value that
* @param {E} val - The "val" parameter is of type E, which means it can be any data type. It represents the value that
* will be stored in the node of a linked list.
*/
constructor(val: T) {
constructor(val: E) {
this._val = val;
this._next = null;
}
private _val: T;
private _val: E;
get val(): T {
get val(): E {
return this._val;
}
set val(value: T) {
set val(value: E) {
this._val = value;
}
private _next: SinglyLinkedListNode<T> | null;
private _next: SinglyLinkedListNode<E> | null;
get next(): SinglyLinkedListNode<T> | null {
get next(): SinglyLinkedListNode<E> | null {
return this._next;
}
set next(value: SinglyLinkedListNode<T> | null) {
set next(value: SinglyLinkedListNode<E> | null) {
this._next = value;
}
}
export class SinglyLinkedList<T = any> {
export class SinglyLinkedList<E = any> {
/**
* The constructor initializes the linked list with an empty head, tail, and length.
*/
@ -47,23 +47,23 @@ export class SinglyLinkedList<T = any> {
this._length = 0;
}
private _head: SinglyLinkedListNode<T> | null;
private _head: SinglyLinkedListNode<E> | null;
get head(): SinglyLinkedListNode<T> | null {
get head(): SinglyLinkedListNode<E> | null {
return this._head;
}
set head(value: SinglyLinkedListNode<T> | null) {
set head(value: SinglyLinkedListNode<E> | null) {
this._head = value;
}
private _tail: SinglyLinkedListNode<T> | null;
private _tail: SinglyLinkedListNode<E> | null;
get tail(): SinglyLinkedListNode<T> | null {
get tail(): SinglyLinkedListNode<E> | null {
return this._tail;
}
set tail(value: SinglyLinkedListNode<T> | null) {
set tail(value: SinglyLinkedListNode<E> | null) {
this._tail = value;
}
@ -76,11 +76,11 @@ export class SinglyLinkedList<T = any> {
/**
* The `fromArray` function creates a new SinglyLinkedList instance and populates it with the elements from the given
* array.
* @param {T[]} data - The `data` parameter is an array of elements of type `T`.
* @param {E[]} data - The `data` parameter is an array of elements of type `E`.
* @returns The `fromArray` function returns a `SinglyLinkedList` object.
*/
static fromArray<T>(data: T[]) {
const singlyLinkedList = new SinglyLinkedList<T>();
static fromArray<E>(data: E[]) {
const singlyLinkedList = new SinglyLinkedList<E>();
for (const item of data) {
singlyLinkedList.push(item);
}
@ -93,10 +93,10 @@ export class SinglyLinkedList<T = any> {
/**
* The `push` function adds a new node with the given data to the end of a singly linked list.
* @param {T} data - The "data" parameter represents the value that you want to add to the linked list. It can be of
* any type (T) as specified in the generic type declaration of the class or function.
* @param {E} data - The "data" parameter represents the value that you want to add to the linked list. It can be of
* any type (E) as specified in the generic type declaration of the class or function.
*/
push(data: T): void {
push(data: E): void {
const newNode = new SinglyLinkedListNode(data);
if (!this.head) {
this.head = newNode;
@ -114,7 +114,7 @@ export class SinglyLinkedList<T = any> {
* @returns The method `pop()` returns the value of the node that is being removed from the end of the linked list. If
* the linked list is empty, it returns `null`.
*/
pop(): T | undefined {
pop(): E | undefined {
if (!this.head) return undefined;
if (this.head === this.tail) {
const val = this.head.val;
@ -139,7 +139,7 @@ export class SinglyLinkedList<T = any> {
* The `shift()` function removes and returns the value of the first node in a linked list.
* @returns The value of the node that is being removed from the beginning of the linked list.
*/
shift(): T | undefined {
shift(): E | undefined {
if (!this.head) return undefined;
const removedNode = this.head;
this.head = this.head.next;
@ -149,10 +149,10 @@ export class SinglyLinkedList<T = any> {
/**
* The unshift function adds a new node with the given value to the beginning of a singly linked list.
* @param {T} val - The parameter "val" represents the value of the new node that will be added to the beginning of the
* @param {E} val - The parameter "val" represents the value of the new node that will be added to the beginning of the
* linked list.
*/
unshift(val: T): void {
unshift(val: E): void {
const newNode = new SinglyLinkedListNode(val);
if (!this.head) {
this.head = newNode;
@ -168,10 +168,10 @@ export class SinglyLinkedList<T = any> {
* The function `getAt` returns the value at a specified index in a linked list, or null if the index is out of range.
* @param {number} index - The index parameter is a number that represents the position of the element we want to
* retrieve from the list.
* @returns The method `getAt(index: number): T | null` returns the value at the specified index in the linked list, or
* @returns The method `getAt(index: number): E | null` returns the value at the specified index in the linked list, or
* `null` if the index is out of bounds.
*/
getAt(index: number): T | undefined {
getAt(index: number): E | undefined {
if (index < 0 || index >= this.length) return undefined;
let current = this.head;
for (let i = 0; i < index; i++) {
@ -184,10 +184,10 @@ export class SinglyLinkedList<T = any> {
* The function `getNodeAt` returns the node at a given index in a singly linked list.
* @param {number} index - The `index` parameter is a number that represents the position of the node we want to
* retrieve from the linked list. It indicates the zero-based index of the node we want to access.
* @returns The method `getNodeAt(index: number)` returns a `SinglyLinkedListNode<T>` object if the node at the
* @returns The method `getNodeAt(index: number)` returns a `SinglyLinkedListNode<E>` object if the node at the
* specified index exists, or `null` if the index is out of bounds.
*/
getNodeAt(index: number): SinglyLinkedListNode<T> | null {
getNodeAt(index: number): SinglyLinkedListNode<E> | null {
let current = this.head;
for (let i = 0; i < index; i++) {
current = current!.next;
@ -202,7 +202,7 @@ export class SinglyLinkedList<T = any> {
* @returns The method `deleteAt` returns the value of the node that was deleted, or `null` if the index is out of
* bounds.
*/
deleteAt(index: number): T | undefined {
deleteAt(index: number): E | undefined {
if (index < 0 || index >= this.length) return undefined;
if (index === 0) return this.shift();
if (index === this.length - 1) return this.pop();
@ -214,18 +214,18 @@ export class SinglyLinkedList<T = any> {
return removedNode!.val;
}
delete(valueOrNode: T): boolean;
delete(valueOrNode: SinglyLinkedListNode<T>): boolean;
delete(valueOrNode: E): boolean;
delete(valueOrNode: SinglyLinkedListNode<E>): boolean;
/**
* The delete function removes a node with a specific value from a singly linked list.
* @param {T | SinglyLinkedListNode<T>} valueOrNode - The `valueOrNode` parameter can accept either a value of type `T`
* or a `SinglyLinkedListNode<T>` object.
* @param {E | SinglyLinkedListNode<E>} valueOrNode - The `valueOrNode` parameter can accept either a value of type `E`
* or a `SinglyLinkedListNode<E>` object.
* @returns The `delete` method returns a boolean value. It returns `true` if the value or node is found and
* successfully deleted from the linked list, and `false` if the value or node is not found in the linked list.
*/
delete(valueOrNode: T | SinglyLinkedListNode<T>): boolean {
let value: T;
delete(valueOrNode: E | SinglyLinkedListNode<E>): boolean {
let value: E;
if (valueOrNode instanceof SinglyLinkedListNode) {
value = valueOrNode.val;
} else {
@ -261,12 +261,12 @@ export class SinglyLinkedList<T = any> {
* The `insertAt` function inserts a value at a specified index in a singly linked list.
* @param {number} index - The index parameter represents the position at which the new value should be inserted in the
* linked list. It is of type number.
* @param {T} val - The `val` parameter represents the value that you want to insert into the linked list at the
* @param {E} val - The `val` parameter represents the value that you want to insert into the linked list at the
* specified index.
* @returns The `insert` method returns a boolean value. It returns `true` if the insertion is successful, and `false`
* if the index is out of bounds.
*/
insertAt(index: number, val: T): boolean {
insertAt(index: number, val: E): boolean {
if (index < 0 || index > this.length) return false;
if (index === 0) {
this.unshift(val);
@ -305,10 +305,10 @@ export class SinglyLinkedList<T = any> {
/**
* The `toArray` function converts a linked list into an array.
* @returns The `toArray()` method is returning an array of type `T[]`.
* @returns The `toArray()` method is returning an array of type `E[]`.
*/
toArray(): T[] {
const array: T[] = [];
toArray(): E[] {
const array: E[] = [];
let current = this.head;
while (current) {
array.push(current.val);
@ -324,9 +324,9 @@ export class SinglyLinkedList<T = any> {
reverse(): void {
if (!this.head || this.head === this.tail) return;
let prev: SinglyLinkedListNode<T> | null = null;
let current: SinglyLinkedListNode<T> | null = this.head;
let next: SinglyLinkedListNode<T> | null = null;
let prev: SinglyLinkedListNode<E> | null = null;
let current: SinglyLinkedListNode<E> | null = this.head;
let next: SinglyLinkedListNode<E> | null = null;
while (current) {
next = current.next;
@ -340,12 +340,12 @@ export class SinglyLinkedList<T = any> {
/**
* The `find` function iterates through a linked list and returns the first element that satisfies a given condition.
* @param callback - A function that takes a value of type T as its parameter and returns a boolean value. This
* @param callback - A function that takes a value of type E as its parameter and returns a boolean value. This
* function is used to determine whether a particular value in the linked list satisfies a certain condition.
* @returns The method `find` returns the first element in the linked list that satisfies the condition specified by
* the callback function. If no element satisfies the condition, it returns `null`.
*/
find(callback: (val: T) => boolean): T | null {
find(callback: (val: E) => boolean): E | null {
let current = this.head;
while (current) {
if (callback(current.val)) {
@ -358,11 +358,11 @@ export class SinglyLinkedList<T = any> {
/**
* The `indexOf` function returns the index of the first occurrence of a given value in a linked list.
* @param {T} value - The value parameter is the value that you want to find the index of in the linked list.
* @param {E} value - The value parameter is the value that you want to find the index of in the linked list.
* @returns The method is returning the index of the first occurrence of the specified value in the linked list. If the
* value is not found, it returns -1.
*/
indexOf(value: T): number {
indexOf(value: E): number {
let index = 0;
let current = this.head;
@ -380,11 +380,11 @@ export class SinglyLinkedList<T = any> {
/**
* The function finds a node in a singly linked list by its value and returns the node if found, otherwise returns
* null.
* @param {T} value - The value parameter is the value that we want to search for in the linked list.
* @returns a `SinglyLinkedListNode<T>` if a node with the specified value is found in the linked list. If no node with
* @param {E} value - The value parameter is the value that we want to search for in the linked list.
* @returns a `SinglyLinkedListNode<E>` if a node with the specified value is found in the linked list. If no node with
* the specified value is found, the function returns `null`.
*/
findNode(value: T): SinglyLinkedListNode<T> | null {
findNode(value: E): SinglyLinkedListNode<E> | null {
let current = this.head;
while (current) {
@ -397,21 +397,21 @@ export class SinglyLinkedList<T = any> {
return null;
}
insertBefore(existingValue: T, newValue: T): boolean;
insertBefore(existingValue: SinglyLinkedListNode<T>, newValue: T): boolean;
insertBefore(existingValue: E, newValue: E): boolean;
insertBefore(existingValue: SinglyLinkedListNode<E>, newValue: E): boolean;
/**
* The `insertBefore` function inserts a new value before an existing value in a singly linked list.
* @param {T | SinglyLinkedListNode<T>} existingValueOrNode - The existing value or node that you want to insert the
* @param {E | SinglyLinkedListNode<E>} existingValueOrNode - The existing value or node that you want to insert the
* new value before. It can be either the value itself or a node containing the value in the linked list.
* @param {T} newValue - The `newValue` parameter represents the value that you want to insert into the linked list.
* @param {E} newValue - The `newValue` parameter represents the value that you want to insert into the linked list.
* @returns The method `insertBefore` returns a boolean value. It returns `true` if the new value was successfully
* inserted before the existing value, and `false` otherwise.
*/
insertBefore(existingValueOrNode: T | SinglyLinkedListNode<T>, newValue: T): boolean {
insertBefore(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {
if (!this.head) return false;
let existingValue: T;
let existingValue: E;
if (existingValueOrNode instanceof SinglyLinkedListNode) {
existingValue = existingValueOrNode.val;
} else {
@ -437,19 +437,19 @@ export class SinglyLinkedList<T = any> {
return false;
}
insertAfter(existingValueOrNode: T, newValue: T): boolean;
insertAfter(existingValueOrNode: SinglyLinkedListNode<T>, newValue: T): boolean;
insertAfter(existingValueOrNode: E, newValue: E): boolean;
insertAfter(existingValueOrNode: SinglyLinkedListNode<E>, newValue: E): boolean;
/**
* The `insertAfter` function inserts a new node with a given value after an existing node in a singly linked list.
* @param {T | SinglyLinkedListNode<T>} existingValueOrNode - The existing value or node in the linked list after which
* @param {E | SinglyLinkedListNode<E>} existingValueOrNode - The existing value or node in the linked list after which
* the new value will be inserted. It can be either the value of the existing node or the existing node itself.
* @param {T} newValue - The value that you want to insert into the linked list after the existing value or node.
* @param {E} newValue - The value that you want to insert into the linked list after the existing value or node.
* @returns The method returns a boolean value. It returns true if the new value was successfully inserted after the
* existing value or node, and false if the existing value or node was not found in the linked list.
*/
insertAfter(existingValueOrNode: T | SinglyLinkedListNode<T>, newValue: T): boolean {
let existingNode: T | SinglyLinkedListNode<T> | null;
insertAfter(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {
let existingNode: E | SinglyLinkedListNode<E> | null;
if (existingValueOrNode instanceof SinglyLinkedListNode) {
existingNode = existingValueOrNode;
@ -473,10 +473,10 @@ export class SinglyLinkedList<T = any> {
/**
* The function counts the number of occurrences of a given value in a linked list.
* @param {T} value - The value parameter is the value that you want to count the occurrences of in the linked list.
* @param {E} value - The value parameter is the value that you want to count the occurrences of in the linked list.
* @returns The count of occurrences of the given value in the linked list.
*/
countOccurrences(value: T): number {
countOccurrences(value: E): number {
let count = 0;
let current = this.head;

View file

@ -6,22 +6,22 @@
* @license MIT License
*/
// todo need to be improved
export class MatrixNTI2D<T = number> {
private readonly _matrix: Array<Array<T>>;
export class MatrixNTI2D<V = any> {
private readonly _matrix: Array<Array<V>>;
/**
* The constructor creates a matrix with the specified number of rows and columns, and initializes all elements to a
* given initial value or 0 if not provided.
* @param options - An object containing the following properties:
*/
constructor(options: {row: number; col: number; initialVal?: T}) {
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));
}
/* The `toArray` method returns the matrix as a two-dimensional array. It converts the internal representation of the
matrix, which is an array of arrays, into a format that is more commonly used in JavaScript. */
toArray(): Array<Array<T>> {
toArray(): Array<Array<V>> {
return this._matrix;
}
}

View file

@ -8,21 +8,21 @@
import {PriorityQueue} from './priority-queue';
import type {PriorityQueueOptions, SpecifyOptional} from '../../types';
export class MaxPriorityQueue<T = number> extends PriorityQueue<T> {
export class MaxPriorityQueue<E = any> extends PriorityQueue<E> {
constructor(options?: Omit<PriorityQueueOptions<number>, 'comparator'>);
constructor(options: PriorityQueueOptions<T>);
constructor(options: PriorityQueueOptions<E>);
/**
* The constructor initializes a priority queue with an optional comparator function.
* @param [options] - The `options` parameter is an optional object that can contain various properties to configure
* the priority queue.
*/
constructor(options?: SpecifyOptional<PriorityQueueOptions<T>, 'comparator'>) {
constructor(options?: SpecifyOptional<PriorityQueueOptions<E>, 'comparator'>) {
super({
...options,
comparator: options?.comparator
? options.comparator
: (a: T, b: T) => {
: (a: E, b: E) => {
const aKey = a as unknown as number,
bKey = b as unknown as number;
return bKey - aKey;
@ -30,8 +30,8 @@ export class MaxPriorityQueue<T = number> extends PriorityQueue<T> {
});
}
static override heapify<T extends number>(options?: Omit<PriorityQueueOptions<T>, 'comparator'>): MaxPriorityQueue<T>;
static override heapify<T>(options: PriorityQueueOptions<T>): MaxPriorityQueue<T>;
static override heapify<E extends number>(options?: Omit<PriorityQueueOptions<E>, 'comparator'>): MaxPriorityQueue<E>;
static override heapify<E>(options: PriorityQueueOptions<E>): MaxPriorityQueue<E>;
/**
* The function `heapify` creates a max priority queue from the given options and returns it.
@ -39,12 +39,12 @@ export class MaxPriorityQueue<T = number> extends PriorityQueue<T> {
* queue. It can have the following properties:
* @returns a MaxPriorityQueue object.
*/
static override heapify<T>(options: PriorityQueueOptions<T>): MaxPriorityQueue<T> {
const maxPQ = new MaxPriorityQueue<T>({
static override heapify<E>(options: PriorityQueueOptions<E>): MaxPriorityQueue<E> {
const maxPQ = new MaxPriorityQueue<E>({
...options,
comparator: options?.comparator
? options.comparator
: (a: T, b: T) => {
: (a: E, b: E) => {
const aKey = a as unknown as number,
bKey = b as unknown as number;
return bKey - aKey;

View file

@ -8,21 +8,21 @@
import {PriorityQueue} from './priority-queue';
import type {PriorityQueueOptions, SpecifyOptional} from '../../types';
export class MinPriorityQueue<T = number> extends PriorityQueue<T> {
export class MinPriorityQueue<E = any> extends PriorityQueue<E> {
constructor(options?: Omit<PriorityQueueOptions<number>, 'comparator'>);
constructor(options: PriorityQueueOptions<T>);
constructor(options: PriorityQueueOptions<E>);
/**
* The constructor initializes a priority queue with an optional comparator function.
* @param [options] - The `options` parameter is an optional object that can contain various configuration options for
* the `PriorityQueue` constructor.
*/
constructor(options?: SpecifyOptional<PriorityQueueOptions<T>, 'comparator'>) {
constructor(options?: SpecifyOptional<PriorityQueueOptions<E>, 'comparator'>) {
super({
...options,
comparator: options?.comparator
? options.comparator
: (a: T, b: T) => {
: (a: E, b: E) => {
const aKey = a as unknown as number,
bKey = b as unknown as number;
return aKey - bKey;
@ -30,8 +30,8 @@ export class MinPriorityQueue<T = number> extends PriorityQueue<T> {
});
}
static override heapify<T extends number>(options?: Omit<PriorityQueueOptions<T>, 'comparator'>): MinPriorityQueue<T>;
static override heapify<T>(options: PriorityQueueOptions<T>): MinPriorityQueue<T>;
static override heapify<E extends number>(options?: Omit<PriorityQueueOptions<E>, 'comparator'>): MinPriorityQueue<E>;
static override heapify<E>(options: PriorityQueueOptions<E>): MinPriorityQueue<E>;
/**
* The function `heapify` creates a new MinPriorityQueue instance and sets the comparator function based on the options
@ -40,12 +40,12 @@ export class MinPriorityQueue<T = number> extends PriorityQueue<T> {
* queue. It can have the following properties:
* @returns a MinPriorityQueue object.
*/
static override heapify<T>(options: PriorityQueueOptions<T>): MinPriorityQueue<T> {
const minPQ = new MinPriorityQueue<T>({
static override heapify<E>(options: PriorityQueueOptions<E>): MinPriorityQueue<E> {
const minPQ = new MinPriorityQueue<E>({
...options,
comparator: options?.comparator
? options.comparator
: (a: T, b: T) => {
: (a: E, b: E) => {
const aKey = a as unknown as number,
bKey = b as unknown as number;
return aKey - bKey;

View file

@ -7,13 +7,13 @@
*/
import type {PriorityQueueComparator, PriorityQueueDFSOrderPattern, PriorityQueueOptions} from '../../types';
export class PriorityQueue<T = number> {
export class PriorityQueue<E = any> {
/**
* The constructor initializes a priority queue with the given options, including an array of nodes and a comparator
* function.
* @param options - The `options` parameter is an object that contains the following properties:
*/
constructor(options: PriorityQueueOptions<T>) {
constructor(options: PriorityQueueOptions<E>) {
const {nodes, comparator, isFix = true} = options;
this._comparator = comparator;
@ -24,9 +24,9 @@ export class PriorityQueue<T = number> {
}
}
protected _nodes: T[] = [];
protected _nodes: E[] = [];
get nodes(): T[] {
get nodes(): E[] {
return this._nodes;
}
@ -41,7 +41,7 @@ export class PriorityQueue<T = number> {
* the priority queue, and "initialValues" which is an array of initial values to be added to the priority
* @returns a new instance of the PriorityQueue class after performing the heapify operation on it.
*/
static heapify<T>(options: PriorityQueueOptions<T>) {
static heapify<E>(options: PriorityQueueOptions<E>) {
const heap = new PriorityQueue(options);
heap._fix();
return heap;
@ -54,52 +54,52 @@ export class PriorityQueue<T = number> {
* following properties:
* @returns the result of calling the `isValid()` method on a new instance of the `PriorityQueue` class.
*/
static isPriorityQueueified<T>(options: Omit<PriorityQueueOptions<T>, 'isFix'>) {
static isPriorityQueueified<E>(options: Omit<PriorityQueueOptions<E>, 'isFix'>) {
return new PriorityQueue({...options, isFix: false}).isValid();
}
/**
* Starting from TypeScript version 5.0 and onwards, the use of distinct access modifiers for Getters and Setters is not permitted. As an alternative, to ensure compatibility, it is necessary to adopt a Java-style approach for Setters (using the same name as the property) while utilizing separate method names for Getters.
*/
getNodes(): T[] {
getNodes(): E[] {
return this._nodes;
}
/**
* The "add" function adds a node to the heap and ensures that the heap property is maintained.
* @param {T} node - The parameter "node" is of type T, which means it can be any data type. It represents the node
* @param {E} node - The parameter "node" is of type E, which means it can be any data type. It represents the node
* that needs to be added to the heap.
*/
add(node: T) {
add(node: E) {
this.nodes.push(node);
this._heapifyUp(this.size - 1);
}
/**
* The "has" function checks if a given node is present in the list of nodes.
* @param {T} node - The parameter `node` is of type `T`, which means it can be any type. It represents the node that
* @param {E} node - The parameter `node` is of type `E`, which means it can be any type. It represents the node that
* we want to check if it exists in the `nodes` array.
* @returns a boolean value indicating whether the given node is included in the array of nodes.
*/
has(node: T): boolean {
has(node: E): boolean {
return this.nodes.includes(node);
}
/**
* The `peek` function returns the first element of the `nodes` array if it exists, otherwise it returns `null`.
* @returns The `peek()` function is returning the first element (`T`) of the `nodes` array if the `size` is not zero.
* @returns The `peek()` function is returning the first element (`E`) of the `nodes` array if the `size` is not zero.
* Otherwise, it returns `null`.
*/
peek(): T | null {
peek(): E | null {
return this.size ? this.nodes[0] : null;
}
/**
* The `poll` function removes and returns the top element from a heap data structure.
* @returns The `poll()` method returns a value of type `T` or `null`.
* @returns The `poll()` method returns a value of type `E` or `null`.
*/
poll(): T | null {
let res: T | null = null;
poll(): E | null {
let res: E | null = null;
if (this.size > 1) {
this._swap(0, this.nodes.length - 1);
res = this.nodes.pop() ?? null;
@ -112,10 +112,10 @@ export class PriorityQueue<T = number> {
/**
* The `leaf` function returns the last element in the `nodes` array or `null` if the array is empty.
* @returns The method `leaf()` is returning the last element (`T`) in the `nodes` array if it exists. If the array is
* @returns The method `leaf()` is returning the last element (`E`) in the `nodes` array if it exists. If the array is
* empty or the last element is `null`, then it returns `null`.
*/
leaf(): T | null {
leaf(): E | null {
return this.nodes[this.size - 1] ?? null;
}
@ -138,9 +138,9 @@ export class PriorityQueue<T = number> {
/**
* The toArray function returns an array containing all the elements in the nodes property.
* @returns An array of type T, which is the elements of the nodes property.
* @returns An array of type E, which is the elements of the nodes property.
*/
toArray(): T[] {
toArray(): E[] {
return [...this.nodes];
}
@ -150,8 +150,8 @@ export class PriorityQueue<T = number> {
* @returns The `clone()` method is returning a new instance of the `PriorityQueue` class with the same `nodes` and
* `comparator` properties as the original instance.
*/
clone(): PriorityQueue<T> {
return new PriorityQueue<T>({
clone(): PriorityQueue<E> {
return new PriorityQueue<E>({
nodes: this.nodes,
comparator: this._comparator
});
@ -183,10 +183,10 @@ export class PriorityQueue<T = number> {
/**
* The function sorts the elements in a data structure and returns them in an array.
* Plan to support sorting of duplicate elements.
* @returns The `sort()` method is returning an array of type `T[]`.
* @returns The `sort()` method is returning an array of type `E[]`.
*/
sort(): T[] {
const visitedNode: T[] = [];
sort(): E[] {
const visitedNode: E[] = [];
while (this.size !== 0) {
const top = this.poll();
if (top) visitedNode.push(top);
@ -199,10 +199,10 @@ export class PriorityQueue<T = number> {
* based on the specified traversal order.
* @param {PriorityQueueDFSOrderPattern} dfsMode - The dfsMode parameter is a string that specifies the order in which
* the nodes should be visited during the Depth-First Search (DFS) traversal. It can have one of the following values:
* @returns an array of type `(T | null)[]`.
* @returns an array of type `(E | null)[]`.
*/
DFS(dfsMode: PriorityQueueDFSOrderPattern): (T | null)[] {
const visitedNode: (T | null)[] = [];
DFS(dfsMode: PriorityQueueDFSOrderPattern): (E | null)[] {
const visitedNode: (E | null)[] = [];
const traverse = (cur: number) => {
const leftChildIndex = this._getLeft(cur);
@ -230,11 +230,11 @@ export class PriorityQueue<T = number> {
return visitedNode;
}
protected _setNodes(value: T[]) {
protected _setNodes(value: E[]) {
this._nodes = value;
}
protected readonly _comparator: PriorityQueueComparator<T> = (a: T, b: T) => {
protected readonly _comparator: PriorityQueueComparator<E> = (a: E, b: E) => {
const aKey = a as unknown as number,
bKey = b as unknown as number;
return aKey - bKey;

View file

@ -9,19 +9,19 @@ import {DoublyLinkedList} from '../linked-list';
// O(n) time complexity of obtaining the value
// O(1) time complexity of adding at the beginning and the end
export class Deque<T> extends DoublyLinkedList<T> {}
export class Deque<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
// todo tested slowest one
export class ObjectDeque<T = number> {
export class ObjectDeque<E = number> {
constructor(capacity?: number) {
if (capacity !== undefined) this._capacity = capacity;
}
private _nodes: {[key: number]: T} = {};
private _nodes: {[key: number]: E} = {};
get nodes(): {[p: number]: T} {
get nodes(): {[p: number]: E} {
return this._nodes;
}
@ -63,10 +63,10 @@ export class ObjectDeque<T = number> {
/**
* The "addFirst" function adds a value to the beginning of an array-like data structure.
* @param {T} value - The `value` parameter represents the value that you want to add to the beginning of the data
* @param {E} value - The `value` parameter represents the value that you want to add to the beginning of the data
* structure.
*/
addFirst(value: T) {
addFirst(value: E) {
if (this._size === 0) {
const mid = Math.floor(this._capacity / 2);
this._first = mid;
@ -80,9 +80,9 @@ export class ObjectDeque<T = number> {
/**
* The addLast function adds a value to the end of an array-like data structure.
* @param {T} value - The `value` parameter represents the value that you want to add to the end of the data structure.
* @param {E} value - The `value` parameter represents the value that you want to add to the end of the data structure.
*/
addLast(value: T) {
addLast(value: E) {
if (this._size === 0) {
const mid = Math.floor(this._capacity / 2);
this._first = mid;
@ -156,7 +156,7 @@ export class ObjectDeque<T = number> {
return this._size <= 0;
}
protected _seNodes(value: {[p: number]: T}) {
protected _seNodes(value: {[p: number]: E}) {
this._nodes = value;
}
@ -167,8 +167,8 @@ export class ObjectDeque<T = number> {
// O(1) time complexity of obtaining the value
// O(n) time complexity of adding at the beginning and the end
export class ArrayDeque<T> {
protected _nodes: T[] = [];
export class ArrayDeque<E> {
protected _nodes: E[] = [];
get size() {
return this._nodes.length;
@ -180,10 +180,10 @@ export class ArrayDeque<T> {
/**
* The function "addLast" adds a value to the end of an array.
* @param {T} value - The value parameter represents the value that you want to add to the end of the array.
* @param {E} value - The value parameter represents the value that you want to add to the end of the array.
* @returns The return value is the new length of the array after the value has been added.
*/
addLast(value: T) {
addLast(value: E) {
return this._nodes.push(value);
}
@ -191,7 +191,7 @@ export class ArrayDeque<T> {
* The function "pollLast" returns and removes the last element from an array, or returns null if the array is empty.
* @returns The method `pollLast()` returns the last element of the `_nodes` array, or `null` if the array is empty.
*/
pollLast(): T | null {
pollLast(): E | null {
return this._nodes.pop() ?? null;
}
@ -200,7 +200,7 @@ export class ArrayDeque<T> {
* @returns The `pollFirst()` function returns the first element of the `_nodes` array, or `null` if the array is
* empty.
*/
pollFirst(): T | null {
pollFirst(): E | null {
return this._nodes.shift() ?? null;
}
@ -210,20 +210,20 @@ export class ArrayDeque<T> {
/**
* The function "addFirst" adds a value to the beginning of an array.
* @param {T} value - The value parameter represents the value that you want to add to the beginning of the array.
* @param {E} value - The value parameter represents the value that you want to add to the beginning of the array.
* @returns The return value of the `addFirst` function is the new length of the array `_nodes` after adding the
* `value` at the beginning.
*/
addFirst(value: T) {
addFirst(value: E) {
return this._nodes.unshift(value);
}
/**
* The `peekFirst` function returns the first element of an array or null if the array is empty.
* @returns The function `peekFirst()` is returning the first element (`T`) of the `_nodes` array. If the array is
* @returns The function `peekFirst()` is returning the first element (`E`) of the `_nodes` array. If the array is
* empty, it will return `null`.
*/
peekFirst(): T | null {
peekFirst(): E | null {
return this._nodes[0] ?? null;
}
@ -231,7 +231,7 @@ export class ArrayDeque<T> {
* The `peekLast` function returns the last element of an array or null if the array is empty.
* @returns The method `peekLast()` returns the last element of the `_nodes` array, or `null` if the array is empty.
*/
peekLast(): T | null {
peekLast(): E | null {
return this._nodes[this._nodes.length - 1] ?? null;
}
@ -246,7 +246,7 @@ export class ArrayDeque<T> {
* @returns The method is returning the element at the specified index in the `_nodes` array. If the element exists, it
* will be returned. If the element does not exist (i.e., the index is out of bounds), `null` will be returned.
*/
get(index: number): T | null {
get(index: number): E | null {
return this._nodes[index] ?? null;
}
@ -254,11 +254,11 @@ export class ArrayDeque<T> {
* The set function assigns a value to a specific index in an array.
* @param {number} index - The index parameter is a number that represents the position of the element in the array
* that you want to set a new value for.
* @param {T} value - The value parameter represents the new value that you want to set at the specified index in the
* @param {E} value - The value parameter represents the new value that you want to set at the specified index in the
* _nodes array.
* @returns The value that is being set at the specified index in the `_nodes` array.
*/
set(index: number, value: T) {
set(index: number, value: E) {
return (this._nodes[index] = value);
}
@ -267,12 +267,12 @@ export class ArrayDeque<T> {
* @param {number} index - The index parameter specifies the position at which the value should be inserted in the
* array. It is a number that represents the index of the array where the value should be inserted. The index starts
* from 0, so the first element of the array has an index of 0, the second element has
* @param {T} value - The value parameter represents the value that you want to insert into the array at the specified
* @param {E} value - The value parameter represents the value that you want to insert into the array at the specified
* index.
* @returns The splice method returns an array containing the removed elements, if any. In this case, since no elements
* are being removed, an empty array will be returned.
*/
insert(index: number, value: T) {
insert(index: number, value: E) {
return this._nodes.splice(index, 0, value);
}

View file

@ -5,12 +5,12 @@
*/
import {SinglyLinkedList} from '../linked-list';
export class LinkedListQueue<T = any> extends SinglyLinkedList<T> {
export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
/**
* The enqueue function adds a value to the end of an array.
* @param {T} value - The value parameter represents the value that you want to add to the queue.
* @param {E} value - The value parameter represents the value that you want to add to the queue.
*/
enqueue(value: T) {
enqueue(value: E) {
this.push(value);
}
@ -18,7 +18,7 @@ export class LinkedListQueue<T = any> extends SinglyLinkedList<T> {
* The `dequeue` function removes and returns the first element from a queue, or returns null if the queue is empty.
* @returns The method is returning the element at the front of the queue, or null if the queue is empty.
*/
dequeue(): T | undefined {
dequeue(): E | undefined {
return this.shift();
}
@ -26,30 +26,30 @@ export class LinkedListQueue<T = any> extends SinglyLinkedList<T> {
* The `peek` function returns the value of the head node in a linked list, or `undefined` if the list is empty.
* @returns The `peek()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.
*/
peek(): T | undefined {
peek(): E | undefined {
return this.head?.val;
}
}
export class Queue<T = any> {
export class Queue<E = any> {
/**
* The constructor initializes an instance of a class with an optional array of elements and sets the offset to 0.
* @param {T[]} [elements] - The `elements` parameter is an optional array of elements of type `T`. If provided, it
* @param {E[]} [elements] - The `elements` parameter is an optional array of elements of type `E`. If provided, it
* will be used to initialize the `_nodes` property of the class. If not provided, the `_nodes` property will be
* initialized as an empty array.
*/
constructor(elements?: T[]) {
constructor(elements?: E[]) {
this._nodes = elements || [];
this._offset = 0;
}
private _nodes: T[];
private _nodes: E[];
get nodes(): T[] {
get nodes(): E[] {
return this._nodes;
}
set nodes(value: T[]) {
set nodes(value: E[]) {
this._nodes = value;
}
@ -75,20 +75,20 @@ export class Queue<T = any> {
* The function "fromArray" creates a new Queue object from an array of elements.Creates a queue from an existing array.
* @public
* @static
* @param {T[]} elements - The "elements" parameter is an array of elements of type T.
* @param {E[]} elements - The "elements" parameter is an array of elements of type E.
* @returns The method is returning a new instance of the Queue class, initialized with the elements from the input
* array.
*/
static fromArray<T>(elements: T[]): Queue<T> {
static fromArray<E>(elements: E[]): Queue<E> {
return new Queue(elements);
}
/**
* The push function adds an element to the end of the queue and returns the updated queue.Adds an element at the back of the queue.
* @param {T} element - The `element` parameter represents the element that you want to add to the queue.
* @returns The `add` method is returning a `Queue<T>` object.
* @param {E} element - The `element` parameter represents the element that you want to add to the queue.
* @returns The `add` method is returning a `Queue<E>` object.
*/
push(element: T): Queue<T> {
push(element: E): Queue<E> {
this.nodes.push(element);
return this;
}
@ -98,7 +98,7 @@ export class Queue<T = any> {
* necessary to optimize performance.
* @returns The function `shift()` returns either the first element in the queue or `null` if the queue is empty.
*/
shift(): T | undefined {
shift(): E | undefined {
if (this.size === 0) return undefined;
const first = this.peek();
@ -118,7 +118,7 @@ export class Queue<T = any> {
* @returns The `peek()` method returns the first element of the data structure, represented by the `_nodes` array at
* the `_offset` index. If the data structure is empty (size is 0), it returns `null`.
*/
peek(): T | undefined {
peek(): E | undefined {
return this.size > 0 ? this.nodes[this.offset] : undefined;
}
@ -127,27 +127,27 @@ export class Queue<T = any> {
* @returns The method `peekLast()` returns the last element of the `_nodes` array if the array is not empty. If the
* array is empty, it returns `null`.
*/
peekLast(): T | undefined {
peekLast(): E | undefined {
return this.size > 0 ? this.nodes[this.nodes.length - 1] : undefined;
}
/**
* The enqueue function adds a value to the end of a queue.
* @param {T} value - The value parameter represents the value that you want to add to the queue.
* @param {E} value - The value parameter represents the value that you want to add to the queue.
*/
enqueue(value: T) {
enqueue(value: E) {
this.push(value);
}
/**
* The `dequeue` function removes and returns the first element from a queue, or returns null if the queue is empty.
* @returns The method is returning a value of type T or null.
* @returns The method is returning a value of type E or null.
*/
dequeue(): T | undefined {
dequeue(): E | undefined {
return this.shift();
}
getAt(index: number): T | undefined {
getAt(index: number): E | undefined {
return this.nodes[index];
}
@ -161,9 +161,9 @@ export class Queue<T = any> {
/**
* The toArray() function returns an array of elements from the current offset to the end of the _nodes array.
* @returns An array of type T is being returned.
* @returns An array of type E is being returned.
*/
toArray(): T[] {
toArray(): E[] {
return this.nodes.slice(this.offset);
}
@ -179,7 +179,7 @@ export class Queue<T = any> {
* The `clone()` function returns a new Queue object with the same elements as the original Queue.
* @returns The `clone()` method is returning a new instance of the `Queue` class.
*/
clone(): Queue<T> {
clone(): Queue<E> {
return new Queue(this.nodes.slice(this.offset));
}

View file

@ -3,26 +3,26 @@
* @copyright Tyler Zeng <zrwusa@gmail.com>
* @class
*/
export class Stack<T = number> {
protected _elements: T[];
export class Stack<E = any> {
protected _elements: E[];
/**
* The constructor initializes an array of elements, which can be provided as an optional parameter.
* @param {T[]} [elements] - The `elements` parameter is an optional parameter of type `T[]`, which represents an array
* of elements of type `T`. It is used to initialize the `_elements` property of the class. If the `elements` parameter
* @param {E[]} [elements] - The `elements` parameter is an optional parameter of type `E[]`, which represents an array
* of elements of type `E`. It is used to initialize the `_elements` property of the class. If the `elements` parameter
* is provided and is an array, it is assigned to the `_elements
*/
constructor(elements?: T[]) {
constructor(elements?: E[]) {
this._elements = Array.isArray(elements) ? elements : [];
}
/**
* The function "fromArray" creates a new Stack object from an array of elements.
* @param {T[]} elements - The `elements` parameter is an array of elements of type `T`.
* @param {E[]} elements - The `elements` parameter is an array of elements of type `E`.
* @returns {Stack} The method is returning a new instance of the Stack class, initialized with the elements from the input
* array.
*/
static fromArray<T>(elements: T[]): Stack<T> {
static fromArray<E>(elements: E[]): Stack<E> {
return new Stack(elements);
}
@ -46,7 +46,7 @@ export class Stack<T = number> {
* The `peek` function returns the last element of an array, or null if the array is empty.
* @returns The `peek()` function returns the last element of the `_elements` array, or `null` if the array is empty.
*/
peek(): T | null {
peek(): E | null {
if (this.isEmpty()) return null;
return this._elements[this._elements.length - 1];
@ -54,10 +54,10 @@ export class Stack<T = number> {
/**
* The push function adds an element to the stack and returns the updated stack.
* @param {T} element - The parameter "element" is of type T, which means it can be any data type.
* @returns The `push` method is returning the updated `Stack<T>` object.
* @param {E} element - The parameter "element" is of type E, which means it can be any data type.
* @returns The `push` method is returning the updated `Stack<E>` object.
*/
push(element: T): Stack<T> {
push(element: E): Stack<E> {
this._elements.push(element);
return this;
}
@ -67,7 +67,7 @@ export class Stack<T = number> {
* @returns The `pop()` method is returning the last element of the array `_elements` if the array is not empty. If the
* array is empty, it returns `null`.
*/
pop(): T | null {
pop(): E | null {
if (this.isEmpty()) return null;
return this._elements.pop() || null;
@ -75,9 +75,9 @@ export class Stack<T = number> {
/**
* The toArray function returns a copy of the elements in an array.
* @returns An array of type T.
* @returns An array of type E.
*/
toArray(): T[] {
toArray(): E[] {
return this._elements.slice();
}
@ -92,7 +92,7 @@ export class Stack<T = number> {
* The `clone()` function returns a new `Stack` object with the same elements as the original stack.
* @returns The `clone()` method is returning a new `Stack` object with a copy of the `_elements` array.
*/
clone(): Stack<T> {
clone(): Stack<E> {
return new Stack(this._elements.slice());
}
}

View file

@ -1,5 +1,5 @@
export class TreeNode<T = any> {
constructor(id: string, value?: T, children?: TreeNode<T>[]) {
export class TreeNode<V = any> {
constructor(id: string, value?: V, children?: TreeNode<V>[]) {
this._id = id;
this._value = value || undefined;
this._children = children || [];
@ -15,27 +15,27 @@ export class TreeNode<T = any> {
this._id = value;
}
private _value?: T | undefined;
private _value?: V | undefined;
get value(): T | undefined {
get value(): V | undefined {
return this._value;
}
set value(value: T | undefined) {
set value(value: V | undefined) {
this._value = value;
}
private _children?: TreeNode<T>[] | undefined;
private _children?: TreeNode<V>[] | undefined;
get children(): TreeNode<T>[] | undefined {
get children(): TreeNode<V>[] | undefined {
return this._children;
}
set children(value: TreeNode<T>[] | undefined) {
set children(value: TreeNode<V>[] | undefined) {
this._children = value;
}
addChildren(children: TreeNode<T> | TreeNode<T>[]) {
addChildren(children: TreeNode<V> | TreeNode<V>[]) {
if (!this.children) {
this.children = [];
}
@ -51,7 +51,7 @@ export class TreeNode<T = any> {
const beginRoot = this;
let maxDepth = 1;
if (beginRoot) {
const bfs = (node: TreeNode<T>, level: number) => {
const bfs = (node: TreeNode<V>, level: number) => {
if (level > maxDepth) {
maxDepth = level;
}