diff --git a/README.md b/README.md
index dc413a5..150c78d 100644
--- a/README.md
+++ b/README.md
@@ -916,3 +916,32 @@ optimal approach to data structure design.
+## Benchmark
+
+
avl-tree
+
test name | time taken (ms) | executions per sec | executed times | sample mean (secs) | sample deviation |
---|
add 1000 randomly | 2.39 | 418.91 | 22 | 0.00 | 6.47e-5 |
delete 1000 randomly | 0.06 | 1.77e+4 | 917 | 5.66e-5 | 1.90e-6 |
addMany 1000 | 3.32 | 301.33 | 17 | 0.00 | 5.90e-4 |
get 1000 | 55.03 | 18.17 | 1 | 0.06 | 0.00 |
+
+
binary-tree
+
test name | time taken (ms) | executions per sec | executed times | sample mean (secs) | sample deviation |
---|
add 1000 | 66.49 | 15.04 | 3 | 0.07 | 0.00 |
delete 1000 | 24.04 | 41.60 | 1106 | 0.02 | 0.04 |
addMany 1000 | 9.05 | 110.44 | 6 | 0.01 | 2.88e-4 |
get 1000 | 32.12 | 31.13 | 2 | 0.03 | 6.75e-4 |
+
+
bst
+
test name | time taken (ms) | executions per sec | executed times | sample mean (secs) | sample deviation |
---|
add 1000 randomly | 2.27 | 440.62 | 23 | 0.00 | 1.42e-4 |
delete 1000 randomly | 0.05 | 2.19e+4 | 1174 | 4.57e-5 | 1.97e-6 |
addMany 1000 balanced | 2.93 | 341.38 | 19 | 0.00 | 1.13e-4 |
get 1000 | 62.85 | 15.91 | 1 | 0.06 | 0.01 |
+
+
heap
+
test name | time taken (ms) | executions per sec | executed times | sample mean (secs) | sample deviation |
---|
add & 1000 | 0.35 | 2878.39 | 149 | 3.47e-4 | 1.93e-5 |
fib add & pop 1000 | 3.98 | 251.35 | 14 | 0.00 | 1.32e-4 |
+
+
doubly-linked-list
+
test name | time taken (ms) | executions per sec | executed times | sample mean (secs) | sample deviation |
---|
unshift 1000000 | 193.19 | 5.18 | 1 | 0.19 | 0.04 |
unshift & shift 1000000 | 170.35 | 5.87 | 1 | 0.17 | 0.03 |
insertBefore 1000 | 0.03 | 3.43e+4 | 1888 | 2.91e-5 | 6.03e-6 |
+
+
singly-linked-list
+
test name | time taken (ms) | executions per sec | executed times | sample mean (secs) | sample deviation |
---|
push & pop 1000 | 1.79 | 560.08 | 29 | 0.00 | 7.70e-5 |
insertBefore 1000 | 2.31 | 433.45 | 22 | 0.00 | 5.52e-5 |
+
+
max-priority-queue
+
test name | time taken (ms) | executions per sec | executed times | sample mean (secs) | sample deviation |
---|
refill & poll 1000000 | 1859.40 | 0.54 | 1 | 1.86 | 0.03 |
+
+
deque
+
test name | time taken (ms) | executions per sec | executed times | sample mean (secs) | sample deviation |
---|
push 1000000 | 215.00 | 4.65 | 1 | 0.22 | 0.01 |
shift 1000000 | 25.04 | 39.94 | 3 | 0.03 | 0.00 |
+
+
queue
+
test name | time taken (ms) | executions per sec | executed times | sample mean (secs) | sample deviation |
---|
push 1000000 | 41.81 | 23.92 | 2 | 0.04 | 0.00 |
push & shift 1000000 | 79.17 | 12.63 | 1 | 0.08 | 8.70e-4 |
+
\ No newline at end of file
diff --git a/package.json b/package.json
index 9ef4802..7705366 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "data-structure-typed",
- "version": "1.41.3",
+ "version": "1.41.4",
"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",
@@ -31,7 +31,7 @@
"reformat": "npm run reformat:src && npm run reformat:test",
"update:subs": "npm i avl-tree-typed binary-tree-typed bst-typed heap-typed --save-dev",
"install:all-subs": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed queue-typed --save-dev",
- "test": "jest",
+ "test": "jest --runInBand",
"test:integration": "npm run update:subs && jest --config jest.integration.config.js",
"benchmark": "ts-node test/performance/reportor.ts",
"check:deps": "dependency-cruiser src",
diff --git a/src/data-structures/binary-tree/binary-tree.ts b/src/data-structures/binary-tree/binary-tree.ts
index 1feb431..0372053 100644
--- a/src/data-structures/binary-tree/binary-tree.ts
+++ b/src/data-structures/binary-tree/binary-tree.ts
@@ -179,7 +179,10 @@ export class BinaryTree = BinaryTreeNode
while (queue.size > 0) {
const cur = queue.shift();
if (cur) {
- if (newNode && cur.key === newNode.key) return;
+ if (newNode && cur.key === newNode.key) {
+ cur.value = newNode.value;
+ return;
+ }
const inserted = this._addTo(newNode, cur);
if (inserted !== undefined) return inserted;
if (cur.left) queue.push(cur.left);
@@ -201,16 +204,16 @@ export class BinaryTree = BinaryTreeNode
return;
}
- const key = typeof keyOrNode === 'number' ? keyOrNode : keyOrNode ? keyOrNode.key : undefined;
- const existNode = key !== undefined ? this.getNode(key, (node: N) => node.key) : undefined;
+ // const key = typeof keyOrNode === 'number' ? keyOrNode : keyOrNode ? keyOrNode.key : undefined;
+ // const existNode = key !== undefined ? this.getNode(key, (node: N) => node.key) : undefined;
if (this.root) {
- if (existNode) {
- existNode.value = value;
- inserted = existNode;
- } else {
- inserted = _bfs(this.root, needInsert);
- }
+ // if (existNode) {
+ // existNode.value = value;
+ // inserted = existNode;
+ // } else {
+ inserted = _bfs(this.root, needInsert);
+ // }
} else {
this._setRoot(needInsert);
if (needInsert !== null) {
diff --git a/test/config.js b/test/config.js
deleted file mode 100644
index 1b96349..0000000
--- a/test/config.js
+++ /dev/null
@@ -1,4 +0,0 @@
-'use strict';
-Object.defineProperty(exports, '__esModule', {value: true});
-exports.isDebugTest = void 0;
-exports.isDebugTest = false;
diff --git a/test/performance/data-structures/binary-tree/avl-tree.test.ts b/test/performance/data-structures/binary-tree/avl-tree.test.ts
index e69de29..0de0d75 100644
--- a/test/performance/data-structures/binary-tree/avl-tree.test.ts
+++ b/test/performance/data-structures/binary-tree/avl-tree.test.ts
@@ -0,0 +1,24 @@
+import {AVLTree} from '../../../../src';
+import * as Benchmark from 'benchmark';
+import {magnitude, randomInt, randomIntArray} from '../../../utils';
+
+const suite = new Benchmark.Suite();
+const avl = new AVLTree();
+const {N_LOG_N} = magnitude;
+
+suite
+ .add(`add ${N_LOG_N} randomly`, () => {
+ for (let i = 0; i < N_LOG_N; i++) avl.add(randomInt(0, N_LOG_N));
+ })
+ .add(`delete ${N_LOG_N} randomly`, () => {
+ for (let i = 0; i < N_LOG_N; i++) avl.delete(randomInt(0, N_LOG_N));
+ })
+ .add(`addMany ${N_LOG_N}`, () => {
+ const arr = randomIntArray(N_LOG_N);
+ avl.addMany(arr);
+ })
+ .add(`get ${N_LOG_N}`, () => {
+ for (let i = 0; i < N_LOG_N; i++) avl.get(randomInt(-N_LOG_N, N_LOG_N));
+ });
+
+export {suite};
diff --git a/test/performance/data-structures/binary-tree/binary-tree.test.ts b/test/performance/data-structures/binary-tree/binary-tree.test.ts
index 8d7e0b5..6217aef 100644
--- a/test/performance/data-structures/binary-tree/binary-tree.test.ts
+++ b/test/performance/data-structures/binary-tree/binary-tree.test.ts
@@ -1,18 +1,25 @@
import {BinaryTree} from '../../../../src';
-
import * as Benchmark from 'benchmark';
+import {magnitude, randomInt, randomIntArray} from '../../../utils';
-export const suite = new Benchmark.Suite();
-const bt = new BinaryTree();
+const suite = new Benchmark.Suite();
+const biTree = new BinaryTree();
+const {N_LOG_N} = magnitude;
suite
- .add('add 1000', () => {
- for (let i = 0; i < 1000; i++) {
- bt.add(i);
- }
+ .add(`add ${N_LOG_N}`, () => {
+ for (let i = 0; i < N_LOG_N; i++) biTree.add(randomInt(-N_LOG_N, N_LOG_N));
})
- .add('add & delete 1000', () => {
- for (let i = 0; i < 1000; i++) {
- bt.delete(i);
- }
+ .add(`delete ${N_LOG_N}`, () => {
+ for (let i = 0; i < N_LOG_N; i++) biTree.delete(randomInt(-N_LOG_N, N_LOG_N));
+ })
+ .add(`addMany ${N_LOG_N}`, () => {
+ biTree.clear();
+ const arr = randomIntArray(N_LOG_N);
+ biTree.addMany(arr);
+ })
+ .add(`get ${N_LOG_N}`, () => {
+ for (let i = 0; i < N_LOG_N; i++) biTree.get(randomInt(-N_LOG_N, N_LOG_N));
});
+
+export {suite};
diff --git a/test/performance/data-structures/binary-tree/bst.test.ts b/test/performance/data-structures/binary-tree/bst.test.ts
index f16440d..5c48beb 100644
--- a/test/performance/data-structures/binary-tree/bst.test.ts
+++ b/test/performance/data-structures/binary-tree/bst.test.ts
@@ -1,18 +1,24 @@
import {BST} from '../../../../src';
-
import * as Benchmark from 'benchmark';
+import {magnitude, randomInt, randomIntArray} from '../../../utils';
-export const suite = new Benchmark.Suite();
-const bt = new BST();
+const suite = new Benchmark.Suite();
+const bst = new BST();
+const {N_LOG_N} = magnitude;
suite
- .add('add 1000', () => {
- for (let i = 0; i < 1000; i++) {
- bt.add(i);
- }
+ .add(`add ${N_LOG_N} randomly`, () => {
+ for (let i = 0; i < N_LOG_N; i++) bst.add(randomInt(0, N_LOG_N));
})
- .add('add & delete 1000', () => {
- for (let i = 0; i < 1000; i++) {
- bt.delete(i);
- }
+ .add(`delete ${N_LOG_N} randomly`, () => {
+ for (let i = 0; i < N_LOG_N; i++) bst.delete(randomInt(0, N_LOG_N));
+ })
+ .add(`addMany ${N_LOG_N} balanced`, () => {
+ const arr = randomIntArray(N_LOG_N);
+ bst.addMany(arr);
+ })
+ .add(`get ${N_LOG_N}`, () => {
+ for (let i = 0; i < N_LOG_N; i++) bst.get(randomInt(-N_LOG_N, N_LOG_N));
});
+
+export {suite};
diff --git a/test/performance/data-structures/heap/heap.test.ts b/test/performance/data-structures/heap/heap.test.ts
index e69de29..0775c71 100644
--- a/test/performance/data-structures/heap/heap.test.ts
+++ b/test/performance/data-structures/heap/heap.test.ts
@@ -0,0 +1,30 @@
+import {FibonacciHeap, Heap} from '../../../../src';
+import * as Benchmark from 'benchmark';
+import {magnitude} from '../../../utils';
+
+const suite = new Benchmark.Suite();
+const {N_LOG_N} = magnitude;
+
+suite
+ .add(`add & ${N_LOG_N}`, () => {
+ const heap = new Heap({comparator: (a, b) => b - a});
+
+ for (let i = 0; i < N_LOG_N; i++) {
+ heap.add(i);
+ }
+
+ for (let i = 0; i < N_LOG_N; i++) {
+ heap.pop();
+ }
+ })
+ .add(`fib add & pop ${N_LOG_N}`, () => {
+ const fbHeap = new FibonacciHeap();
+ for (let i = 1; i <= N_LOG_N; i++) {
+ fbHeap.push(i);
+ }
+ for (let i = 1; i <= N_LOG_N; i++) {
+ fbHeap.pop();
+ }
+ });
+
+export {suite};
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 e69de29..7847c1b 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
@@ -0,0 +1,40 @@
+import {DoublyLinkedList, DoublyLinkedListNode} from '../../../../src';
+import * as Benchmark from 'benchmark';
+import {magnitude} from '../../../utils';
+
+const suite = new Benchmark.Suite();
+const {LINEAR, N_LOG_N} = magnitude;
+
+suite
+ .add(`unshift ${LINEAR}`, () => {
+ const list = new DoublyLinkedList();
+
+ for (let i = 0; i < LINEAR; i++) {
+ list.unshift(i);
+ }
+ })
+ .add(`unshift & shift ${LINEAR}`, () => {
+ const list = new DoublyLinkedList();
+
+ for (let i = 0; i < LINEAR; i++) {
+ list.unshift(i);
+ }
+ for (let i = 0; i < LINEAR; i++) {
+ list.shift();
+ }
+ })
+ .add(`insertBefore ${N_LOG_N}`, () => {
+ const doublyList = new DoublyLinkedList();
+ let midNode: DoublyLinkedListNode | null = null;
+ const midIndex = Math.floor(N_LOG_N / 2);
+ for (let i = 0; i < N_LOG_N; i++) {
+ doublyList.push(i);
+ if (i === midIndex) {
+ midNode = doublyList.getNode(i);
+ } else if (i > midIndex && midNode) {
+ doublyList.insertBefore(midNode, i);
+ }
+ }
+ });
+
+export {suite};
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 e69de29..a0c491b 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
@@ -0,0 +1,34 @@
+import {SinglyLinkedList, SinglyLinkedListNode} from '../../../../src';
+import * as Benchmark from 'benchmark';
+import {magnitude} from '../../../utils';
+
+const suite = new Benchmark.Suite();
+const {N_LOG_N} = magnitude;
+
+suite
+ .add(`push & pop ${N_LOG_N}`, () => {
+ const list = new SinglyLinkedList();
+
+ for (let i = 0; i < N_LOG_N; i++) {
+ list.push(i);
+ }
+
+ for (let i = 0; i < N_LOG_N; i++) {
+ list.pop();
+ }
+ })
+ .add(`insertBefore ${N_LOG_N}`, () => {
+ const singlyList = new SinglyLinkedList();
+ let midSinglyNode: SinglyLinkedListNode | null = null;
+ const midIndex = Math.floor(N_LOG_N / 2);
+ for (let i = 0; i < N_LOG_N; i++) {
+ singlyList.push(i);
+ if (i === midIndex) {
+ midSinglyNode = singlyList.getNode(i);
+ } else if (i > midIndex && midSinglyNode) {
+ singlyList.insertBefore(midSinglyNode.value, i);
+ }
+ }
+ });
+
+export {suite};
diff --git a/test/performance/data-structures/priority-queue/max-priority-queue.test.ts b/test/performance/data-structures/priority-queue/max-priority-queue.test.ts
index e69de29..b143987 100644
--- a/test/performance/data-structures/priority-queue/max-priority-queue.test.ts
+++ b/test/performance/data-structures/priority-queue/max-priority-queue.test.ts
@@ -0,0 +1,19 @@
+import {MaxPriorityQueue} from '../../../../src';
+import * as Benchmark from 'benchmark';
+import {magnitude} from '../../../utils';
+
+const suite = new Benchmark.Suite();
+const {LINEAR} = magnitude;
+
+suite.add(`refill & poll ${LINEAR}`, () => {
+ const nodes = Array.from(
+ new Set(Array.from(new Array(LINEAR), () => Math.floor(Math.random() * LINEAR * 100)))
+ );
+ const maxPQ = new MaxPriorityQueue();
+ maxPQ.refill(nodes);
+ while (maxPQ.size > 0) {
+ maxPQ.poll();
+ }
+});
+
+export {suite};
diff --git a/test/performance/data-structures/queue/deque.test.ts b/test/performance/data-structures/queue/deque.test.ts
index bf76aec..6ea4266 100644
--- a/test/performance/data-structures/queue/deque.test.ts
+++ b/test/performance/data-structures/queue/deque.test.ts
@@ -1,18 +1,20 @@
import {Deque} from '../../../../src';
import * as Benchmark from 'benchmark';
+import {magnitude} from '../../../utils';
export const suite = new Benchmark.Suite();
+const {LINEAR} = magnitude;
suite
- .add('push', () => {
+ .add(`push ${LINEAR}`, () => {
const deque = new Deque();
- for (let i = 0; i < 10; i++) {
+ for (let i = 0; i < LINEAR; i++) {
deque.push(i);
}
})
- .add('shift', () => {
+ .add(`shift ${LINEAR}`, () => {
const deque = new Deque();
- for (let i = 0; i < 10; i++) {
+ for (let i = 0; i < LINEAR; i++) {
deque.push(i);
deque.shift();
}
diff --git a/test/performance/data-structures/queue/queue.test.ts b/test/performance/data-structures/queue/queue.test.ts
index 24d21c0..f256e0b 100644
--- a/test/performance/data-structures/queue/queue.test.ts
+++ b/test/performance/data-structures/queue/queue.test.ts
@@ -1,20 +1,25 @@
import {Queue} from '../../../../src';
-
import * as Benchmark from 'benchmark';
+import {magnitude} from '../../../utils';
-export const suite = new Benchmark.Suite();
+const suite = new Benchmark.Suite();
+const {LINEAR} = magnitude;
suite
- .add('push 1000000', () => {
+ .add(`push ${LINEAR}`, () => {
const queue = new Queue();
- for (let i = 0; i < 1000000; i++) {
+
+ for (let i = 0; i < LINEAR; i++) {
queue.push(i);
}
})
- .add('push & shift 1000000', () => {
+ .add(`push & shift ${LINEAR}`, () => {
const queue = new Queue();
- for (let i = 0; i < 1000000; i++) {
+
+ for (let i = 0; i < LINEAR; i++) {
queue.push(i);
queue.shift();
}
});
+
+export {suite};
diff --git a/test/performance/reportor.ts b/test/performance/reportor.ts
index 6f0841a..2bd0ab5 100644
--- a/test/performance/reportor.ts
+++ b/test/performance/reportor.ts
@@ -2,7 +2,7 @@ import * as Benchmark from 'benchmark';
import * as path from 'path';
import * as fs from 'fs';
import * as fastGlob from 'fast-glob';
-import {numberFix, render, Color} from './utils';
+import {Color, numberFix, render} from '../utils';
import {PerformanceTest} from './types';
const reportDistPath = 'benchmark';
@@ -15,7 +15,7 @@ let testFileCount = 0,
completedCount = 0;
const performanceTests: PerformanceTest[] = [];
-const {GREEN, BOLD, END} = Color;
+const {GREEN, BOLD, RED, END, YELLOW, CYAN, BG_YELLOW} = Color;
testFiles.forEach((file: string) => {
testFileCount++;
@@ -37,6 +37,17 @@ const composeReport = () => {
performance of data-structure-typed