diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c77fa3..74178ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. - [Semantic Versioning](https://semver.org/spec/v2.0.0.html) - [`auto-changelog`](https://github.com/CookPete/auto-changelog) -## [v1.49.2](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) +## [v1.49.3](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) ### Changes diff --git a/README.md b/README.md index c678eba..a28ff33 100644 --- a/README.md +++ b/README.md @@ -196,10 +196,54 @@ our [visual tool](https://github.com/zrwusa/vivid-algorithm) ## Code Snippets -### Binary Search Tree (BST) snippet +### RedBlackTree snippet #### TS +```ts +import {RedBlackTree} from 'data-structure-typed'; + +const rbTree = new RedBlackTree(); +rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]) +rbTree.isAVLBalanced(); // true +rbTree.delete(10); +rbTree.isAVLBalanced(); // true +rbTree.print() +// ___6________ +// / \ +// ___4_ ___11________ +// / \ / \ +// _2_ 5 _8_ ____14__ +// / \ / \ / \ +// 1 3 7 9 12__ 15__ +// \ \ +// 13 16 +``` + +#### JS + +```js +import {RedBlackTree} from 'data-structure-typed'; + +const rbTree = new RedBlackTree(); +rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]) +rbTree.isAVLBalanced(); // true +rbTree.delete(10); +rbTree.isAVLBalanced(); // true +rbTree.print() +// ___6________ +// / \ +// ___4_ ___11________ +// / \ / \ +// _2_ 5 _8_ ____14__ +// / \ / \ / \ +// 1 3 7 9 12__ 15__ +// \ \ +// 13 16 +``` + +### Binary Search Tree (BST) snippet + ```ts import {BST, BSTNode} from 'data-structure-typed'; @@ -259,31 +303,6 @@ objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], [ objBST.delete(11); ``` -#### JS - -```js -const {BST, BSTNode} = require('data-structure-typed'); - -const bst = new BST(); -bst.add(11); -bst.add(3); -bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]); -bst.size === 16; // true -bst.has(6); // true -const node6 = bst.getNode(6); -bst.getHeight(6) === 2; // true -bst.getHeight() === 5; // true -bst.getDepth(6) === 3; // true -const leftMost = bst.getLeftMost(); -leftMost?.key === 1; // true - -bst.delete(6); -bst.get(6); // undefined -bst.isAVLBalanced(); // true or false -const bfsIDs = bst.bfs(); -bfsIDs[0] === 11; // true -``` - ### AVLTree snippet ```ts @@ -296,28 +315,6 @@ avlTree.delete(10); avlTree.isAVLBalanced(); // true ``` -### RedBlackTree snippet - -```ts -import {RedBlackTree} from 'data-structure-typed'; - -const rbTree = new RedBlackTree(); -rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]) -rbTree.isAVLBalanced(); // true -rbTree.delete(10); -rbTree.isAVLBalanced(); // true -rbTree.print() -// ___6________ -// / \ -// ___4_ ___11________ -// / \ / \ -// _2_ 5 _8_ ____14__ -// / \ / \ / \ -// 1 3 7 9 12__ 15__ -// \ \ -// 13 16 -``` - ### Directed Graph simple snippet ```ts @@ -672,7 +669,7 @@ avl2.print(); -## Standard library data structure comparison +## The corresponding relationships between data structures in different language standard libraries. @@ -686,9 +683,15 @@ avl2.print(); + + + + + + - + @@ -981,52 +984,52 @@ avl2.print(); [//]: # (No deletion!!! Start of Replace Section)
avl-tree
-
Heap<E>--heapq
PriorityQueue<E> priority_queue<T> PriorityQueue<E>heapq-
Deque<E>
test nametime taken (ms)executions per secsample deviation
10,000 add randomly50.7419.710.00
10,000 add & delete randomly127.767.830.02
10,000 addMany57.1417.500.00
10,000 get52.2219.150.01
+
test nametime taken (ms)executions per secsample deviation
10,000 add randomly48.4220.650.00
10,000 add & delete randomly107.729.280.02
10,000 addMany55.4018.056.22e-4
10,000 get53.8918.560.02
binary-tree
-
test nametime taken (ms)executions per secsample deviation
1,000 add randomly18.3254.590.00
1,000 add & delete randomly26.5437.690.01
1,000 addMany18.7953.220.00
1,000 get18.9552.780.00
1,000 has19.7650.600.01
1,000 dfs159.966.250.01
1,000 bfs73.6313.580.08
1,000 morris225.934.430.05
+
test nametime taken (ms)executions per secsample deviation
1,000 add randomly17.7556.352.23e-4
1,000 add & delete randomly25.5839.100.01
1,000 addMany19.6550.890.00
1,000 get21.0347.550.01
1,000 has19.8150.480.01
1,000 dfs183.375.450.03
1,000 bfs65.6115.240.02
1,000 morris231.004.330.06
bst
-
test nametime taken (ms)executions per secsample deviation
10,000 add randomly48.8020.492.79e-4
10,000 add & delete randomly110.729.030.00
10,000 addMany46.1921.650.00
10,000 get49.2820.297.92e-4
+
test nametime taken (ms)executions per secsample deviation
10,000 add randomly49.9620.027.65e-4
10,000 add & delete randomly116.778.560.02
10,000 addMany49.0620.380.01
10,000 get49.0620.387.13e-4
rb-tree
-
test nametime taken (ms)executions per secsample deviation
100,000 add80.8412.370.00
100,000 add & delete randomly206.654.840.01
100,000 getNode57.4217.420.00
100,000 add & iterator109.599.120.00
+
test nametime taken (ms)executions per secsample deviation
100,000 add83.4211.990.01
100,000 add & delete randomly243.054.110.07
100,000 getNode218.874.570.05
100,000 add & iterator124.228.050.01
comparison
-
test nametime taken (ms)executions per secsample deviation
SRC PQ 10,000 add0.146917.741.81e-6
CJS PQ 10,000 add0.156883.533.84e-6
MJS PQ 10,000 add0.571761.705.07e-6
SRC PQ 10,000 add & poll3.45289.743.63e-4
CJS PQ 10,000 add & poll3.53283.144.73e-5
MJS PQ 10,000 add & poll3.31302.383.64e-5
+
test nametime taken (ms)executions per secsample deviation
SRC PQ 10,000 add0.156710.401.90e-5
CJS PQ 10,000 add0.166407.424.25e-5
MJS PQ 10,000 add0.621602.371.51e-4
SRC PQ 10,000 add & poll3.67272.420.00
CJS PQ 10,000 add & poll3.95252.900.00
MJS PQ 10,000 add & poll3.33300.288.65e-5
directed-graph
-
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.109860.539.32e-7
1,000 addEdge6.34157.718.55e-4
1,000 getVertex0.052.16e+44.61e-7
1,000 getEdge22.6744.120.00
tarjan217.594.600.01
tarjan all6489.860.150.09
topologicalSort179.225.580.00
+
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.118958.103.30e-5
1,000 addEdge6.37156.981.96e-4
1,000 getVertex0.052.04e+48.22e-6
1,000 getEdge24.4940.830.00
tarjan235.544.250.04
tarjan all6766.740.150.32
topologicalSort197.525.060.04
hash-map
-
test nametime taken (ms)executions per secsample deviation
1,000,000 set108.759.200.04
Native Map 1,000,000 set217.554.600.02
Native Set 1,000,000 add179.675.570.03
1,000,000 set & get122.668.150.03
Native Map 1,000,000 set & get282.473.540.04
Native Set 1,000,000 add & has174.485.730.02
1,000,000 ObjKey set & get336.832.970.06
Native Map 1,000,000 ObjKey set & get314.003.180.06
Native Set 1,000,000 ObjKey add & has267.843.730.03
+
test nametime taken (ms)executions per secsample deviation
1,000,000 set117.828.490.05
Native Map 1,000,000 set220.924.530.03
Native Set 1,000,000 add187.445.340.02
1,000,000 set & get125.447.970.04
Native Map 1,000,000 set & get300.103.330.06
Native Set 1,000,000 add & has200.884.980.02
1,000,000 ObjKey set & get361.002.770.06
Native Map 1,000,000 ObjKey set & get335.342.980.09
Native Set 1,000,000 ObjKey add & has261.283.830.07
heap
-
test nametime taken (ms)executions per secsample deviation
100,000 add & poll80.4912.420.00
100,000 add & dfs34.0129.403.88e-4
10,000 fib add & pop359.702.780.00
+
test nametime taken (ms)executions per secsample deviation
100,000 add & poll80.4312.430.00
100,000 add & dfs36.9527.070.00
10,000 fib add & pop386.632.590.05
doubly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push229.174.360.06
1,000,000 unshift220.534.530.06
1,000,000 unshift & shift172.125.810.03
1,000,000 addBefore309.583.230.06
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push235.154.250.07
1,000,000 unshift245.364.080.08
1,000,000 unshift & shift175.535.700.03
1,000,000 addBefore319.213.130.06
singly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift211.624.730.06
10,000 push & pop219.724.550.03
10,000 addBefore249.094.010.01
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift202.024.950.04
10,000 push & pop228.774.370.04
10,000 addBefore274.253.650.05
max-priority-queue
-
test nametime taken (ms)executions per secsample deviation
10,000 refill & poll8.96111.611.80e-4
+
test nametime taken (ms)executions per secsample deviation
10,000 refill & poll9.39106.510.00
priority-queue
-
test nametime taken (ms)executions per secsample deviation
100,000 add & poll106.149.420.00
+
test nametime taken (ms)executions per secsample deviation
100,000 add & poll114.368.740.02
deque
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push13.9171.894.15e-4
1,000,000 push & pop22.8243.832.45e-4
100,000 push & shift2.38420.493.61e-5
Native Array 100,000 push & shift2718.620.370.35
100,000 unshift & shift2.28438.784.18e-4
Native Array 100,000 unshift & shift4065.010.250.21
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push14.8167.510.00
1,000,000 push & pop25.3439.470.01
100,000 push & shift2.49400.867.97e-4
Native Array 100,000 push & shift2390.920.420.17
100,000 unshift & shift2.48403.146.46e-4
Native Array 100,000 unshift & shift4462.410.220.34
queue
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push44.4622.490.01
100,000 push & shift5.16193.830.00
Native Array 100,000 push & shift2195.560.460.29
Native Array 100,000 push & pop4.40227.040.00
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push51.9919.240.03
100,000 push & shift5.23191.347.00e-4
Native Array 100,000 push & shift2400.960.420.28
Native Array 100,000 push & pop4.36229.521.14e-4
stack
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push44.0522.700.01
1,000,000 push & pop49.7220.110.01
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push43.5522.960.01
1,000,000 push & pop55.2918.090.01
trie
-
test nametime taken (ms)executions per secsample deviation
100,000 push44.3322.560.00
100,000 getWords88.4711.300.01
+
test nametime taken (ms)executions per secsample deviation
100,000 push48.6620.550.00
100,000 getWords95.0910.520.01
[//]: # (No deletion!!! End of Replace Section) diff --git a/README_zh-CN.md b/README_zh-CN.md index 97709e0..7d72ecb 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -199,9 +199,51 @@ const { ## 代码片段 -### 二叉搜索树 (BST) 代码示例 +### 红黑树 代码示例 #### TS +```ts +import {RedBlackTree} from 'data-structure-typed'; + +const rbTree = new RedBlackTree(); +rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]) +rbTree.isAVLBalanced(); // true +rbTree.delete(10); +rbTree.isAVLBalanced(); // true +rbTree.print() +// ___6________ +// / \ +// ___4_ ___11________ +// / \ / \ +// _2_ 5 _8_ ____14__ +// / \ / \ / \ +// 1 3 7 9 12__ 15__ +// \ \ +// 13 16 +``` + +#### JS +```js +import {RedBlackTree} from 'data-structure-typed'; + +const rbTree = new RedBlackTree(); +rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]) +rbTree.isAVLBalanced(); // true +rbTree.delete(10); +rbTree.isAVLBalanced(); // true +rbTree.print() +// ___6________ +// / \ +// ___4_ ___11________ +// / \ / \ +// _2_ 5 _8_ ____14__ +// / \ / \ / \ +// 1 3 7 9 12__ 15__ +// \ \ +// 13 16 +``` + +### 二叉搜索树 (BST) 代码示例 ```ts import {BST, BSTNode} from 'data-structure-typed'; @@ -262,31 +304,6 @@ objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], [ objBST.delete(11); ``` -#### JS - -```js -const {BST, BSTNode} = require('data-structure-typed'); - -const bst = new BST(); -bst.add(11); -bst.add(3); -bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]); -bst.size === 16; // true -bst.has(6); // true -const node6 = bst.getNode(6); -bst.getHeight(6) === 2; // true -bst.getHeight() === 5; // true -bst.getDepth(6) === 3; // true -const leftMost = bst.getLeftMost(); -leftMost?.key === 1; // true - -bst.delete(6); -bst.get(6); // undefined -bst.isAVLBalanced(); // true or false -const bfsIDs = bst.bfs(); -bfsIDs[0] === 11; // true -``` - ### AVL树 代码示例 ```ts @@ -299,28 +316,6 @@ avlTree.delete(10); avlTree.isAVLBalanced(); // true ``` -### 红黑树 代码示例 - -```ts -import {RedBlackTree} from 'data-structure-typed'; - -const rbTree = new RedBlackTree(); -rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]) -rbTree.isAVLBalanced(); // true -rbTree.delete(10); -rbTree.isAVLBalanced(); // true -rbTree.print() -// ___6________ -// / \ -// ___4_ ___11________ -// / \ / \ -// _2_ 5 _8_ ____14__ -// / \ / \ / \ -// 1 3 7 9 12__ 15__ -// \ \ -// 13 16 -``` - ### 有向图代码示例 ```ts diff --git a/package.json b/package.json index d860f64..441ed2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "data-structure-typed", - "version": "1.49.2", + "version": "1.49.3", "description": "Data Structures of Javascript & TypeScript. Heap, Binary Tree, Red Black Tree, Linked List, Deque, Trie, HashMap, Directed Graph, Undirected Graph, Binary Search Tree(BST), AVL Tree, Priority Queue, Graph, Queue, Tree Multiset, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue, Stack. Benchmark compared with C++ STL. API aligned with ES6 and Java.util. Usability is comparable to Python", "main": "dist/cjs/index.js", "module": "dist/mjs/index.js", diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts index b9a3637..3dd5e1c 100644 --- a/src/data-structures/binary-tree/binary-tree.ts +++ b/src/data-structures/binary-tree/binary-tree.ts @@ -1957,7 +1957,7 @@ export class BinaryTree = Bi } } - protected _defaultOneParamCallback = (node: N) => node.key; + protected _defaultOneParamCallback = (node: N | null | undefined) => node ? node.key : undefined; /** * Swap the data of two nodes in the binary tree. diff --git a/src/data-structures/graph/abstract-graph.ts b/src/data-structures/graph/abstract-graph.ts index 00f4586..4917541 100644 --- a/src/data-structures/graph/abstract-graph.ts +++ b/src/data-structures/graph/abstract-graph.ts @@ -173,19 +173,7 @@ export abstract class AbstractGraph< * Space Complexity: O(1) - Constant space, as it creates only a few variables. */ - /** - * Time Complexity: O(1) - Constant time for Map operations. - * Space Complexity: O(1) - Constant space, as it creates only a few variables. - * - * The `deleteVertex` function removes a vertex from a graph by its ID or by the vertex object itself. - * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID - * (`VertexKey`). - * @returns The method is returning a boolean value. - */ - deleteVertex(vertexOrKey: VO | VertexKey): boolean { - const vertexKey = this._getVertexKey(vertexOrKey); - return this._vertexMap.delete(vertexKey); - } + abstract deleteVertex(vertexOrKey: VO | VertexKey): boolean; /** * Time Complexity: O(K), where K is the number of vertexMap to be removed. diff --git a/src/data-structures/graph/directed-graph.ts b/src/data-structures/graph/directed-graph.ts index e863a3c..09d8393 100644 --- a/src/data-structures/graph/directed-graph.ts +++ b/src/data-structures/graph/directed-graph.ts @@ -240,7 +240,7 @@ export class DirectedGraph< * (`VertexKey`). * @returns The method is returning a boolean value. */ - override deleteVertex(vertexOrKey: VO | VertexKey): boolean { + deleteVertex(vertexOrKey: VO | VertexKey): boolean { let vertexKey: VertexKey; let vertex: VO | undefined; if (this.isVertexKey(vertexOrKey)) { @@ -252,8 +252,12 @@ export class DirectedGraph< } if (vertex) { - this._outEdgeMap.delete(vertex) - this._inEdgeMap.delete(vertex) + const neighbors = this.getNeighbors(vertex); + for (const neighbor of neighbors) { + this._inEdgeMap.delete(neighbor); + } + this._outEdgeMap.delete(vertex); + this._inEdgeMap.delete(vertex); } return this._vertexMap.delete(vertexKey); diff --git a/src/data-structures/graph/undirected-graph.ts b/src/data-structures/graph/undirected-graph.ts index 45241b9..8f56e3c 100644 --- a/src/data-structures/graph/undirected-graph.ts +++ b/src/data-structures/graph/undirected-graph.ts @@ -212,7 +212,7 @@ export class UndirectedGraph< * (`VertexKey`). * @returns The method is returning a boolean value. */ - override deleteVertex(vertexOrKey: VO | VertexKey): boolean { + deleteVertex(vertexOrKey: VO | VertexKey): boolean { let vertexKey: VertexKey; let vertex: VO | undefined; if (this.isVertexKey(vertexOrKey)) { diff --git a/src/data-structures/linked-list/singly-linked-list.ts b/src/data-structures/linked-list/singly-linked-list.ts index b3d970d..3010040 100644 --- a/src/data-structures/linked-list/singly-linked-list.ts +++ b/src/data-structures/linked-list/singly-linked-list.ts @@ -33,8 +33,7 @@ export class SinglyLinkedList extends IterableElementBase { this._tail = undefined; this._size = 0; if (elements) { - for (const el of elements) - this.push(el); + for (const el of elements) this.push(el); } } diff --git a/test/performance/data-structures/comparison/comparison.test.ts b/test/performance/data-structures/comparison/comparison.test.ts index 9932868..1e914f0 100644 --- a/test/performance/data-structures/comparison/comparison.test.ts +++ b/test/performance/data-structures/comparison/comparison.test.ts @@ -16,7 +16,7 @@ import { getRandomIntArray, magnitude } from '../../../utils'; import { isCompetitor } from '../../../config'; const suite = new Benchmark.Suite(); -const { TEN_THOUSAND, HUNDRED_THOUSAND, LINEAR } = magnitude; +const { TEN_THOUSAND, HUNDRED_THOUSAND, MILLION } = magnitude; const cOrderedMap = new OrderedMap(); const arrHundredThousand = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true); @@ -96,10 +96,10 @@ if (isCompetitor) { hm.getElementByKey(i); } }) - .add(`CPT LL ${LINEAR.toLocaleString()} unshift`, () => { + .add(`CPT LL ${MILLION.toLocaleString()} unshift`, () => { const list = new CLinkedList(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { list.pushFront(i); } }) @@ -114,33 +114,33 @@ if (isCompetitor) { pq.pop(); } }) - .add(`CPT DQ ${LINEAR.toLocaleString()} push`, () => { + .add(`CPT DQ ${MILLION.toLocaleString()} push`, () => { const deque = new CDeque(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { deque.pushBack(i); } }) - .add(`CPT Q ${LINEAR.toLocaleString()} push`, () => { + .add(`CPT Q ${MILLION.toLocaleString()} push`, () => { const queue = new CQueue(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.push(i); } }) - .add(`CPT ST ${LINEAR.toLocaleString()} push`, () => { + .add(`CPT ST ${MILLION.toLocaleString()} push`, () => { const queue = new CStack(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.push(i); } }) - .add(`CPT ST ${LINEAR.toLocaleString()} push & pop`, () => { + .add(`CPT ST ${MILLION.toLocaleString()} push & pop`, () => { const queue = new CStack(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.push(i); } - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.pop(); } }); diff --git a/test/performance/data-structures/linked-list/doubly-linked-list.test.ts b/test/performance/data-structures/linked-list/doubly-linked-list.test.ts index 0b0999b..3dcfa51 100644 --- a/test/performance/data-structures/linked-list/doubly-linked-list.test.ts +++ b/test/performance/data-structures/linked-list/doubly-linked-list.test.ts @@ -5,61 +5,50 @@ import { magnitude } from '../../../utils'; import { isCompetitor } from '../../../config'; const suite = new Benchmark.Suite(); -const { LINEAR } = magnitude; +const { MILLION } = magnitude; -suite.add(`${LINEAR.toLocaleString()} push`, () => { +suite.add(`${MILLION.toLocaleString()} push`, () => { const list = new DoublyLinkedList(); - for (let i = 0; i < LINEAR; i++) { - list.push(i); - } + for (let i = 0; i < MILLION; i++) list.push(i); }); if (isCompetitor) { - suite.add(`CPT ${LINEAR.toLocaleString()} push`, () => { + suite.add(`CPT ${MILLION.toLocaleString()} push`, () => { const list = new CLinkedList(); - for (let i = 0; i < LINEAR; i++) { - list.pushBack(i); - } + for (let i = 0; i < MILLION; i++) list.pushBack(i); }); } -suite.add(`${LINEAR.toLocaleString()} unshift`, () => { +suite.add(`${MILLION.toLocaleString()} unshift`, () => { const list = new DoublyLinkedList(); - for (let i = 0; i < LINEAR; i++) { - list.unshift(i); - } + for (let i = 0; i < MILLION; i++) list.unshift(i); }); if (isCompetitor) { - suite.add(`CPT ${LINEAR.toLocaleString()} unshift`, () => { + suite.add(`CPT ${MILLION.toLocaleString()} unshift`, () => { const list = new CLinkedList(); - for (let i = 0; i < LINEAR; i++) { - list.pushFront(i); - } + for (let i = 0; i < MILLION; i++) list.pushFront(i); }); } suite - .add(`${LINEAR.toLocaleString()} unshift & shift`, () => { + .add(`${MILLION.toLocaleString()} unshift & shift`, () => { const list = new DoublyLinkedList(); - for (let i = 0; i < LINEAR; i++) { - list.unshift(i); - } - for (let i = 0; i < LINEAR; i++) { - list.shift(); - } + for (let i = 0; i < MILLION; i++) list.unshift(i); + + for (let i = 0; i < MILLION; i++) list.shift(); }) - .add(`${LINEAR.toLocaleString()} addBefore`, () => { + .add(`${MILLION.toLocaleString()} addBefore`, () => { const doublyList = new DoublyLinkedList(); let midNode: DoublyLinkedListNode | undefined; - const midIndex = Math.floor(LINEAR / 2); - for (let i = 0; i < LINEAR; i++) { + const midIndex = Math.floor(MILLION / 2); + for (let i = 0; i < MILLION; i++) { doublyList.push(i); if (i === midIndex) { midNode = doublyList.getNode(i); diff --git a/test/performance/data-structures/linked-list/singly-linked-list.test.ts b/test/performance/data-structures/linked-list/singly-linked-list.test.ts index db9f224..32518bf 100644 --- a/test/performance/data-structures/linked-list/singly-linked-list.test.ts +++ b/test/performance/data-structures/linked-list/singly-linked-list.test.ts @@ -9,24 +9,16 @@ suite .add(`${MILLION.toLocaleString()} push & shift`, () => { const list = new SinglyLinkedList(); - for (let i = 0; i < MILLION; i++) { - list.push(i); - } + for (let i = 0; i < MILLION; i++) list.push(i); - for (let i = 0; i < MILLION; i++) { - list.shift(); - } + for (let i = 0; i < MILLION; i++) list.shift(); }) .add(`${TEN_THOUSAND.toLocaleString()} push & pop`, () => { const list = new SinglyLinkedList(); - for (let i = 0; i < TEN_THOUSAND; i++) { - list.push(i); - } + for (let i = 0; i < TEN_THOUSAND; i++) list.push(i); - for (let i = 0; i < TEN_THOUSAND; i++) { - list.pop(); - } + for (let i = 0; i < TEN_THOUSAND; i++) list.pop(); }) .add(`${TEN_THOUSAND.toLocaleString()} addBefore`, () => { const singlyList = new SinglyLinkedList(); diff --git a/test/performance/data-structures/queue/deque.test.ts b/test/performance/data-structures/queue/deque.test.ts index 588ab41..41e8cd5 100644 --- a/test/performance/data-structures/queue/deque.test.ts +++ b/test/performance/data-structures/queue/deque.test.ts @@ -5,26 +5,26 @@ import { magnitude } from '../../../utils'; import { isCompetitor } from '../../../config'; export const suite = new Benchmark.Suite(); -const { LINEAR, HUNDRED_THOUSAND } = magnitude; +const { MILLION, HUNDRED_THOUSAND } = magnitude; -suite.add(`${LINEAR.toLocaleString()} push`, () => { +suite.add(`${MILLION.toLocaleString()} push`, () => { const deque = new Deque(); - for (let i = 0; i < LINEAR; i++) deque.push(i); + for (let i = 0; i < MILLION; i++) deque.push(i); }); if (isCompetitor) { - suite.add(`CPT ${LINEAR.toLocaleString()} push`, () => { + suite.add(`CPT ${MILLION.toLocaleString()} push`, () => { const _deque = new CDeque(); - for (let i = 0; i < LINEAR; i++) _deque.pushBack(i); + for (let i = 0; i < MILLION; i++) _deque.pushBack(i); }); } -suite.add(`${LINEAR.toLocaleString()} push & pop`, () => { +suite.add(`${MILLION.toLocaleString()} push & pop`, () => { const _deque = new Deque(); - for (let i = 0; i < LINEAR; i++) _deque.push(i); - for (let i = 0; i < LINEAR; i++) _deque.pop(); + for (let i = 0; i < MILLION; i++) _deque.push(i); + for (let i = 0; i < MILLION; i++) _deque.pop(); }) .add(`${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => { diff --git a/test/performance/data-structures/queue/queue.test.ts b/test/performance/data-structures/queue/queue.test.ts index c476fa8..5e8feba 100644 --- a/test/performance/data-structures/queue/queue.test.ts +++ b/test/performance/data-structures/queue/queue.test.ts @@ -5,20 +5,20 @@ import { magnitude } from '../../../utils'; import { isCompetitor } from '../../../config'; const suite = new Benchmark.Suite(); -const { LINEAR, HUNDRED_THOUSAND } = magnitude; +const { MILLION, HUNDRED_THOUSAND } = magnitude; -suite.add(`${LINEAR.toLocaleString()} push`, () => { +suite.add(`${MILLION.toLocaleString()} push`, () => { const queue = new Queue(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.push(i); } }); if (isCompetitor) { - suite.add(`CPT ${LINEAR.toLocaleString()} push`, () => { + suite.add(`CPT ${MILLION.toLocaleString()} push`, () => { const queue = new CQueue(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.push(i); } }); diff --git a/test/performance/data-structures/stack/stack.test.ts b/test/performance/data-structures/stack/stack.test.ts index 4731c21..186d6c8 100644 --- a/test/performance/data-structures/stack/stack.test.ts +++ b/test/performance/data-structures/stack/stack.test.ts @@ -5,42 +5,42 @@ import { magnitude } from '../../../utils'; import { isCompetitor } from '../../../config'; const suite = new Benchmark.Suite(); -const { LINEAR } = magnitude; +const { MILLION } = magnitude; -suite.add(`${LINEAR.toLocaleString()} push`, () => { +suite.add(`${MILLION.toLocaleString()} push`, () => { const stack = new Stack(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { stack.push(i); } }); if (isCompetitor) { - suite.add(`CPT ${LINEAR.toLocaleString()} push`, () => { + suite.add(`CPT ${MILLION.toLocaleString()} push`, () => { const queue = new CStack(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.push(i); } }); } -suite.add(`${LINEAR.toLocaleString()} push & pop`, () => { +suite.add(`${MILLION.toLocaleString()} push & pop`, () => { const queue = new Stack(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.push(i); } - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.pop(); } }); if (isCompetitor) { - suite.add(`CPT ${LINEAR.toLocaleString()} push & pop`, () => { + suite.add(`CPT ${MILLION.toLocaleString()} push & pop`, () => { const queue = new CStack(); - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.push(i); } - for (let i = 0; i < LINEAR; i++) { + for (let i = 0; i < MILLION; i++) { queue.pop(); } }); diff --git a/test/unit/data-structures/binary-tree/binary-tree.test.ts b/test/unit/data-structures/binary-tree/binary-tree.test.ts index 450fb14..39ff76d 100644 --- a/test/unit/data-structures/binary-tree/binary-tree.test.ts +++ b/test/unit/data-structures/binary-tree/binary-tree.test.ts @@ -639,4 +639,19 @@ describe('BinaryTree iterative methods test', () => { const values = binaryTree.values(); expect([...values]).toEqual(['b', 'a', 'c']); }); + + test('should iterative method return undefined when the node is null', () => { + const tree = new BinaryTree() + tree.addMany([-10, -10, -10, 9, 9, 20, null, null, 15, 7, 8, null, 2, null, 6, null, null, 8, 8, 8]); + const bfsResult = tree.bfs(undefined, undefined, undefined, true); + expect(bfsResult).toEqual([ + -10, 9, + 20, undefined, + undefined, 15, + 7, 8, + undefined, 2, + undefined, 6, + undefined, undefined + ]); + }) }); \ No newline at end of file diff --git a/test/unit/data-structures/graph/directed-graph.test.ts b/test/unit/data-structures/graph/directed-graph.test.ts index f0d5b1d..d84619d 100644 --- a/test/unit/data-structures/graph/directed-graph.test.ts +++ b/test/unit/data-structures/graph/directed-graph.test.ts @@ -635,7 +635,7 @@ describe('DirectedGraph iterative Methods', () => { expect(concatenated).toBe(vertexMap.join('')); }); - test('Removing an edge of a DirectedGraph should not delete additional edges', () => { + test('Removing an edge of a DirectedGraph should delete additional edges', () => { const dg = new DirectedGraph(); dg.addVertex('hello') dg.addVertex('hi') @@ -649,9 +649,22 @@ describe('DirectedGraph iterative Methods', () => { dg.deleteEdge('hello', 'hi') expect(dg.getEdge('hello', 'hi')).toBe(undefined) expect(dg.getEdge('hello', 'hey')).toBeInstanceOf(DirectedEdge) + expect(dg.incomingEdgesOf("Hi")).toEqual([]) }); - test('Removing a vertex from a UndirectedGraph should remove its edges', () => { + test('Removing a vertex of a DirectedGraph should delete additional edges', () => { + const graph = new DirectedGraph(); + + graph.addVertex("Hello"); + graph.addVertex("Hi"); + + graph.addEdge("Hello", "Hi"); + graph.deleteVertex("Hello"); + + expect(graph.incomingEdgesOf("Hi")).toEqual([]); + }) + + test('Removing a vertex from a DirectedGraph should remove its edges', () => { const dg = new DirectedGraph(); dg.addVertex('hello') dg.addVertex('world') diff --git a/test/unit/data-structures/graph/undirected-graph.test.ts b/test/unit/data-structures/graph/undirected-graph.test.ts index 1f93d18..cf00f36 100644 --- a/test/unit/data-structures/graph/undirected-graph.test.ts +++ b/test/unit/data-structures/graph/undirected-graph.test.ts @@ -190,6 +190,19 @@ describe('UndirectedGraph', () => { expect(dg.getEdge('hello', 'hey')).toBeInstanceOf(UndirectedEdge) }); + + test('Removing a vertex of a DirectedGraph should delete additional edges', () => { + const graph = new UndirectedGraph(); + + graph.addVertex("Hello"); + graph.addVertex("Hi"); + + graph.addEdge("Hello", "Hi"); + graph.deleteVertex("Hello"); + + expect(graph.edgesOf("Hi")).toEqual([]); + }) + test('Removing a vertex from a UndirectedGraph should remove its edges', () => { const dg = new UndirectedGraph(); dg.addVertex('hello') diff --git a/test/unit/data-structures/hash/hash-map.test.ts b/test/unit/data-structures/hash/hash-map.test.ts index 78e480c..5f4d862 100644 --- a/test/unit/data-structures/hash/hash-map.test.ts +++ b/test/unit/data-structures/hash/hash-map.test.ts @@ -554,4 +554,25 @@ describe('LinkedHashMap setMany, keys, values', () => { test('values', () => { expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]) }); + + test('entries', () => { + expect([...hm.entries()]).toEqual([[2, 2], [3, 3], [4, 4], [5, 5], [6, 6]]) + }); + + test('every', () => { + expect(hm.every(value => value > 4)).toBe(false) + }); + + test('some', () => { + expect(hm.some(value => value > 6)).toBe(false) + }); + + test('hasValue', () => { + expect(hm.hasValue(3)).toBe(true) + expect(hm.hasValue(7)).toBe(false) + }); + + test('print', () => { + hm.print(); + }); }); \ No newline at end of file diff --git a/test/unit/data-structures/linked-list/doubly-linked-list.test.ts b/test/unit/data-structures/linked-list/doubly-linked-list.test.ts index dd20da9..24c5207 100644 --- a/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +++ b/test/unit/data-structures/linked-list/doubly-linked-list.test.ts @@ -424,4 +424,31 @@ describe('iterable methods', () => { expect([...dl.map(element => element * 2)]).toEqual([2, 4, 6]); expect(dl.reduce((accumulator, element) => accumulator + element, 0)).toEqual(6); }); + + test('values', () => { + const dl = new DoublyLinkedList() + dl.push(1); + dl.push(2); + dl.push(3); + dl.delete(2); + dl.unshift(0); + dl.shift(); + dl.pop(); + dl.unshift(3); + expect([...dl.values()]).toEqual([3, 1]) + }) + + test('some', () => { + const dl = new DoublyLinkedList() + dl.push(1); + dl.push(2); + dl.push(3); + dl.delete(2); + dl.unshift(0); + dl.shift(); + dl.pop(); + dl.unshift(3); + expect(dl.some(value => value > 1)).toBe(true) + expect(dl.some(value => value > 100)).toBe(false) + }) }); \ No newline at end of file diff --git a/test/utils/big-o.ts b/test/utils/big-o.ts index bb30b01..b639463 100644 --- a/test/utils/big-o.ts +++ b/test/utils/big-o.ts @@ -2,16 +2,16 @@ import { AnyFunction } from '../types'; import { isDebugTest } from '../config'; const isDebug = isDebugTest; -const orderReducedBy = 1; // reduction of bigO's order compared to the baseline bigO +// const orderReducedBy = 1; // reduction of bigO's order compared to the baseline bigO export const magnitude = { - CONSTANT: Math.pow(10, 9), - LOG_N: Math.pow(10, 8 - orderReducedBy), - LINEAR: Math.pow(10, 7 - orderReducedBy), - N_LOG_N: Math.pow(10, 4 - orderReducedBy), - SQUARED: Math.pow(10, 3 - orderReducedBy), - CUBED: Math.pow(10, 2 - orderReducedBy), - FACTORIAL: 20 - orderReducedBy, + // CONSTANT: Math.pow(10, 9), + // LOG_N: Math.pow(10, 8 - orderReducedBy), + // LINEAR: Math.pow(10, 7 - orderReducedBy), + // N_LOG_N: Math.pow(10, 4 - orderReducedBy), + // SQUARED: Math.pow(10, 3 - orderReducedBy), + // CUBED: Math.pow(10, 2 - orderReducedBy), + // FACTORIAL: 20 - orderReducedBy, THOUSAND: 1000, TEN_THOUSAND: 10000, HUNDRED_THOUSAND: 100000, @@ -21,12 +21,12 @@ export const magnitude = { }; export const bigO = { - CONSTANT: magnitude.CONSTANT / 100000, - LOG_N: Math.log2(magnitude.LOG_N) / 1000, - LINEAR: magnitude.LINEAR / 1000, - N_LOG_N: (magnitude.N_LOG_N * Math.log2(magnitude.LOG_N)) / 1000, - SQUARED: Math.pow(magnitude.SQUARED, 2) / 1000, - CUBED: Math.pow(magnitude.SQUARED, 3) / 1000, + // CONSTANT: magnitude.CONSTANT / 100000, + // LOG_N: Math.log2(magnitude.LOG_N) / 1000, + // LINEAR: magnitude.LINEAR / 1000, + // N_LOG_N: (magnitude.N_LOG_N * Math.log2(magnitude.LOG_N)) / 1000, + // SQUARED: Math.pow(magnitude.SQUARED, 2) / 1000, + // CUBED: Math.pow(magnitude.SQUARED, 3) / 1000, FACTORIAL: 10000 };