data-structure-typed 1.36.9 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +2 -1
  2. package/dist/data-structures/binary-tree/binary-tree.d.ts +1 -11
  3. package/dist/data-structures/binary-tree/binary-tree.js +8 -57
  4. package/dist/data-structures/binary-tree/binary-tree.js.map +1 -1
  5. package/dist/data-structures/binary-tree/bst.d.ts +6 -20
  6. package/dist/data-structures/binary-tree/bst.js +22 -122
  7. package/dist/data-structures/binary-tree/bst.js.map +1 -1
  8. package/dist/data-structures/binary-tree/tree-multiset.d.ts +1 -55
  9. package/dist/data-structures/binary-tree/tree-multiset.js +3 -240
  10. package/dist/data-structures/binary-tree/tree-multiset.js.map +1 -1
  11. package/dist/data-structures/graph/abstract-graph.js +4 -3
  12. package/dist/data-structures/graph/abstract-graph.js.map +1 -1
  13. package/lib/data-structures/binary-tree/binary-tree.d.ts +1 -11
  14. package/lib/data-structures/binary-tree/binary-tree.js +8 -57
  15. package/lib/data-structures/binary-tree/bst.d.ts +6 -20
  16. package/lib/data-structures/binary-tree/bst.js +22 -122
  17. package/lib/data-structures/binary-tree/tree-multiset.d.ts +1 -55
  18. package/lib/data-structures/binary-tree/tree-multiset.js +3 -240
  19. package/lib/data-structures/graph/abstract-graph.js +4 -3
  20. package/package.json +9 -7
  21. package/src/data-structures/binary-tree/binary-tree.ts +8 -62
  22. package/src/data-structures/binary-tree/bst.ts +22 -106
  23. package/src/data-structures/binary-tree/tree-multiset.ts +3 -231
  24. package/src/data-structures/graph/abstract-graph.ts +4 -3
  25. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +5 -3
  26. package/test/unit/data-structures/binary-tree/bst.test.ts +44 -7
  27. package/test/unit/data-structures/binary-tree/overall.test.ts +1 -1
  28. package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +39 -9
  29. package/test/unit/data-structures/queue/deque.test.ts +17 -0
  30. package/test/unit/data-structures/queue/queue.test.ts +42 -0
  31. package/test/utils/big-o.ts +5 -4
  32. package/umd/bundle.min.js +1 -1
  33. package/umd/bundle.min.js.map +1 -1
@@ -9,6 +9,7 @@ import type {BinaryTreeNodeKey, TreeMultisetNodeNested, TreeMultisetOptions} fro
9
9
  import {BinaryTreeDeletedResult, CP, DFSOrderPattern, FamilyPosition, LoopType} from '../../types';
10
10
  import {IBinaryTree} from '../../interfaces';
11
11
  import {AVLTree, AVLTreeNode} from './avl-tree';
12
+ import {Queue} from '../queue';
12
13
 
13
14
  export class TreeMultisetNode<
14
15
  V = any,
@@ -349,121 +350,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
349
350
  return bstDeletedResult;
350
351
  }
351
352
 
