mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 04:44:04 +00:00
[test] test coverage enriched to 90.37%
This commit is contained in:
parent
c492af0461
commit
f87e682f26
|
@ -273,11 +273,6 @@ module.exports = {
|
|||
your webpack config is a function and takes them (see webpack documentation
|
||||
for details)
|
||||
*/
|
||||
// webpackConfig: {
|
||||
// fileName: './webpack.config.js',
|
||||
// env: {},
|
||||
// arguments: {},
|
||||
// },
|
||||
|
||||
/* Babel config ('.babelrc', '.babelrc.json', '.babelrc.json5', ...) to use
|
||||
for compilation (and whatever other naughty things babel plugins do to
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,6 +8,7 @@ npm-debug.*
|
|||
*.orig.*
|
||||
.DS_Store
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
/notes
|
||||
/backup
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.idea
|
||||
.vscode
|
||||
.auto-changelog
|
||||
.auto-changelog-template.hbs
|
||||
.dependency-cruiser.js
|
||||
|
@ -9,7 +10,6 @@
|
|||
/notes
|
||||
/backup
|
||||
|
||||
/webpack.config.js
|
||||
/scripts
|
||||
/tsconfig.prod.json
|
||||
|
||||
|
|
62
package-lock.json
generated
62
package-lock.json
generated
|
@ -1045,9 +1045,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@eslint-community/regexpp": {
|
||||
"version": "4.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz",
|
||||
"integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==",
|
||||
"version": "4.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
|
||||
"integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
|
@ -2021,12 +2021,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.8.tgz",
|
||||
"integrity": "sha512-YRsdVxq6OaLfmR9Hy816IMp33xOBjfyOgUd77ehqg96CFywxAPbDbXvAsuN2KVg2HOT8Eh6uAfU+l4WffwPVrQ==",
|
||||
"version": "20.8.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz",
|
||||
"integrity": "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.25.1"
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/semver": {
|
||||
|
@ -2728,9 +2728,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/avl-tree-typed": {
|
||||
"version": "1.39.0",
|
||||
"resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.39.0.tgz",
|
||||
"integrity": "sha512-YpYfpO0slt8R5lcy4wrz7inKFAG1NKUZk2FnJ2FEYIdBJaBIUvW0cflx6Cuuy1iRiXbazpTqGQgKC0nERWUiow==",
|
||||
"version": "1.39.1",
|
||||
"resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.39.1.tgz",
|
||||
"integrity": "sha512-V4H5cBue8qzsUYzDIngPR6FJELuuMtwYSk34BdpgwPHpo79ZL0LqJmEiIY9FCmkoYPQFvZAz/Z7+RH9MJXgZPA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"data-structure-typed": "^1.39.0"
|
||||
|
@ -2927,9 +2927,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/binary-tree-typed": {
|
||||
"version": "1.39.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.39.0.tgz",
|
||||
"integrity": "sha512-oJzCbrs+l4qacscxFvVB/ielr22KiO8z/bWSx/tJmafpinWmkAuQIBRGqo+frfFi8MKstNerHPEF+4yT8AakUA==",
|
||||
"version": "1.39.1",
|
||||
"resolved": "https://registry.npmjs.org/binary-tree-typed/-/binary-tree-typed-1.39.1.tgz",
|
||||
"integrity": "sha512-fbPwGQXmy9GKw/23yRm9c+9wDNgXbhvGUP6za0NQuo3kvJ522SAEzvgwPXEqO92RIKT/OpP0+aO5dpTJaOiodQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"data-structure-typed": "^1.39.0"
|
||||
|
@ -3011,9 +3011,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/bst-typed": {
|
||||
"version": "1.39.0",
|
||||
"resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.39.0.tgz",
|
||||
"integrity": "sha512-AvitIe0j8jPrXyZkQI5zhTYIc4eS5rxvW59/0YHymg54BeMs+zm1WzouPhsh7qp9D+IcTpQmqDY0kjc07Tic3w==",
|
||||
"version": "1.39.1",
|
||||
"resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.39.1.tgz",
|
||||
"integrity": "sha512-Oo86lN3GJIODrGHZSpNJZ7X1N1adgEpY8kd7jOvZd+zF2BHEJVpW8uTk3PtSgbCLGnEkSzE2lXWaaOZh5F9x1A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"data-structure-typed": "^1.39.0"
|
||||
|
@ -3082,9 +3082,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001554",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001554.tgz",
|
||||
"integrity": "sha512-A2E3U//MBwbJVzebddm1YfNp7Nud5Ip+IPn4BozBmn4KqVX7AvluoIDFWjsv5OkGnKUXQVmMSoMKLa3ScCblcQ==",
|
||||
"version": "1.0.30001557",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001557.tgz",
|
||||
"integrity": "sha512-91oR7hLNUP3gG6MLU+n96em322a8Xzes8wWdBKhLgUoiJsAF5irZnxSUCbc+qUZXNnPCfUwLOi9ZCZpkvjQajw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -3413,9 +3413,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/data-structure-typed": {
|
||||
"version": "1.39.0",
|
||||
"resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.39.0.tgz",
|
||||
"integrity": "sha512-HESmI/a+uE3ELRDVKIBSmfgSMep4ETJco8jeZD2By5lNhMW9HDZE+SGNqlSeBJd3PdJyact9dWlXWwg7S3+ztQ==",
|
||||
"version": "1.39.1",
|
||||
"resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.39.1.tgz",
|
||||
"integrity": "sha512-zAotqpGJoWKG12b4pybA05oih3RAy50RlD++ye8M58AjcM5Aw8lZjWlsNmi+ICiAdq8P0xdJM6Z7/etysctJZg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/debug": {
|
||||
|
@ -3598,9 +3598,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.566",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.566.tgz",
|
||||
"integrity": "sha512-mv+fAy27uOmTVlUULy15U3DVJ+jg+8iyKH1bpwboCRhtDC69GKf1PPTZvEIhCyDr81RFqfxZJYrbgp933a1vtg==",
|
||||
"version": "1.4.569",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.569.tgz",
|
||||
"integrity": "sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/emittery": {
|
||||
|
@ -4771,9 +4771,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/heap-typed": {
|
||||
"version": "1.39.0",
|
||||
"resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.39.0.tgz",
|
||||
"integrity": "sha512-n9Qa+Ph6nnqRN6lz52R62CHrpgWixU/39P22WT9Epf+4dj+pDYPKEGekCCidjjxQXgoR56d6XjnZWFgiQYYN4Q==",
|
||||
"version": "1.39.1",
|
||||
"resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.39.1.tgz",
|
||||
"integrity": "sha512-+fKr3EKYNGLK9ZVLeZZFP58eKvGv/zWGYbBOZYIXkQZeBXtdL0b4rHL0LsoIpuyPMbhXDFNOhaasG4D1NbCu2Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"data-structure-typed": "^1.39.0"
|
||||
|
@ -8915,9 +8915,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.25.3",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
|
||||
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "data-structure-typed",
|
||||
"version": "1.39.1",
|
||||
"version": "1.39.2",
|
||||
"description": "Data Structures of Javascript & TypeScript. Binary Tree, BST, Graph, Heap, Priority Queue, Linked List, Queue, Deque, Stack, AVL Tree, Tree Multiset, Trie, Directed Graph, Undirected Graph, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue.",
|
||||
"main": "dist/cjs/index.js",
|
||||
"module": "dist/mjs/index.js",
|
||||
|
|
|
@ -21,8 +21,7 @@ export class AVLTreeNode<V = any, N extends AVLTreeNode<V, N> = AVLTreeNodeNeste
|
|||
|
||||
export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTreeNodeNested<V>>>
|
||||
extends BST<V, N>
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
implements IBinaryTree<V, N> {
|
||||
/**
|
||||
* This is a constructor function for an AVL tree data structure in TypeScript.
|
||||
* @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the
|
||||
|
@ -161,7 +160,7 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
// Balance Restoration: If a balance issue is discovered after inserting a node, it requires balance restoration operations. Balance restoration includes four basic cases where rotation operations need to be performed to fix the balance:
|
||||
switch (
|
||||
this._balanceFactor(A) // second O(1)
|
||||
) {
|
||||
) {
|
||||
case -2:
|
||||
if (A && A.left) {
|
||||
if (this._balanceFactor(A.left) <= 0) {
|
||||
|
|
|
@ -17,7 +17,7 @@ export class BinaryIndexedTree {
|
|||
* @param - - `frequency`: The default frequency value. It is optional and has a default
|
||||
* value of 0.
|
||||
*/
|
||||
constructor({frequency = 0, max}: {frequency?: number; max: number}) {
|
||||
constructor({frequency = 0, max}: { frequency?: number; max: number }) {
|
||||
this._freq = frequency;
|
||||
this._max = max;
|
||||
this._freqMap = {0: 0};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import type {OneParamCallback, BinaryTreeNodeKey, BinaryTreeNodeNested, BinaryTreeOptions} from '../../types';
|
||||
import type {BinaryTreeNodeKey, BinaryTreeNodeNested, BinaryTreeOptions, OneParamCallback} from '../../types';
|
||||
import {BinaryTreeDeletedResult, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
import {trampoline} from '../../utils';
|
||||
|
@ -108,8 +108,7 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
|
|||
* @template N - The type of the binary tree's nodes.
|
||||
*/
|
||||
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>>
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
implements IBinaryTree<V, N> {
|
||||
/**
|
||||
* Creates a new instance of BinaryTree.
|
||||
* @param {BinaryTreeOptions} [options] - The options for the binary tree.
|
||||
|
@ -395,7 +394,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return -1;
|
||||
}
|
||||
|
||||
const stack: {node: N; depth: number}[] = [{node: beginRoot, depth: 0}];
|
||||
const stack: { node: N; depth: number }[] = [{node: beginRoot, depth: 0}];
|
||||
let maxHeight = 0;
|
||||
|
||||
while (stack.length > 0) {
|
||||
|
@ -832,7 +831,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
_traverse(beginRoot);
|
||||
} else {
|
||||
// 0: visit, 1: print
|
||||
const stack: {opt: 0 | 1; node: N | null | undefined}[] = [{opt: 0, node: beginRoot}];
|
||||
const stack: { opt: 0 | 1; node: N | null | undefined }[] = [{opt: 0, node: beginRoot}];
|
||||
|
||||
while (stack.length > 0) {
|
||||
const cur = stack.pop();
|
||||
|
@ -1093,6 +1092,49 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* The above function is an iterator for a binary tree that can be used to traverse the tree in
|
||||
* either an iterative or recursive manner.
|
||||
* @param node - The `node` parameter represents the current node in the binary tree from which the
|
||||
* iteration starts. It is an optional parameter with a default value of `this.root`, which means
|
||||
* that if no node is provided, the iteration will start from the root of the binary tree.
|
||||
* @returns The `*[Symbol.iterator]` method returns a generator object that yields the keys of the
|
||||
* binary tree nodes in a specific order.
|
||||
*/
|
||||
* [Symbol.iterator](node = this.root): Generator<BinaryTreeNodeKey, void, undefined> {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.iterationType === IterationType.ITERATIVE) {
|
||||
const stack: (N | null | undefined)[] = [];
|
||||
let current: N | null | undefined = node;
|
||||
|
||||
while (current || stack.length > 0) {
|
||||
while (current) {
|
||||
stack.push(current);
|
||||
current = current.left;
|
||||
}
|
||||
|
||||
current = stack.pop();
|
||||
|
||||
if (current) yield current.key;
|
||||
if (current) current = current.right;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (node.left) {
|
||||
yield* this[Symbol.iterator](node.left);
|
||||
}
|
||||
yield node.key;
|
||||
if (node.right) {
|
||||
yield* this[Symbol.iterator](node.right);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Swap the data of two nodes in the binary tree.
|
||||
* @param {N} srcNode - The source node to swap.
|
||||
|
|
|
@ -19,8 +19,7 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
|
|||
|
||||
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>>
|
||||
extends BinaryTree<V, N>
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
implements IBinaryTree<V, N> {
|
||||
/**
|
||||
* The constructor function initializes a binary search tree object with an optional comparator
|
||||
* function.
|
||||
|
|
|
@ -21,8 +21,7 @@ export class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V
|
|||
|
||||
export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNested<V>>>
|
||||
extends BST<V, N>
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
implements IBinaryTree<V, N> {
|
||||
constructor(options?: RBTreeOptions) {
|
||||
super(options);
|
||||
}
|
||||
|
|
|
@ -37,8 +37,7 @@ export class TreeMultisetNode<
|
|||
*/
|
||||
export class TreeMultiset<V = any, N extends TreeMultisetNode<V, N> = TreeMultisetNode<V, TreeMultisetNodeNested<V>>>
|
||||
extends AVLTree<V, N>
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
implements IBinaryTree<V, N> {
|
||||
/**
|
||||
* The constructor function for a TreeMultiset class in TypeScript, which extends another class and sets an option to
|
||||
* merge duplicated values.
|
||||
|
|
|
@ -105,8 +105,7 @@ export abstract class AbstractEdge<V = any> {
|
|||
export abstract class AbstractGraph<
|
||||
V extends AbstractVertex<any> = AbstractVertex<any>,
|
||||
E extends AbstractEdge<any> = AbstractEdge<any>
|
||||
> implements IGraph<V, E>
|
||||
{
|
||||
> implements IGraph<V, E> {
|
||||
private _vertices: Map<VertexKey, V> = new Map<VertexKey, V>();
|
||||
|
||||
get vertices(): Map<VertexKey, V> {
|
||||
|
@ -554,14 +553,14 @@ export abstract class AbstractGraph<
|
|||
}
|
||||
|
||||
getMinDist &&
|
||||
distMap.forEach((d, v) => {
|
||||
if (v !== srcVertex) {
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
if (genPaths) minDest = v;
|
||||
}
|
||||
distMap.forEach((d, v) => {
|
||||
if (v !== srcVertex) {
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
if (genPaths) minDest = v;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
genPaths && getPaths(minDest);
|
||||
|
||||
|
@ -623,7 +622,7 @@ export abstract class AbstractGraph<
|
|||
if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);
|
||||
}
|
||||
|
||||
const heap = new PriorityQueue<{key: number; val: V}>({comparator: (a, b) => a.key - b.key});
|
||||
const heap = new PriorityQueue<{ key: number; val: V }>({comparator: (a, b) => a.key - b.key});
|
||||
heap.add({key: 0, val: srcVertex});
|
||||
|
||||
distMap.set(srcVertex, 0);
|
||||
|
@ -852,7 +851,7 @@ export abstract class AbstractGraph<
|
|||
* `predecessor` property is a 2D array of vertices (or `null`) representing the predecessor vertices in the shortest
|
||||
* path between vertices in the
|
||||
*/
|
||||
floyd(): {costs: number[][]; predecessor: (V | null)[][]} {
|
||||
floyd(): { costs: number[][]; predecessor: (V | null)[][] } {
|
||||
const idAndVertices = [...this._vertices];
|
||||
const n = idAndVertices.length;
|
||||
|
||||
|
|
|
@ -64,8 +64,7 @@ export class DirectedEdge<V = any> extends AbstractEdge<V> {
|
|||
|
||||
export class DirectedGraph<V extends DirectedVertex<any> = DirectedVertex, E extends DirectedEdge<any> = DirectedEdge>
|
||||
extends AbstractGraph<V, E>
|
||||
implements IGraph<V, E>
|
||||
{
|
||||
implements IGraph<V, E> {
|
||||
/**
|
||||
* The constructor function initializes an instance of a class.
|
||||
*/
|
||||
|
|
|
@ -51,12 +51,11 @@ export class UndirectedEdge<V = number> extends AbstractEdge<V> {
|
|||
}
|
||||
|
||||
export class UndirectedGraph<
|
||||
V extends UndirectedVertex<any> = UndirectedVertex,
|
||||
E extends UndirectedEdge<any> = UndirectedEdge
|
||||
>
|
||||
V extends UndirectedVertex<any> = UndirectedVertex,
|
||||
E extends UndirectedEdge<any> = UndirectedEdge
|
||||
>
|
||||
extends AbstractGraph<V, E>
|
||||
implements IGraph<V, E>
|
||||
{
|
||||
implements IGraph<V, E> {
|
||||
/**
|
||||
* The constructor initializes a new Map object to store edges.
|
||||
*/
|
||||
|
|
|
@ -157,7 +157,7 @@ export class HashMap<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
*entries(): IterableIterator<[K, V]> {
|
||||
* entries(): IterableIterator<[K, V]> {
|
||||
for (const bucket of this.table) {
|
||||
if (bucket) {
|
||||
for (const [key, value] of bucket) {
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export class TreeMap {}
|
||||
export class TreeMap {
|
||||
}
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export class TreeSet {}
|
||||
export class TreeSet {
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ export class Heap<E = any> {
|
|||
protected nodes: E[] = [];
|
||||
protected readonly comparator: Comparator<E>;
|
||||
|
||||
constructor(options: {comparator: Comparator<E>; nodes?: E[]}) {
|
||||
constructor(options: { comparator: Comparator<E>; nodes?: E[] }) {
|
||||
this.comparator = options.comparator;
|
||||
if (options.nodes && options.nodes.length > 0) {
|
||||
this.nodes = options.nodes;
|
||||
|
@ -39,7 +39,7 @@ export class Heap<E = any> {
|
|||
* @returns A new Heap instance.
|
||||
* @param options
|
||||
*/
|
||||
static heapify<E>(options: {nodes: E[]; comparator: Comparator<E>}): Heap<E> {
|
||||
static heapify<E>(options: { nodes: E[]; comparator: Comparator<E> }): Heap<E> {
|
||||
return new Heap<E>(options);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import type {Comparator} from '../../types';
|
|||
|
||||
export class MaxHeap<E = any> extends Heap<E> {
|
||||
constructor(
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -11,7 +11,7 @@ import type {Comparator} from '../../types';
|
|||
|
||||
export class MinHeap<E = any> extends Heap<E> {
|
||||
constructor(
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -625,6 +625,9 @@ export class DoublyLinkedList<E = any> {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function returns an iterator that iterates over the values of a linked list.
|
||||
*/
|
||||
* [Symbol.iterator]() {
|
||||
let current = this.head;
|
||||
|
||||
|
|
|
@ -587,6 +587,9 @@ export class SinglyLinkedList<E = any> {
|
|||
return accumulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function returns an iterator that iterates over the values of a linked list.
|
||||
*/
|
||||
* [Symbol.iterator]() {
|
||||
let current = this.head;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ export class MatrixNTI2D<V = any> {
|
|||
* given initial value or 0 if not provided.
|
||||
* @param options - An object containing the following properties:
|
||||
*/
|
||||
constructor(options: {row: number; col: number; initialVal?: V}) {
|
||||
constructor(options: { row: number; col: number; initialVal?: V }) {
|
||||
const {row, col, initialVal} = options;
|
||||
this._matrix = new Array(row).fill(undefined).map(() => new Array(col).fill(initialVal || 0));
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ export class Vector2D {
|
|||
public x: number = 0,
|
||||
public y: number = 0,
|
||||
public w: number = 1 // needed for matrix multiplication
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The function checks if the x and y values of a point are both zero.
|
||||
|
|
|
@ -10,7 +10,7 @@ import type {Comparator} from '../../types';
|
|||
|
||||
export class MaxPriorityQueue<E = any> extends PriorityQueue<E> {
|
||||
constructor(
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -10,7 +10,7 @@ import type {Comparator} from '../../types';
|
|||
|
||||
export class MinPriorityQueue<E = any> extends PriorityQueue<E> {
|
||||
constructor(
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -10,7 +10,7 @@ import {Heap} from '../heap';
|
|||
import {Comparator} from '../../types';
|
||||
|
||||
export class PriorityQueue<E = any> extends Heap<E> {
|
||||
constructor(options: {comparator: Comparator<E>; nodes?: E[]}) {
|
||||
constructor(options: { comparator: Comparator<E>; nodes?: E[] }) {
|
||||
super(options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import {DoublyLinkedList} from '../linked-list';
|
|||
|
||||
// O(n) time complexity of obtaining the value
|
||||
// O(1) time complexity of adding at the beginning and the end
|
||||
export class Deque<E = any> extends DoublyLinkedList<E> {}
|
||||
export class Deque<E = any> extends DoublyLinkedList<E> {
|
||||
}
|
||||
|
||||
// O(1) time complexity of obtaining the value
|
||||
// O(n) time complexity of adding at the beginning and the end
|
||||
|
@ -19,9 +20,9 @@ export class ObjectDeque<E = number> {
|
|||
if (capacity !== undefined) this._capacity = capacity;
|
||||
}
|
||||
|
||||
private _nodes: {[key: number]: E} = {};
|
||||
private _nodes: { [key: number]: E } = {};
|
||||
|
||||
get nodes(): {[p: number]: E} {
|
||||
get nodes(): { [p: number]: E } {
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
|
@ -156,7 +157,7 @@ export class ObjectDeque<E = number> {
|
|||
return this._size <= 0;
|
||||
}
|
||||
|
||||
protected _seNodes(value: {[p: number]: E}) {
|
||||
protected _seNodes(value: { [p: number]: E }) {
|
||||
this._nodes = value;
|
||||
}
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ export class Queue<E = any> {
|
|||
return new Queue(this.nodes.slice(this.offset));
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
* [Symbol.iterator]() {
|
||||
for (const item of this.nodes) {
|
||||
yield item;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export type Direction = 'up' | 'right' | 'down' | 'left';
|
||||
|
||||
export type Turning = {[key in Direction]: Direction};
|
||||
export type Turning = { [key in Direction]: Direction };
|
||||
|
||||
export type NavigatorParams<T = any> = {
|
||||
matrix: T[][];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export type ToThunkFn = () => ReturnType<TrlFn>;
|
||||
export type Thunk = () => ReturnType<ToThunkFn> & {__THUNK__: symbol};
|
||||
export type Thunk = () => ReturnType<ToThunkFn> & { __THUNK__: symbol };
|
||||
export type TrlFn = (...args: any[]) => any;
|
||||
export type TrlAsyncFn = (...args: any[]) => any;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export type KeyValueObject = {[key: string]: any};
|
||||
export type KeyValueObject = { [key: string]: any };
|
||||
|
||||
export type KeyValueObjectWithKey = {[key: string]: any; key: string | number | symbol};
|
||||
export type KeyValueObjectWithKey = { [key: string]: any; key: string | number | symbol };
|
||||
|
||||
export type NonNumberNonObjectButDefined = string | boolean | symbol | null;
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ describe('Individual package BST operations test', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
|
|
|
@ -219,7 +219,7 @@ describe('AVL Tree Test recursively', () => {
|
|||
});
|
||||
|
||||
describe('AVLTree APIs test', () => {
|
||||
const avl = new AVLTree<{id: number; text: string}>();
|
||||
const avl = new AVLTree<{ id: number; text: string }>();
|
||||
beforeEach(() => {
|
||||
avl.clear();
|
||||
});
|
||||
|
|
|
@ -125,11 +125,19 @@ describe('BinaryTree', () => {
|
|||
});
|
||||
|
||||
it('should traverse in-order', () => {
|
||||
tree.add(null);
|
||||
tree.delete(1);
|
||||
expect(tree.getHeight()).toBe(-1);
|
||||
tree.add(4);
|
||||
tree.add(2);
|
||||
expect(tree.getHeight()).toBe(1);
|
||||
tree.iterationType = IterationType.RECURSIVE;
|
||||
expect(tree.getHeight()).toBe(1);
|
||||
tree.iterationType = IterationType.ITERATIVE;
|
||||
|
||||
tree.add(6);
|
||||
tree.add(1);
|
||||
tree.add(3);
|
||||
tree.add(new BinaryTreeNode(3));
|
||||
tree.add(5);
|
||||
tree.add(7);
|
||||
|
||||
|
@ -160,6 +168,7 @@ describe('BinaryTree', () => {
|
|||
]);
|
||||
|
||||
expect(tree.isSubtreeBST(tree.get(4), IterationType.RECURSIVE)).toBe(true);
|
||||
expect(tree.isSubtreeBST(tree.get(4), IterationType.ITERATIVE)).toBe(true);
|
||||
});
|
||||
|
||||
it('should subTreeTraverse', () => {
|
||||
|
@ -197,6 +206,7 @@ describe('BinaryTree Morris Traversal', () => {
|
|||
|
||||
expect(result).toEqual(expected);
|
||||
expect(tree.dfs(node => node.key, 'in')).toEqual(expected);
|
||||
expect(tree.dfs(node => node.key, 'in', tree.root, IterationType.RECURSIVE)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should perform pre-order Morris traversal correctly as dfs traversal', () => {
|
||||
|
@ -231,7 +241,7 @@ describe('BinaryTree Morris Traversal', () => {
|
|||
});
|
||||
|
||||
describe('BinaryTree APIs test', () => {
|
||||
const avl = new AVLTree<{id: number; text: string}>();
|
||||
const avl = new AVLTree<{ id: number; text: string }>();
|
||||
beforeEach(() => {
|
||||
avl.clear();
|
||||
});
|
||||
|
@ -255,8 +265,10 @@ describe('BinaryTree traversals', () => {
|
|||
const arr = [35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55];
|
||||
tree.refill(arr);
|
||||
expect(tree.dfs(node => node.key, 'pre')).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
|
||||
expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
|
||||
expect(tree.dfs(node => node.key, 'in')).toEqual([15, 16, 20, 28, 29, 30, 35, 40, 45, 50, 55]);
|
||||
expect(tree.dfs(node => node.key, 'post')).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
|
||||
expect(tree.dfs(node => node.key, 'post', tree.root, IterationType.RECURSIVE)).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
|
||||
expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
||||
]);
|
||||
|
@ -281,7 +293,7 @@ describe('BinaryTree', () => {
|
|||
let tree: BinaryTree<string>;
|
||||
|
||||
beforeEach(() => {
|
||||
tree = new BinaryTree<string>();
|
||||
tree = new BinaryTree<string>({iterationType: IterationType.RECURSIVE});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -441,6 +453,14 @@ describe('BinaryTree', () => {
|
|||
tree.add(3, 'B');
|
||||
tree.add(7, 'C');
|
||||
|
||||
tree.iterationType = IterationType.ITERATIVE;
|
||||
// @ts-ignore
|
||||
expect([...tree]).toEqual([3, 5, 7]);
|
||||
tree.iterationType = IterationType.RECURSIVE;
|
||||
// @ts-ignore
|
||||
expect([...tree]).toEqual([3, 5, 7]);
|
||||
tree.iterationType = IterationType.ITERATIVE;
|
||||
|
||||
const result = tree.morris();
|
||||
expect(result).toEqual([3, 5, 7]);
|
||||
// Add assertions for the result of Morris traversal
|
||||
|
|
|
@ -189,7 +189,7 @@ describe('BST operations test', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
|
@ -260,7 +260,7 @@ describe('BST operations test', () => {
|
|||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
objBST.bfs(node => bfsNodesAfterBalanced.push(node));
|
||||
expect(bfsNodesAfterBalanced[0].key).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
@ -385,7 +385,7 @@ describe('BST operations test', () => {
|
|||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
objBST.bfs(node => bfsNodes.push(node));
|
||||
expect(bfsNodes[0].key).toBe(2);
|
||||
expect(bfsNodes[1].key).toBe(12);
|
||||
|
@ -579,7 +579,7 @@ describe('BST operations test recursively', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
|
@ -650,7 +650,7 @@ describe('BST operations test recursively', () => {
|
|||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
objBST.bfs(node => bfsNodesAfterBalanced.push(node));
|
||||
expect(bfsNodesAfterBalanced[0].key).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
@ -775,7 +775,7 @@ describe('BST operations test recursively', () => {
|
|||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
objBST.bfs(node => bfsNodes.push(node));
|
||||
expect(bfsNodes[0].key).toBe(2);
|
||||
expect(bfsNodes[1].key).toBe(12);
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('Overall BinaryTree Test', () => {
|
|||
bfsIDs[0] === 11; // true
|
||||
expect(bfsIDs[0]).toBe(11);
|
||||
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ describe('TreeMultiset operations test', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objTreeMultiset = new TreeMultiset<{key: number; keyA: number}>();
|
||||
const objTreeMultiset = new TreeMultiset<{ key: number; keyA: number }>();
|
||||
expect(objTreeMultiset).toBeInstanceOf(TreeMultiset);
|
||||
objTreeMultiset.add(11, {key: 11, keyA: 11});
|
||||
objTreeMultiset.add(3, {key: 3, keyA: 3});
|
||||
|
@ -447,7 +447,7 @@ describe('TreeMultiset operations test recursively', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objTreeMultiset = new TreeMultiset<{key: number; keyA: number}>();
|
||||
const objTreeMultiset = new TreeMultiset<{ key: number; keyA: number }>();
|
||||
expect(objTreeMultiset).toBeInstanceOf(TreeMultiset);
|
||||
objTreeMultiset.add(11, {key: 11, keyA: 11});
|
||||
objTreeMultiset.add(3, {key: 3, keyA: 3});
|
||||
|
|
|
@ -52,3 +52,23 @@ describe('CoordinateMap', () => {
|
|||
expect(retrievedValue).toBe(value);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CoordinateMap', () => {
|
||||
class MyCoordinateMap<V = any> extends CoordinateMap<V> {
|
||||
constructor(joint?: string) {
|
||||
super(joint);
|
||||
this._setJoint(joint += '-')
|
||||
}
|
||||
}
|
||||
|
||||
const cMap = new MyCoordinateMap<number>('*');
|
||||
|
||||
beforeEach(() => {
|
||||
cMap.set([0, 0], 0);
|
||||
cMap.set([0, 1], 1);
|
||||
cMap.set([1, 1], 11);
|
||||
})
|
||||
it('should joint to be *-', () => {
|
||||
expect(cMap.joint).toBe('*-');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -39,3 +39,28 @@ describe('CoordinateSet', () => {
|
|||
expect(hasValue).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('MyCoordinateSet', () => {
|
||||
class MyCoordinateSet extends CoordinateSet {
|
||||
constructor(joint?: string) {
|
||||
super(joint);
|
||||
this._setJoint(joint += '-')
|
||||
}
|
||||
}
|
||||
|
||||
const mySet = new MyCoordinateSet('*');
|
||||
|
||||
beforeEach(() => {
|
||||
mySet.add([0, 0]);
|
||||
mySet.add([0, 1]);
|
||||
mySet.add([1, 1]);
|
||||
})
|
||||
it('should joint to be *-', () => {
|
||||
expect(mySet.joint).toBe('*-');
|
||||
});
|
||||
|
||||
it('should has, delete', () => {
|
||||
mySet.delete([0, 1]);
|
||||
expect(mySet.has([0, 1])).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,7 +15,9 @@ describe('HashNode', () => {
|
|||
describe('HashTable', () => {
|
||||
it('should initialize with default capacity', () => {
|
||||
const hashTable = new HashTable<string, string>();
|
||||
|
||||
hashTable.capacity = hashTable.capacity;
|
||||
hashTable.buckets = hashTable.buckets;
|
||||
hashTable.hashFn = hashTable.hashFn;
|
||||
expect(hashTable.capacity).toBe(16);
|
||||
expect(hashTable.size).toBe(0);
|
||||
expect(hashTable.buckets.length).toBe(16);
|
||||
|
|
|
@ -22,7 +22,7 @@ describe('Heap Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should object heap work well', function () {
|
||||
const minHeap = new MinHeap<{a: string; key: number}>({comparator: (a, b) => a.key - b.key});
|
||||
const minHeap = new MinHeap<{ a: string; key: number }>({comparator: (a, b) => a.key - b.key});
|
||||
minHeap.add({key: 1, a: 'a1'});
|
||||
minHeap.add({key: 6, a: 'a6'});
|
||||
minHeap.add({key: 2, a: 'a2'});
|
||||
|
@ -37,7 +37,7 @@ describe('Heap Operation Test', () => {
|
|||
i++;
|
||||
}
|
||||
|
||||
const maxHeap = new MaxHeap<{key: number; a: string}>({comparator: (a, b) => b.key - a.key});
|
||||
const maxHeap = new MaxHeap<{ key: number; a: string }>({comparator: (a, b) => b.key - a.key});
|
||||
maxHeap.add({key: 1, a: 'a1'});
|
||||
maxHeap.add({key: 6, a: 'a6'});
|
||||
maxHeap.add({key: 5, a: 'a5'});
|
||||
|
|
|
@ -1,9 +1,72 @@
|
|||
import {DoublyLinkedList} from '../../../../src';
|
||||
import {DoublyLinkedList, DoublyLinkedListNode} from '../../../../src';
|
||||
import {bigO, magnitude} from '../../../utils';
|
||||
|
||||
describe('DoublyLinkedListNode', () => {
|
||||
it('should DoublyLinkedListNode', () => {
|
||||
const node1 = new DoublyLinkedListNode<number>(2);
|
||||
expect(node1.val).toBe(2);
|
||||
node1.val = 1;
|
||||
expect(node1.val).toBe(1);
|
||||
})
|
||||
});
|
||||
|
||||
describe('DoublyLinkedList Operation Test', () => {
|
||||
let list: DoublyLinkedList<number>;
|
||||
let objectList: DoublyLinkedList<{keyA: number}>;
|
||||
|
||||
beforeEach(() => {
|
||||
list = DoublyLinkedList.fromArray([1, 2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
it('should out of bound index', () => {
|
||||
expect(list.getNodeAt(-1)).toBe(null);
|
||||
expect(list.getNodeAt(5)).toBe(null);
|
||||
expect(list.insertAt(5, 6)).toBe(true);
|
||||
});
|
||||
|
||||
it('should insertBefore', () => {
|
||||
expect(list.insertBefore(1, 0)).toBe(true);
|
||||
});
|
||||
|
||||
it('should deleteAt', () => {
|
||||
expect(list.deleteAt(1)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should delete tail', () => {
|
||||
expect(list.delete(list.tail)).toBe(true);
|
||||
expect(list.tail?.val).toBe(4);
|
||||
expect(list.delete(6)).toBe(false);
|
||||
expect(list.tail?.val).toBe(4);
|
||||
});
|
||||
|
||||
|
||||
it('should find null', () => {
|
||||
expect(list.find(val => val === 6)).toBe(null);
|
||||
|
||||
});
|
||||
|
||||
it('should indexOf -1', () => {
|
||||
expect(list.indexOf(6)).toBe(-1);
|
||||
});
|
||||
|
||||
it('should findBackward null', () => {
|
||||
expect(list.findBackward(val => val === 0)).toBe(null);
|
||||
});
|
||||
|
||||
it('should insertAfter tail', () => {
|
||||
expect(list.insertAfter(list.tail!, 6)).toBe(true);
|
||||
});
|
||||
|
||||
it('should insertAfter tail', () => {
|
||||
// @ts-ignore
|
||||
expect([...list]).toEqual([1, 2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('DoublyLinkedList Operation Test', () => {
|
||||
let list: DoublyLinkedList<number>;
|
||||
let objectList: DoublyLinkedList<{ keyA: number }>;
|
||||
|
||||
beforeEach(() => {
|
||||
list = new DoublyLinkedList();
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
import {SinglyLinkedList} from '../../../../src';
|
||||
import {SinglyLinkedList, SinglyLinkedListNode} from '../../../../src';
|
||||
import {bigO, magnitude} from '../../../utils';
|
||||
|
||||
describe('SinglyLinkedListNode', () => {
|
||||
it('should SinglyLinkedList', () => {
|
||||
const node1 = new SinglyLinkedListNode<number>(2);
|
||||
expect(node1.val).toBe(2);
|
||||
node1.val = 1;
|
||||
expect(node1.val).toBe(1);
|
||||
})
|
||||
});
|
||||
|
||||
describe('SinglyLinkedList Operation Test', () => {
|
||||
let list: SinglyLinkedList<number>;
|
||||
let objectList: SinglyLinkedList<{keyA: number}>;
|
||||
let objectList: SinglyLinkedList<{ keyA: number }>;
|
||||
beforeEach(() => {
|
||||
list = new SinglyLinkedList<number>();
|
||||
objectList = new SinglyLinkedList<{keyA: number}>();
|
||||
objectList = new SinglyLinkedList<{ keyA: number }>();
|
||||
});
|
||||
|
||||
describe('push', () => {
|
||||
|
@ -21,8 +30,10 @@ describe('SinglyLinkedList Operation Test', () => {
|
|||
it('should delete and return the last element of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const popped = list.pop();
|
||||
expect(popped).toBe(2);
|
||||
expect(popped).toBe(3);
|
||||
expect(list.popLast()).toBe(2);
|
||||
expect(list.toArray()).toEqual([1]);
|
||||
});
|
||||
|
||||
|
@ -36,9 +47,11 @@ describe('SinglyLinkedList Operation Test', () => {
|
|||
it('should delete and return the first element of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const shifted = list.shift();
|
||||
expect(shifted).toBe(1);
|
||||
expect(list.toArray()).toEqual([2]);
|
||||
expect(list.popFirst()).toBe(2);
|
||||
expect(list.toArray()).toEqual([3]);
|
||||
});
|
||||
|
||||
it('should return undefined if the list is empty', () => {
|
||||
|
@ -50,7 +63,7 @@ describe('SinglyLinkedList Operation Test', () => {
|
|||
describe('unshift', () => {
|
||||
it('should add elements to the beginning of the list', () => {
|
||||
list.unshift(1);
|
||||
list.unshift(2);
|
||||
list.addFirst(2);
|
||||
expect(list.toArray()).toEqual([2, 1]);
|
||||
});
|
||||
});
|
||||
|
@ -62,6 +75,7 @@ describe('SinglyLinkedList Operation Test', () => {
|
|||
list.push(3);
|
||||
const element = list.getAt(1);
|
||||
expect(element).toBe(2);
|
||||
expect(list.getNodeAt(2)?.val).toBe(3);
|
||||
});
|
||||
|
||||
it('should return undefined for an out-of-bounds index', () => {
|
||||
|
@ -113,9 +127,14 @@ describe('SinglyLinkedList Operation Test', () => {
|
|||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const removed = list.delete(2);
|
||||
expect(removed).toBe(true);
|
||||
expect(list.toArray()).toEqual([1, 3]);
|
||||
list.push(4);
|
||||
list.push(5);
|
||||
expect(list.delete(2)).toBe(true);
|
||||
expect(list.toArray()).toEqual([1, 3, 4, 5]);
|
||||
expect(list.delete(1)).toBe(true);
|
||||
expect(list.toArray()).toEqual([3, 4, 5]);
|
||||
expect(list.delete(5)).toBe(true);
|
||||
expect(list.toArray()).toEqual([3, 4]);
|
||||
});
|
||||
|
||||
it('should return false if the value is not found', () => {
|
||||
|
@ -427,7 +446,6 @@ describe('SinglyLinkedList', () => {
|
|||
expect(list.length).toBe(1);
|
||||
});
|
||||
|
||||
// Add more test cases for other methods like shift, unshift, getAt, deleteAt, and more.
|
||||
|
||||
it('should reverse the list', () => {
|
||||
list.push(1);
|
||||
|
@ -439,7 +457,6 @@ describe('SinglyLinkedList', () => {
|
|||
// Add more assertions for reversed order.
|
||||
});
|
||||
|
||||
// Add more test cases for other methods like find, indexOf, and more.
|
||||
|
||||
it('should convert the list to an array', () => {
|
||||
list.push(1);
|
||||
|
@ -447,5 +464,35 @@ describe('SinglyLinkedList', () => {
|
|||
list.push(3);
|
||||
const array = list.toArray();
|
||||
expect(array).toEqual([1, 2, 3]);
|
||||
// @ts-ignore
|
||||
expect([...list]).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should filter the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
expect(list.filter(val => val !== 2).toArray()).toEqual([1, 3]);
|
||||
});
|
||||
|
||||
|
||||
it('should forEach the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.forEach(val => val++);
|
||||
expect(list.toArray()).toEqual([1, 2, 3])
|
||||
});
|
||||
|
||||
it('should map the list', () => {
|
||||
list.addLast(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
expect(list.map(val => val * 2).toArray()).toEqual([2, 4, 6]);
|
||||
});
|
||||
|
||||
it('should reduce the list', () => {
|
||||
const list1 = SinglyLinkedList.fromArray([1, 2, 3]);
|
||||
expect(list1.reduce((acc, val) => acc + val, 0)).toEqual(6);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,7 +17,7 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should add elements and maintain heap property in a object MaxPriorityQueue', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<{keyA: number}>({comparator: (a, b) => b.keyA - a.keyA});
|
||||
const priorityQueue = new MaxPriorityQueue<{ keyA: number }>({comparator: (a, b) => b.keyA - a.keyA});
|
||||
priorityQueue.refill([{keyA: 5}, {keyA: 3}, {keyA: 1}]);
|
||||
priorityQueue.add({keyA: 7});
|
||||
|
||||
|
@ -64,7 +64,7 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
|
||||
it('should correctly heapify an object array', () => {
|
||||
const nodes = [{keyA: 5}, {keyA: 3}, {keyA: 7}, {keyA: 1}];
|
||||
const maxPQ = MaxPriorityQueue.heapify<{keyA: number}>({nodes: nodes, comparator: (a, b) => b.keyA - a.keyA});
|
||||
const maxPQ = MaxPriorityQueue.heapify<{ keyA: number }>({nodes: nodes, comparator: (a, b) => b.keyA - a.keyA});
|
||||
|
||||
expect(maxPQ.poll()?.keyA).toBe(7);
|
||||
expect(maxPQ.poll()?.keyA).toBe(5);
|
||||
|
|
|
@ -26,7 +26,7 @@ export const bigO = {
|
|||
|
||||
function findPotentialN(input: any): number {
|
||||
let longestArray: any[] = [];
|
||||
let mostProperties: {[key: string]: any} = {};
|
||||
let mostProperties: { [key: string]: any } = {};
|
||||
|
||||
function recurse(obj: any) {
|
||||
if (Array.isArray(obj)) {
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
const path = require('path');
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
mode:'production',
|
||||
entry: './src/index.ts',
|
||||
target: 'web',
|
||||
output: {
|
||||
filename: 'bundle.min.js',
|
||||
path: path.resolve(__dirname, 'umd'),
|
||||
library: 'dataStructureTyped',
|
||||
libraryTarget: 'umd',
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
}
|
||||
],
|
||||
},
|
||||
devtool: 'source-map',
|
||||
},
|
||||
];
|
Loading…
Reference in a new issue