352
- /**
353
- * The function `getSubTreeCount` calculates the number of nodes and the sum of their counts in a subtree, using either
354
- * recursive or iterative traversal.
355
- * @param {N | null | undefined} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree in a
356
- * binary tree.
357
- * @returns The function `getSubTreeCount` returns an array `[number, number]`.
358
- */
359
- getSubTreeCount(subTreeRoot: N | null | undefined) {
360
- const res: [number, number] = [0, 0];
361
- if (!subTreeRoot) return res;
362
-
363
- if (this.loopType === LoopType.RECURSIVE) {
364
- const _traverse = (cur: N) => {
365
- res[0]++;
366
- res[1] += cur.count;
367
- cur.left && _traverse(cur.left);
368
- cur.right && _traverse(cur.right);
369
- };
370
-
371
- _traverse(subTreeRoot);
372
- return res;
373
- } else {
374
- const stack: N[] = [subTreeRoot];
375
-
376
- while (stack.length > 0) {
377
- const cur = stack.pop()!;
378
- res[0]++;
379
- res[1] += cur.count;
380
- cur.right && stack.push(cur.right);
381
- cur.left && stack.push(cur.left);
382
- }
383
-
384
- return res;
385
- }
386
- }
387
-
388
- /**
389
- * The function `subTreeSumCount` calculates the sum of the `count` property of each node in a subtree, either
390
- * recursively or iteratively.
391
- * @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree
392
- * in a binary tree. It can be either a `BinaryTreeNodeKey` (a unique identifier for a node in the binary tree) or
393
- * `null` if the subtree is empty.
394
- * @returns the sum of the count values of all nodes in the subtree rooted at `subTreeRoot`.
395
- */
396
- subTreeSumCount(subTreeRoot: N | BinaryTreeNodeKey | null): number {
397
- if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
398
-
399
- if (!subTreeRoot) return 0;
400
-
401
- let sum = 0;
402
-
403
- if (this.loopType === LoopType.RECURSIVE) {
404
- const _traverse = (cur: N): void => {
405
- sum += cur.count;
406
- cur.left && _traverse(cur.left);
407
- cur.right && _traverse(cur.right);
408
- };
409
-
410
- _traverse(subTreeRoot);
411
- } else {
412
- const stack: N[] = [subTreeRoot];
413
-
414
- while (stack.length > 0) {
415
- const cur = stack.pop()!;
416
- sum += cur.count;
417
- cur.right && stack.push(cur.right);
418
- cur.left && stack.push(cur.left);
419
- }
420
- }
421
-
422
- return sum;
423
- }
424
-
425
- /**
426
- * The function `subTreeAddCount` recursively or iteratively traverses a binary tree and adds a given delta value to
427
- * the `count` property of each node.
428
- * @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree
429
- * in a binary tree. It can be either a `BinaryTreeNodeKey` (a unique identifier for a node in the binary tree), a
430
- * `BinaryTreeNode` object, or `null` if the subtree is empty.
431
- * @param {number} delta - The delta parameter is a number that represents the amount by which the count of each node
432
- * in the subtree should be increased or decreased.
433
- * @returns a boolean value.
434
- */
435
- subTreeAddCount(subTreeRoot: N | BinaryTreeNodeKey | null, delta: number): boolean {
436
- if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
437
-
438
- if (!subTreeRoot) return false;
439
-
440
- const _addByProperty = (cur: N) => {
441
- cur.count += delta;
442
- this._setCount(this.count + delta);
443
- };
444
-
445
- if (this.loopType === LoopType.RECURSIVE) {
446
- const _traverse = (cur: N) => {
447
- _addByProperty(cur);
448
- cur.left && _traverse(cur.left);
449
- cur.right && _traverse(cur.right);
450
- };
451
-
452
- _traverse(subTreeRoot);
453
- } else {
454
- const stack: N[] = [subTreeRoot];
455
-
456
- while (stack.length > 0) {
457
- const cur = stack.pop()!;
458
-
459
- _addByProperty(cur);
460
- cur.right && stack.push(cur.right);
461
- cur.left && stack.push(cur.left);
462
- }
463
- }
464
- return true;
465
- }
466
-
467
353
  /**
468
354
  * The function `getNodesByCount` returns an array of nodes that have a specific count property, either recursively or
469
355
  * using a queue.
@@ -492,8 +378,8 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
492
378
 
493
379
  _traverse(this.root);
494
380
  } else {
495
- const queue: N[] = [this.root];
496
- while (queue.length > 0) {
381
+ const queue = new Queue<N>([this.root]);
382
+ while (queue.size > 0) {
497
383
  const cur = queue.shift();
498
384
  if (cur) {
499
385
  if (cur.count === nodeProperty) {
@@ -545,120 +431,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
545
431
  return nodes.map(node => node.count);
546
432
  }
547
433
 
548
- /**
549
- * The function dfsCountIterative performs an iterative depth-first search and returns an array of node counts based on
550
- * the specified traversal pattern.
551
- * @param {'in' | 'pre' | 'post'} [pattern] - The pattern parameter is a string that specifies the traversal order for
552
- * the Depth-First Search (dfs) algorithm. It can have three possible values: 'in', 'pre', or 'post'.
553
- * @param loopType - The loopType parameter is a string that specifies the type of loop to use when traversing the
554
- * @returns The dfsCountIterative function returns an array of numbers, which represents the count property of each node
555
- * in the dfs traversal.
556
- */
557
- dfsCount(pattern: DFSOrderPattern = 'in', loopType: LoopType = LoopType.ITERATIVE): number[] {
558
- const nodes = super.dfs(pattern, 'node', loopType);
559
- return nodes.map(node => node.count);
560
- }
561
-
562
- /**
563
- * The `lesserSumCount` function calculates the sum of the counts of all nodes in a binary tree that have a lesser
564
- * value than a given node.
565
- * @param {N | BinaryTreeNodeKey | null} beginNode - The `beginNode` parameter can be one of the following:
566
- * @returns the sum of the counts of nodes in the binary tree that have a lesser value than the given beginNode.
567
- */
568
- lesserSumCount(beginNode: N | BinaryTreeNodeKey | null): number {
569
- if (typeof beginNode === 'number') beginNode = this.get(beginNode, 'key');
570
- if (!beginNode) return 0;
571
- if (!this.root) return 0;
572
- const key = beginNode.key;
573
-
574
- let sum = 0;
575
-
576
- if (this.loopType === LoopType.RECURSIVE) {
577
- const _traverse = (cur: N): void => {
578
- const compared = this._compare(cur.key, key);
579
- if (compared === CP.eq) {
580
- if (cur.right) sum += this.subTreeSumCount(cur.right);
581
- return;
582
- } else if (compared === CP.lt) {
583
- if (cur.left) sum += this.subTreeSumCount(cur.left);
584
- sum += cur.count;
585
- if (cur.right) _traverse(cur.right);
586
- else return;
587
- } else {
588
- if (cur.left) _traverse(cur.left);
589
- else return;
590
- }
591
- };
592
-
593
- _traverse(this.root);
594
- } else {
595
- const queue: N[] = [this.root];
596
- while (queue.length > 0) {
597
- const cur = queue.shift();
598
- if (cur) {
599
- const compared = this._compare(cur.key, key);
600
- if (compared === CP.eq) {
601
- if (cur.right) sum += this.subTreeSumCount(cur.right);
602
- return sum;
603
- } else if (compared === CP.lt) {
604
- // todo maybe a bug
605
- if (cur.left) sum += this.subTreeSumCount(cur.left);
606
- sum += cur.count;
607
- if (cur.right) queue.push(cur.right);
608
- else return sum;
609
- } else {
610
- if (cur.left) queue.push(cur.left);
611
- else return sum;
612
- }
613
- }
614
- }
615
- }
616
-
617
- return sum;
618
- }
619
-
620
- /**
621
- * The function `allGreaterNodesAddCount` updates the count property of all nodes in a binary tree that have an ID
622
- * greater than a given ID by a specified delta value.
623
- * @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be one of the following:
624
- * @param {number} delta - The `delta` parameter is a number that represents the amount by which the `count` property
625
- * of each node should be increased.
626
- * @returns a boolean value.
627
- */
628
- allGreaterNodesAddCount(node: N | BinaryTreeNodeKey | null, delta: number): boolean {
629
- if (typeof node === 'number') node = this.get(node, 'key');
630
- if (!node) return false;
631
- const key = node.key;
632
- if (!this.root) return false;
633
-
634
- if (this.loopType === LoopType.RECURSIVE) {
635
- const _traverse = (cur: N) => {
636
- const compared = this._compare(cur.key, key);
637
- if (compared === CP.gt) cur.count += delta;
638
-
639
- if (!cur.left && !cur.right) return;
640
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) _traverse(cur.left);
641
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) _traverse(cur.right);
642
- };
643
-
644
- _traverse(this.root);
645
- return true;
646
- } else {
647
- const queue: N[] = [this.root];
648
- while (queue.length > 0) {
649
- const cur = queue.shift();
650
- if (cur) {
651
- const compared = this._compare(cur.key, key);
652
- if (compared === CP.gt) cur.count += delta;
653
-
654
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) queue.push(cur.left);
655
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) queue.push(cur.right);
656
- }
657
- }
658
- return true;
659
- }
660
- }
661
-
662
434
  /**
663
435
  * The clear() function clears the data and sets the count to 0.
664
436
  */
@@ -9,6 +9,7 @@ import {arrayRemove, uuidV4} from '../../utils';
9
9
  import {PriorityQueue} from '../priority-queue';
10
10
  import type {DijkstraResult, VertexKey} from '../../types';
11
11
  import {IGraph} from '../../interfaces';
12
+ import {Queue} from '../queue';
12
13
 
13
14
  export abstract class AbstractVertex<V = any> {
14
15
  /**
@@ -342,11 +343,11 @@ export abstract class AbstractGraph<
342
343
  }
343
344
 
344
345
  const visited: Map<V, boolean> = new Map();
345
- const queue: V[] = [vertex1];
346
+ const queue = new Queue<V>([vertex1]);
346
347
  visited.set(vertex1, true);
347
348
  let cost = 0;
348
- while (queue.length > 0) {
349
- for (let i = 0; i < queue.length; i++) {
349
+ while (queue.size > 0) {
350
+ for (let i = 0; i < queue.size; i++) {
350
351
  const cur = queue.shift();
351
352
  if (cur === vertex2) {
352
353
  return cost;
@@ -1,4 +1,4 @@
1
- import {AVLTree} from '../../../../src';
1
+ import {AVLTree, CP} from '../../../../src';
2
2
 
3
3
  describe('AVL Tree Test', () => {
4
4
  it('should perform various operations on a AVL Tree', () => {
@@ -22,10 +22,12 @@ describe('AVL Tree Test', () => {
22
22
  const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
23
23
  expect(getMinNodeBySpecificNode?.key).toBe(12);
24
24
 
25
- const subTreeSum = node15 && tree.subTreeSum(node15);
25
+ let subTreeSum = 0;
26
+ node15 && tree.subTreeForeach(node15, node => (subTreeSum += node.key));
26
27
  expect(subTreeSum).toBe(70);
27
28
 
28
- const lesserSum = tree.lesserSum(10);
29
+ let lesserSum = 0;
30
+ tree.lesserOrGreaterForeach(10, CP.lt, node => (lesserSum += node.key));
29
31
  expect(lesserSum).toBe(45);
30
32
 
31
33
  // node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
@@ -1,4 +1,6 @@
1
- import {BST, BSTNode} from '../../../../src';
1
+ import {BST, BSTNode, CP} from '../../../../src';
2
+
3
+ const isDebug = false;
2
4
 
3
5
  describe('BST operations test', () => {
4
6
  it('should perform various operations on a Binary Search Tree with numeric values', () => {
@@ -7,7 +9,7 @@ describe('BST operations test', () => {
7
9
  bst.add(11, 11);
8
10
  bst.add(3, 3);
9
11
  const idsAndValues = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
10
- bst.addMany(idsAndValues, idsAndValues);
12
+ bst.addMany(idsAndValues, idsAndValues, false);
11
13
  expect(bst.root).toBeInstanceOf(BSTNode);
12
14
 
13
15
  if (bst.root) expect(bst.root.key).toBe(11);
@@ -33,10 +35,12 @@ describe('BST operations test', () => {
33
35
  const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
34
36
  expect(minNodeBySpecificNode?.key).toBe(12);
35
37
 
36
- const subTreeSum = node15 && bst.subTreeSum(15);
38
+ let subTreeSum = 0;
39
+ node15 && bst.subTreeForeach(15, node => (subTreeSum += node.key));
37
40
  expect(subTreeSum).toBe(70);
38
41
 
39
- const lesserSum = bst.lesserSum(10);
42
+ let lesserSum = 0;
43
+ bst.lesserOrGreaterForeach(10, CP.lt, node => (lesserSum += node.key));
40
44
  expect(lesserSum).toBe(45);
41
45
 
42
46
  expect(node15).toBeInstanceOf(BSTNode);
@@ -204,7 +208,8 @@ describe('BST operations test', () => {
204
208
 
205
209
  objBST.addMany(
206
210
  values.map(item => item.key),
207
- values
211
+ values,
212
+ false
208
213
  );
209
214
 
210
215
  expect(objBST.root).toBeInstanceOf(BSTNode);
@@ -231,10 +236,12 @@ describe('BST operations test', () => {
231
236
  const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
232
237
  expect(minNodeBySpecificNode?.key).toBe(12);
233
238
 
234
- const subTreeSum = node15 && objBST.subTreeSum(node15);
239
+ let subTreeSum = 0;
240
+ node15 && objBST.subTreeForeach(node15, node => (subTreeSum += node.key));
235
241
  expect(subTreeSum).toBe(70);
236
242
 
237
- const lesserSum = objBST.lesserSum(10);
243
+ let lesserSum = 0;
244
+ objBST.lesserOrGreaterForeach(10, CP.lt, node => (lesserSum += node.key));
238
245
  expect(lesserSum).toBe(45);
239
246
 
240
247
  expect(node15).toBeInstanceOf(BSTNode);
@@ -378,3 +385,33 @@ describe('BST operations test', () => {
378
385
  expect(bfsNodes[2].key).toBe(16);
379
386
  });
380
387
  });
388
+
389
+ describe('BST Performance test', function () {
390
+ const bst = new BST<BSTNode<number>>();
391
+ const inputSize = 10000; // Adjust input sizes as needed
392
+
393
+ beforeEach(() => {
394
+ bst.clear();
395
+ });
396
+
397
+ it(`Observe the time consumption of BST.dfs be good`, function () {
398
+ const startDFS = performance.now();
399
+ const dfs = bst.dfs();
400
+ isDebug && console.log('---bfs', performance.now() - startDFS, dfs.length);
401
+ });
402
+
403
+ it('Should the time consumption of lesserOrGreaterForeach fitting O(n log n)', function () {
404
+ const nodes: number[] = [];
405
+ for (let i = 0; i < inputSize; i++) {
406
+ nodes.push(i);
407
+ }
408
+ const start = performance.now();
409
+ bst.addMany(nodes);
410
+ isDebug && console.log('---add', performance.now() - start);
411
+ const startL = performance.now();
412
+ bst.lesserOrGreaterForeach(inputSize / 2, CP.lt, node => {
413
+ return node.key - 1;
414
+ });
415
+ isDebug && console.log('---lesserOrGreaterForeach', performance.now() - startL);
416
+ });
417
+ });
@@ -5,7 +5,7 @@ describe('Overall BinaryTree Test', () => {
5
5
  const bst = new BST();
6
6
  bst.add(11);
7
7
  bst.add(3);
8
- bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
8
+ bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], undefined, false);
9
9
  bst.size === 16; // true
10
10
  expect(bst.size).toBe(16); // true
11
11
  bst.has(6); // true
@@ -1,5 +1,6 @@
1
- import {TreeMultiset, TreeMultisetNode} from '../../../../src';
1
+ import {CP, TreeMultiset, TreeMultisetNode} from '../../../../src';
2
2
 
3
+ const isDebug = false;
3
4
  describe('TreeMultiset operations test', () => {
4
5
  it('should perform various operations on a Binary Search Tree with numeric values', () => {
5
6
  const treeMultiset = new TreeMultiset();
@@ -39,20 +40,26 @@ describe('TreeMultiset operations test', () => {
39
40
  const minNodeBySpecificNode = node15 && treeMultiset.getLeftMost(node15);
40
41
  expect(minNodeBySpecificNode?.key).toBe(12);
41
42
 
42
- const subTreeSum = node15 && treeMultiset.subTreeSum(15);
43
+ let subTreeSum = 0;
44
+ node15 && treeMultiset.subTreeForeach(15, (node: TreeMultisetNode<number>) => (subTreeSum += node.key));
43
45
  expect(subTreeSum).toBe(70);
44
- const lesserSum = treeMultiset.lesserSum(10);
46
+ let lesserSum = 0;
47
+ treeMultiset.lesserOrGreaterForeach(10, CP.lt, (node: TreeMultisetNode<number>) => (lesserSum += node.key));
45
48
  expect(lesserSum).toBe(45);
46
49
 
47
50
  expect(node15 instanceof TreeMultisetNode);
48
51
  if (node15 instanceof TreeMultisetNode) {
49
- const subTreeAdd = treeMultiset.subTreeAddCount(15, 1);
52
+ const subTreeAdd = treeMultiset.subTreeForeach(15, (node: TreeMultisetNode<number>) => (node.count += 1));
50
53
  expect(subTreeAdd);
51
54
  }
52
55
  const node11 = treeMultiset.get(11);
53
56
  expect(node11 instanceof TreeMultisetNode);
54
57
  if (node11 instanceof TreeMultisetNode) {
55
- const allGreaterNodesAdded = treeMultiset.allGreaterNodesAddCount(11, 2);
58
+ const allGreaterNodesAdded = treeMultiset.lesserOrGreaterForeach(
59
+ 11,
60
+ CP.gt,
61
+ (node: TreeMultisetNode<number>) => (node.count += 2)
62
+ );
56
63
  expect(allGreaterNodesAdded);
57
64
  }
58
65
 
@@ -419,13 +426,19 @@ describe('TreeMultiset operations test', () => {
419
426
 
420
427
  describe('TreeMultiset Performance test', function () {
421
428
  // const treeMS = new TreeMultiset<TreeMultisetNode<number>>();
422
- // const inputSizes = [100]; // Adjust input sizes as needed
429
+ // const inputSize = [100]; // Adjust input sizes as needed
423
430
  //
424
431
  // // Define a function to calculate the expected O(n log n) time
425
432
  // function expectedTime(n: number): number {
426
433
  // return n * Math.log(n);
427
434
  // }
428
435
 
436
+ const treeMS = new TreeMultiset<TreeMultisetNode<number>>();
437
+ const inputSize = 100000; // Adjust input sizes as needed
438
+
439
+ beforeEach(() => {
440
+ treeMS.clear();
441
+ });
429
442
  it(`Observe the time consumption of TreeMultiset.add fitting O(n log n)`, function () {
430
443
  // // Create a benchmark suite
431
444
  // const suite = new Benchmark.Suite();
@@ -437,9 +450,9 @@ describe('TreeMultiset Performance test', function () {
437
450
  // }
438
451
  // return arr;
439
452
  // }
440
- // const inputArray = generateRandomArray(inputSizes[0]);
453
+ // const inputArray = generateRandomArray(inputSize[0]);
441
454
  //
442
- // suite.add(`TreeMultiset addMany (n=${inputSizes[0]})`, () => {
455
+ // suite.add(`TreeMultiset addMany (n=${inputSize[0]})`, () => {
443
456
  // treeMS.addMany([...inputArray]);
444
457
  // });
445
458
  //
@@ -453,9 +466,26 @@ describe('TreeMultiset Performance test', function () {
453
466
  // console.log(`Input size (n): ${n}, Observed time: ${observedTime.toFixed(2)}ms, Expected time: ${expected.toFixed(2)}ms`);
454
467
  // })
455
468
  // .on('complete', () => {
456
- // console.log(`Benchmark (n=${inputSizes[0]}) completed.`);
469
+ // console.log(`Benchmark (n=${inputSize[0]}) completed.`);
457
470
  // done(); // Call done to indicate the test is complete
458
471
  // })
459
472
  // .run({async: true});
460
473
  });
474
+
475
+ it(`Observe the time consumption of TreeMultiset.dfs be good`, function () {
476
+ const startDFS = performance.now();
477
+ const dfs = treeMS.dfs();
478
+ isDebug && console.log('---bfs', performance.now() - startDFS, dfs.length);
479
+ });
480
+
481
+ it('Should the time consumption of lesserOrGreaterForeach fitting O(n log n)', function () {
482
+ const start = performance.now();
483
+ for (let i = 0; i < inputSize; i++) {
484
+ treeMS.add(i);
485
+ }
486
+ isDebug && console.log('---add', performance.now() - start);
487
+ const startL = performance.now();
488
+ treeMS.lesserOrGreaterForeach(inputSize / 2, CP.lt, (node: TreeMultisetNode<number>) => (node.count += 1));
489
+ isDebug && console.log('---lesserOrGreaterForeach', performance.now() - startL);
490
+ });
461
491
  });
@@ -1,4 +1,5 @@
1
1
  import {Deque, ArrayDeque, ObjectDeque} from '../../../../src';
2
+ import {bigO} from '../../../utils';
2
3
 
3
4
  describe('Deque Tests', () => {
4
5
  // Test cases for the Deque class (DoublyLinkedList-based)
@@ -128,3 +129,19 @@ describe('Deque Tests', () => {
128
129
  // Add more test cases as needed
129
130
  });
130
131
  });
132
+
133
+ describe('Deque Performance Test', () => {
134
+ const dataSize = 10000;
135
+ it('should numeric queue be efficient', function () {
136
+ const startTime = performance.now();
137
+ const queue = new Deque<number>();
138
+ for (let i = 0; i < dataSize; i++) {
139
+ queue.unshift(i);
140
+ }
141
+ for (let i = 0; i < dataSize; i++) {
142
+ queue.pop();
143
+ }
144
+ console.log(`Queue Deque Test: ${performance.now() - startTime} ms`);
145
+ expect(performance.now() - startTime).toBeLessThan(bigO.LINEAR * 100);
146
+ });
147
+ });
@@ -197,3 +197,45 @@ describe('LinkedListQueue', () => {
197
197
 
198
198
  // Add more test cases for other methods of LinkedListQueue.
199
199
  });
200
+
201
+ describe('Queue Performance Test', () => {
202
+ const dataSize = 10000;
203
+ it('should numeric queue be efficient', function () {
204
+ const startTime = performance.now();
205
+ const queue = new Queue<number>();
206
+ for (let i = 0; i < dataSize; i++) {
207
+ queue.enqueue(i);
208
+ }
209
+ for (let i = 0; i < dataSize; i++) {
210
+ queue.dequeue();
211
+ }
212
+ console.log(`Queue Performance Test: ${performance.now() - startTime} ms`);
213
+ expect(performance.now() - startTime).toBeLessThan(bigO.LINEAR * 100);
214
+ });
215
+
216
+ it('should numeric Array be more efficient than Queue when the data size is 10000', function () {
217
+ const startTime2 = performance.now();
218
+ const queue2: number[] = [];
219
+ for (let i = 0; i < dataSize; i++) {
220
+ queue2.push(i);
221
+ }
222
+ for (let i = 0; i < dataSize; i++) {
223
+ queue2.shift();
224
+ }
225
+ console.log(`Array Performance Test: ${performance.now() - startTime2} ms`);
226
+ expect(performance.now() - startTime2).toBeLessThan(bigO.CUBED * 100);
227
+ });
228
+
229
+ it('should numeric LinkedListQueue be efficient', function () {
230
+ const startTime = performance.now();
231
+ const queue = new LinkedListQueue<number>();
232
+ for (let i = 0; i < dataSize; i++) {
233
+ queue.enqueue(i);
234
+ }
235
+ for (let i = 0; i < dataSize; i++) {
236
+ queue.dequeue();
237
+ }
238
+ console.log(`LinkedListQueue Performance Test: ${performance.now() - startTime} ms`);
239
+ expect(performance.now() - startTime).toBeLessThan(bigO.LINEAR * 100);
240
+ });
241
+ });
@@ -1,5 +1,6 @@
1
1
  import {AnyFunction} from '../types';
2
2
 
3
+ const isDebug = false;
3
4
  const orderReducedBy = 2; // reduction of bigO's order compared to the baseline bigO
4
5
 
5
6
  export const magnitude = {
@@ -148,12 +149,12 @@ export function logBigOMetricsWrap<F extends AnyFunction>(fn: F, args: Parameter
148
149
  methodLog.push([runTime, maxDataSize]);
149
150
 
150
151
  if (methodLog.length >= 20) {
151
- console.log('triggered', methodName, methodLog);
152
+ isDebug && console.log('triggered', methodName, methodLog);
152
153
  const bigO = estimateBigO(
153
154
  methodLog.map(([runTime]) => runTime),
154
155
  methodLog.map(([runTime]) => runTime)
155
156
  );
156
- console.log(`Estimated Big O: ${bigO}`);
157
+ isDebug && console.log(`Estimated Big O: ${bigO}`);
157
158
  methodLogs.delete(methodName);
158
159
  }
159
160
  }
@@ -182,12 +183,12 @@ export function logBigOMetrics(target: any, propertyKey: string, descriptor: Pro
182
183
  methodLog.push([runTime, maxDataSize]);
183
184
 
184
185
  if (methodLog.length >= 20) {
185
- console.log('triggered', methodName, methodLog);
186
+ isDebug && console.log('triggered', methodName, methodLog);
186
187
  const bigO = estimateBigO(
187
188
  methodLog.map(([runTime]) => runTime),
188
189
  methodLog.map(([runTime]) => runTime)
189
190
  );
190
- console.log(`Estimated Big O: ${bigO}`);
191
+ isDebug && console.log(`Estimated Big O: ${bigO}`);
191
192
  methodLogs.delete(methodName);
192
193
  }
193
194
  }