data-structure-typed 2.0.0 → 2.0.2

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 (60) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/cjs/data-structures/binary-tree/binary-tree.js +8 -9
  3. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  4. package/dist/cjs/data-structures/graph/abstract-graph.js +14 -14
  5. package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
  6. package/dist/cjs/data-structures/hash/hash-map.d.ts +46 -0
  7. package/dist/cjs/data-structures/hash/hash-map.js +46 -0
  8. package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
  9. package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +66 -0
  10. package/dist/cjs/data-structures/linked-list/singly-linked-list.js +66 -0
  11. package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
  12. package/dist/cjs/data-structures/queue/queue.d.ts +47 -0
  13. package/dist/cjs/data-structures/queue/queue.js +47 -0
  14. package/dist/cjs/data-structures/queue/queue.js.map +1 -1
  15. package/dist/cjs/data-structures/stack/stack.d.ts +121 -0
  16. package/dist/cjs/data-structures/stack/stack.js +121 -0
  17. package/dist/cjs/data-structures/stack/stack.js.map +1 -1
  18. package/dist/cjs/types/utils/utils.d.ts +1 -7
  19. package/dist/cjs/utils/utils.d.ts +3 -49
  20. package/dist/cjs/utils/utils.js +13 -82
  21. package/dist/cjs/utils/utils.js.map +1 -1
  22. package/dist/esm/data-structures/binary-tree/binary-tree.js +8 -9
  23. package/dist/esm/data-structures/binary-tree/binary-tree.js.map +1 -1
  24. package/dist/esm/data-structures/graph/abstract-graph.js +14 -14
  25. package/dist/esm/data-structures/graph/abstract-graph.js.map +1 -1
  26. package/dist/esm/data-structures/hash/hash-map.d.ts +46 -0
  27. package/dist/esm/data-structures/hash/hash-map.js +46 -0
  28. package/dist/esm/data-structures/hash/hash-map.js.map +1 -1
  29. package/dist/esm/data-structures/linked-list/singly-linked-list.d.ts +66 -0
  30. package/dist/esm/data-structures/linked-list/singly-linked-list.js +66 -0
  31. package/dist/esm/data-structures/linked-list/singly-linked-list.js.map +1 -1
  32. package/dist/esm/data-structures/queue/queue.d.ts +47 -0
  33. package/dist/esm/data-structures/queue/queue.js +47 -0
  34. package/dist/esm/data-structures/queue/queue.js.map +1 -1
  35. package/dist/esm/data-structures/stack/stack.d.ts +121 -0
  36. package/dist/esm/data-structures/stack/stack.js +121 -0
  37. package/dist/esm/data-structures/stack/stack.js.map +1 -1
  38. package/dist/esm/types/utils/utils.d.ts +1 -7
  39. package/dist/esm/utils/utils.d.ts +3 -49
  40. package/dist/esm/utils/utils.js +10 -68
  41. package/dist/esm/utils/utils.js.map +1 -1
  42. package/dist/umd/data-structure-typed.js +32 -80
  43. package/dist/umd/data-structure-typed.min.js +2 -2
  44. package/dist/umd/data-structure-typed.min.js.map +1 -1
  45. package/package.json +2 -2
  46. package/src/data-structures/binary-tree/binary-tree.ts +9 -10
  47. package/src/data-structures/graph/abstract-graph.ts +14 -14
  48. package/src/data-structures/hash/hash-map.ts +46 -0
  49. package/src/data-structures/linked-list/singly-linked-list.ts +66 -0
  50. package/src/data-structures/queue/queue.ts +47 -0
  51. package/src/data-structures/stack/stack.ts +121 -0
  52. package/src/types/utils/utils.ts +1 -6
  53. package/src/utils/utils.ts +11 -83
  54. package/test/unit/data-structures/graph/directed-graph.test.ts +37 -37
  55. package/test/unit/data-structures/graph/undirected-graph.test.ts +2 -2
  56. package/test/unit/data-structures/hash/hash-map.test.ts +135 -0
  57. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +72 -1
  58. package/test/unit/data-structures/queue/queue.test.ts +214 -0
  59. package/test/unit/data-structures/stack/stack.test.ts +165 -0
  60. package/test/unit/utils/utils.test.ts +35 -2
@@ -341,9 +341,9 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
341
341
  expect(distMap.get(vertex3)).toBe(35);
342
342
  expect(distMap.get(vertex4)).toBe(14);
343
343
  expect(distMap.get(vertex5)).toBe(70);
344
- expect(distMap.get(vertex6)).toBe(Infinity);
344
+ expect(distMap.get(vertex6)).toBe(Number.MAX_SAFE_INTEGER);
345
345
  expect(distMap.get(vertex7)).toBe(61);
346
- expect(distMap.get(vertex8)).toBe(Infinity);
346
+ expect(distMap.get(vertex8)).toBe(Number.MAX_SAFE_INTEGER);
347
347
  expect(distMap.get(vertex9)).toBe(19);
348
348
 
349
349
  expect(preMap).toBeInstanceOf(Map);
@@ -351,7 +351,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
351
351
 
352
352
  expect(paths).toBeInstanceOf(Array);
353
353
  expect(paths.length).toBe(0);
354
- expect(min).toBe(Infinity);
354
+ expect(min).toBe(Number.MAX_SAFE_INTEGER);
355
355
  expect(minPath).toBeInstanceOf(Array);
356
356
 
357
357
  const floydResult = myGraph.floydWarshall();
@@ -360,35 +360,35 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
360
360
  const { costs, predecessor } = floydResult;
361
361
  expect(costs).toBeInstanceOf(Array);
362
362
  expect(costs.length).toBe(9);
363
- expect(costs[0]).toEqual([32, 12, 35, 14, 70, Infinity, 61, Infinity, 19]);
364
- expect(costs[1]).toEqual([20, 32, 23, 34, 58, Infinity, 81, Infinity, 39]);
365
- expect(costs[2]).toEqual([3, 15, 38, 17, 35, Infinity, 64, Infinity, 22]);
366
- expect(costs[3]).toEqual([123, 135, 120, 137, 155, Infinity, 47, Infinity, 126]);
367
- expect(costs[4]).toEqual([133, 145, 130, 147, 165, Infinity, 57, Infinity, 136]);
363
+ expect(costs[0]).toEqual([32, 12, 35, 14, 70, Number.MAX_SAFE_INTEGER, 61, Number.MAX_SAFE_INTEGER, 19]);
364
+ expect(costs[1]).toEqual([20, 32, 23, 34, 58, Number.MAX_SAFE_INTEGER, 81, Number.MAX_SAFE_INTEGER, 39]);
365
+ expect(costs[2]).toEqual([3, 15, 38, 17, 35, Number.MAX_SAFE_INTEGER, 64, Number.MAX_SAFE_INTEGER, 22]);
366
+ expect(costs[3]).toEqual([123, 135, 120, 137, 155, Number.MAX_SAFE_INTEGER, 47, Number.MAX_SAFE_INTEGER, 126]);
367
+ expect(costs[4]).toEqual([133, 145, 130, 147, 165, Number.MAX_SAFE_INTEGER, 57, Number.MAX_SAFE_INTEGER, 136]);
368
368
  expect(costs[5]).toEqual([
369
- Infinity,
370
- Infinity,
371
- Infinity,
372
- Infinity,
373
- Infinity,
374
- Infinity,
375
- Infinity,
376
- Infinity,
377
- Infinity
369
+ Number.MAX_SAFE_INTEGER,
370
+ Number.MAX_SAFE_INTEGER,
371
+ Number.MAX_SAFE_INTEGER,
372
+ Number.MAX_SAFE_INTEGER,
373
+ Number.MAX_SAFE_INTEGER,
374
+ Number.MAX_SAFE_INTEGER,
375
+ Number.MAX_SAFE_INTEGER,
376
+ Number.MAX_SAFE_INTEGER,
377
+ Number.MAX_SAFE_INTEGER
378
378
  ]);
379
- expect(costs[6]).toEqual([76, 88, 73, 90, 108, Infinity, 137, Infinity, 79]);
379
+ expect(costs[6]).toEqual([76, 88, 73, 90, 108, Number.MAX_SAFE_INTEGER, 137, Number.MAX_SAFE_INTEGER, 79]);
380
380
  expect(costs[7]).toEqual([
381
- Infinity,
382
- Infinity,
383
- Infinity,
384
- Infinity,
385
- Infinity,
386
- Infinity,
387
- Infinity,
388
- Infinity,
389
- Infinity
381
+ Number.MAX_SAFE_INTEGER,
382
+ Number.MAX_SAFE_INTEGER,
383
+ Number.MAX_SAFE_INTEGER,
384
+ Number.MAX_SAFE_INTEGER,
385
+ Number.MAX_SAFE_INTEGER,
386
+ Number.MAX_SAFE_INTEGER,
387
+ Number.MAX_SAFE_INTEGER,
388
+ Number.MAX_SAFE_INTEGER,
389
+ Number.MAX_SAFE_INTEGER
390
390
  ]);
391
- expect(costs[8]).toEqual([173, 185, 170, 187, 205, Infinity, 97, Infinity, 176]);
391
+ expect(costs[8]).toEqual([173, 185, 170, 187, 205, Number.MAX_SAFE_INTEGER, 97, Number.MAX_SAFE_INTEGER, 176]);
392
392
 
393
393
  expect(predecessor).toBeInstanceOf(Array);
394
394
  expect(predecessor.length).toBe(9);
@@ -458,12 +458,12 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
458
458
  expect(distMap.size).toBe(9);
459
459
  expect(distMap.get(vertex1)).toBe(0);
460
460
  expect(distMap.get(vertex2)).toBe(12);
461
- expect(distMap.get(vertex3)).toBe(Infinity);
461
+ expect(distMap.get(vertex3)).toBe(Number.MAX_SAFE_INTEGER);
462
462
  expect(distMap.get(vertex4)).toBe(14);
463
- expect(distMap.get(vertex5)).toBe(Infinity);
464
- expect(distMap.get(vertex6)).toBe(Infinity);
465
- expect(distMap.get(vertex7)).toBe(Infinity);
466
- expect(distMap.get(vertex8)).toBe(Infinity);
463
+ expect(distMap.get(vertex5)).toBe(Number.MAX_SAFE_INTEGER);
464
+ expect(distMap.get(vertex6)).toBe(Number.MAX_SAFE_INTEGER);
465
+ expect(distMap.get(vertex7)).toBe(Number.MAX_SAFE_INTEGER);
466
+ expect(distMap.get(vertex8)).toBe(Number.MAX_SAFE_INTEGER);
467
467
  expect(distMap.get(vertex9)).toBe(19);
468
468
 
469
469
  expect(minDist).toBe(12);
@@ -512,9 +512,9 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
512
512
  expect(distMap.get(vertex3)).toBe(35);
513
513
  expect(distMap.get(vertex4)).toBe(14);
514
514
  expect(distMap.get(vertex5)).toBe(70);
515
- expect(distMap.get(vertex6)).toBe(Infinity);
515
+ expect(distMap.get(vertex6)).toBe(Number.MAX_SAFE_INTEGER);
516
516
  expect(distMap.get(vertex7)).toBe(61);
517
- expect(distMap.get(vertex8)).toBe(Infinity);
517
+ expect(distMap.get(vertex8)).toBe(Number.MAX_SAFE_INTEGER);
518
518
  expect(distMap.get(vertex9)).toBe(19);
519
519
 
520
520
  expect(minDist).toBe(12);
@@ -574,9 +574,9 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
574
574
  expect(distMap.get(vertex3)).toBe(35);
575
575
  expect(distMap.get(vertex4)).toBe(14);
576
576
  expect(distMap.get(vertex5)).toBe(70);
577
- expect(distMap.get(vertex6)).toBe(Infinity);
577
+ expect(distMap.get(vertex6)).toBe(Number.MAX_SAFE_INTEGER);
578
578
  expect(distMap.get(vertex7)).toBe(61);
579
- expect(distMap.get(vertex8)).toBe(Infinity);
579
+ expect(distMap.get(vertex8)).toBe(Number.MAX_SAFE_INTEGER);
580
580
  expect(distMap.get(vertex9)).toBe(19);
581
581
 
582
582
  expect(minDist).toBe(12);
@@ -264,7 +264,7 @@ describe('cycles, strongly connected components, bridges, articular points in Un
264
264
  expect(lowMap.size).toBe(8);
265
265
  });
266
266
 
267
- it('Should return Infinity if dest is not found', () => {
267
+ it('Should return Number.MAX_SAFE_INTEGER if dest is not found', () => {
268
268
  const graph = new UndirectedGraph<string>();
269
269
 
270
270
  for (let i = 0; i < 3; ++i) {
@@ -274,7 +274,7 @@ it('Should return Infinity if dest is not found', () => {
274
274
  graph.addEdge(0, 1, 1);
275
275
 
276
276
  const minCost02 = graph.getMinCostBetween(0, 2, true);
277
- expect(minCost02).toBe(Infinity);
277
+ expect(minCost02).toBe(Number.MAX_SAFE_INTEGER);
278
278
 
279
279
  const minCost01 = graph.getMinCostBetween(0, 1, true);
280
280
  expect(minCost01).toBe(1);
@@ -842,3 +842,138 @@ describe('LinkedHashMap', () => {
842
842
  });
843
843
  });
844
844
  });
845
+
846
+ describe('classic uses', () => {
847
+ it('@example should maintain insertion order', () => {
848
+ const linkedHashMap = new LinkedHashMap<number, string>();
849
+ linkedHashMap.set(1, 'A');
850
+ linkedHashMap.set(2, 'B');
851
+ linkedHashMap.set(3, 'C');
852
+
853
+ const result = Array.from(linkedHashMap);
854
+ expect(result).toEqual([
855
+ [1, 'A'],
856
+ [2, 'B'],
857
+ [3, 'C']
858
+ ]);
859
+ });
860
+
861
+ it('should allow reverse iteration', () => {
862
+ const linkedHashMap = new LinkedHashMap<number, string>();
863
+ linkedHashMap.set(1, 'A');
864
+ linkedHashMap.set(2, 'B');
865
+ linkedHashMap.set(3, 'C');
866
+
867
+ const result = Array.from(linkedHashMap.reverseBegin());
868
+ expect(result).toEqual([
869
+ [3, 'C'],
870
+ [2, 'B'],
871
+ [1, 'A']
872
+ ]);
873
+ });
874
+
875
+ it('should allow fast deletion at an index', () => {
876
+ const linkedHashMap = new LinkedHashMap<number, string>();
877
+ linkedHashMap.set(1, 'A');
878
+ linkedHashMap.set(2, 'B');
879
+ linkedHashMap.set(3, 'C');
880
+
881
+ linkedHashMap.deleteAt(1);
882
+
883
+ const result = Array.from(linkedHashMap);
884
+ expect(result).toEqual([
885
+ [1, 'A'],
886
+ [3, 'C']
887
+ ]);
888
+ });
889
+
890
+ it('should filter entries correctly', () => {
891
+ const linkedHashMap = new LinkedHashMap<number, string>();
892
+ linkedHashMap.set(1, 'A');
893
+ linkedHashMap.set(2, 'B');
894
+ linkedHashMap.set(3, 'C');
895
+
896
+ const filteredMap = linkedHashMap.filter((key, value) => value !== 'B');
897
+
898
+ const result = Array.from(filteredMap);
899
+ expect(result).toEqual([
900
+ [1, 'A'],
901
+ [3, 'C']
902
+ ]);
903
+ });
904
+
905
+ it('should map entries to a new LinkedHashMap', () => {
906
+ const linkedHashMap = new LinkedHashMap<number, string>();
907
+ linkedHashMap.set(1, 'A');
908
+ linkedHashMap.set(2, 'B');
909
+
910
+ const mappedMap = linkedHashMap.map((key, value) => [value, key]);
911
+
912
+ const result = Array.from(mappedMap);
913
+ expect(result).toEqual([
914
+ ['A', 1],
915
+ ['B', 2]
916
+ ]);
917
+ });
918
+ });
919
+
920
+ describe('classic uses', () => {
921
+ it('@example fast lookup of values by key', () => {
922
+ const hashMap = new HashMap<number, string>();
923
+ hashMap.set(1, 'A');
924
+ hashMap.set(2, 'B');
925
+ hashMap.set(3, 'C');
926
+
927
+ expect(hashMap.get(1)).toBe('A');
928
+ expect(hashMap.get(2)).toBe('B');
929
+ expect(hashMap.get(3)).toBe('C');
930
+ expect(hashMap.get(99)).toBeUndefined(); // Key not present
931
+ });
932
+
933
+ it('@example remove duplicates when adding multiple entries', () => {
934
+ const hashMap = new HashMap<number, string>();
935
+ hashMap.set(1, 'A');
936
+ hashMap.set(2, 'B');
937
+ hashMap.set(1, 'C'); // Update value for key 1
938
+
939
+ expect(hashMap.size).toBe(2);
940
+ expect(hashMap.get(1)).toBe('C');
941
+ expect(hashMap.get(2)).toBe('B');
942
+ });
943
+
944
+ it('@example count occurrences of keys', () => {
945
+ const data = [1, 2, 1, 3, 2, 1];
946
+
947
+ const countMap = new HashMap<number, number>();
948
+ for (const key of data) {
949
+ countMap.set(key, (countMap.get(key) || 0) + 1);
950
+ }
951
+
952
+ expect(countMap.get(1)).toBe(3);
953
+ expect(countMap.get(2)).toBe(2);
954
+ expect(countMap.get(3)).toBe(1);
955
+ });
956
+
957
+ it('should group entries by a key-derived property', () => {
958
+ const entries = [
959
+ { id: 1, group: 'A' },
960
+ { id: 2, group: 'B' },
961
+ { id: 3, group: 'A' },
962
+ { id: 4, group: 'B' }
963
+ ];
964
+
965
+ const groupedMap = new HashMap<string, number[]>();
966
+
967
+ for (const entry of entries) {
968
+ const group = entry.group;
969
+ const id = entry.id;
970
+ if (!groupedMap.has(group)) {
971
+ groupedMap.set(group, []);
972
+ }
973
+ groupedMap.get(group)?.push(id);
974
+ }
975
+
976
+ expect(groupedMap.get('A')).toEqual([1, 3]);
977
+ expect(groupedMap.get('B')).toEqual([2, 4]);
978
+ });
979
+ });
@@ -1,4 +1,4 @@
1
- import { SinglyLinkedList, SinglyLinkedListNode } from '../../../../src';
1
+ import { SinglyLinkedList, SinglyLinkedListNode, Stack } from '../../../../src';
2
2
 
3
3
  describe('SinglyLinkedListNode', () => {
4
4
  it('should SinglyLinkedList', () => {
@@ -649,3 +649,74 @@ describe('iterable methods', () => {
649
649
  expect(sl.reduce((accumulator, element) => accumulator + element, 0)).toEqual(6);
650
650
  });
651
651
  });
652
+
653
+ describe('classic uses', () => {
654
+
655
+ it('@example implementation of a basic text editor', () => {
656
+
657
+ class TextEditor {
658
+ private content: SinglyLinkedList<string>;
659
+ private cursorIndex: number;
660
+ private undoStack: Stack<{ operation: string; data?: any }>;
661
+
662
+ constructor() {
663
+ this.content = new SinglyLinkedList<string>();
664
+ this.cursorIndex = 0; // Cursor starts at the beginning
665
+ this.undoStack = new Stack<{ operation: string; data?: any }>(); // Stack to keep track of operations for undo
666
+ }
667
+
668
+ insert(char: string) {
669
+ this.content.addAt(this.cursorIndex, char);
670
+ this.cursorIndex++;
671
+ this.undoStack.push({ operation: 'insert', data: { index: this.cursorIndex - 1 } });
672
+ }
673
+
674
+ delete() {
675
+ if (this.cursorIndex === 0) return; // Nothing to delete
676
+ const deleted = this.content.deleteAt(this.cursorIndex - 1);
677
+ this.cursorIndex--;
678
+ this.undoStack.push({ operation: 'delete', data: { index: this.cursorIndex, char: deleted } });
679
+ }
680
+
681
+ moveCursor(index: number) {
682
+ this.cursorIndex = Math.max(0, Math.min(index, this.content.length));
683
+ }
684
+
685
+ undo() {
686
+ if (this.undoStack.size === 0) return; // No operations to undo
687
+ const lastAction = this.undoStack.pop();
688
+
689
+ if (lastAction!.operation === 'insert') {
690
+ this.content.deleteAt(lastAction!.data.index);
691
+ this.cursorIndex = lastAction!.data.index;
692
+ } else if (lastAction!.operation === 'delete') {
693
+ this.content.addAt(lastAction!.data.index, lastAction!.data.char);
694
+ this.cursorIndex = lastAction!.data.index + 1;
695
+ }
696
+ }
697
+
698
+ getText(): string {
699
+ return [...this.content].join('');
700
+ }
701
+ }
702
+
703
+ // Example Usage
704
+ const editor = new TextEditor();
705
+ editor.insert('H');
706
+ editor.insert('e');
707
+ editor.insert('l');
708
+ editor.insert('l');
709
+ editor.insert('o');
710
+ expect(editor.getText()).toBe('Hello'); // Output: "Hello"
711
+
712
+ editor.delete();
713
+ expect(editor.getText()).toBe('Hell'); // Output: "Hell"
714
+
715
+ editor.undo();
716
+ expect(editor.getText()).toBe('Hello'); // Output: "Hello"
717
+
718
+ editor.moveCursor(1);
719
+ editor.insert('a');
720
+ expect(editor.getText()).toBe('Haello'); // Output: "Haello"
721
+ });
722
+ });
@@ -454,3 +454,217 @@ describe('LinkedListQueue', () => {
454
454
  expect(cloned.length).toBe(2);
455
455
  });
456
456
  });
457
+
458
+ describe('Queue', () => {
459
+ // Test queue initialization
460
+ it('should initialize correctly with no elements', () => {
461
+ const queue = new Queue();
462
+ expect(queue.isEmpty()).toBe(true);
463
+ expect(queue.length).toBe(0);
464
+ expect(queue.first).toBeUndefined();
465
+ expect(queue.last).toBeUndefined();
466
+ });
467
+
468
+ it('should initialize correctly with given elements', () => {
469
+ const queue = new Queue([1, 2, 3]);
470
+ expect(queue.length).toBe(3);
471
+ expect(queue.first).toBe(1);
472
+ expect(queue.last).toBe(3);
473
+ });
474
+
475
+ // Test push and pushMany
476
+ it('should add elements to the queue', () => {
477
+ const queue = new Queue<number>();
478
+ queue.push(1);
479
+ queue.push(2);
480
+ expect(queue.length).toBe(2);
481
+ expect(queue.first).toBe(1);
482
+ expect(queue.last).toBe(2);
483
+ });
484
+
485
+ it('should add multiple elements using pushMany', () => {
486
+ const queue = new Queue<number>();
487
+ queue.pushMany([1, 2, 3]);
488
+ expect(queue.length).toBe(3);
489
+ expect(queue.elements).toEqual([1, 2, 3]);
490
+ });
491
+
492
+ // Test shift
493
+ it('should remove the first element from the queue', () => {
494
+ const queue = new Queue([1, 2, 3]);
495
+ const shifted = queue.shift();
496
+ expect(shifted).toBe(1);
497
+ expect(queue.length).toBe(2);
498
+ expect(queue.first).toBe(2);
499
+ });
500
+
501
+ // Test delete and deleteAt
502
+ it('should delete an element from the queue', () => {
503
+ const queue = new Queue([1, 2, 3]);
504
+ const result = queue.delete(2);
505
+ expect(result).toBe(true);
506
+ expect(queue.elements).toEqual([1, 3]);
507
+ });
508
+
509
+ it('should delete an element at a specific index', () => {
510
+ const queue = new Queue([1, 2, 3]);
511
+ const deleted = queue.deleteAt(1);
512
+ expect(deleted).toBe(2);
513
+ expect(queue.elements).toEqual([1, 3]);
514
+ });
515
+
516
+ // Test at
517
+ it('should retrieve an element by index', () => {
518
+ const queue = new Queue([1, 2, 3]);
519
+ expect(queue.at(0)).toBe(1);
520
+ expect(queue.at(2)).toBe(3);
521
+ });
522
+
523
+ // Test reverse
524
+ it('should reverse the queue', () => {
525
+ const queue = new Queue([1, 2, 3]);
526
+ queue.reverse();
527
+ expect(queue.elements).toEqual([3, 2, 1]);
528
+ expect(queue.first).toBe(3);
529
+ expect(queue.last).toBe(1);
530
+ });
531
+
532
+ // Test addAt
533
+ it('should add an element at a specific index', () => {
534
+ const queue = new Queue([1, 3]);
535
+ const result = queue.addAt(1, 2);
536
+ expect(result).toBe(true);
537
+ expect(queue.elements).toEqual([1, 2, 3]);
538
+ });
539
+
540
+ // Test setAt
541
+ it('should set an element at a specific index', () => {
542
+ const queue = new Queue([1, 2, 3]);
543
+ const result = queue.setAt(1, 10);
544
+ expect(result).toBe(true);
545
+ expect(queue.elements).toEqual([1, 10, 3]);
546
+ });
547
+
548
+ // Test clear
549
+ it('should clear the queue', () => {
550
+ const queue = new Queue([1, 2, 3]);
551
+ queue.clear();
552
+ expect(queue.isEmpty()).toBe(true);
553
+ expect(queue.length).toBe(0);
554
+ });
555
+
556
+ // Test compact
557
+ it('should compact the queue', () => {
558
+ const queue = new Queue([1, 2, 3]);
559
+ queue.shift();
560
+ queue.shift();
561
+ queue.compact();
562
+ expect(queue.elements).toEqual([3]);
563
+ });
564
+
565
+ // Test splice
566
+ it('should splice elements from the queue', () => {
567
+ const queue = new Queue([1, 2, 3, 4]);
568
+ const removed = queue.splice(1, 2);
569
+ expect(removed.elements).toEqual([2, 3]);
570
+ expect(queue.elements).toEqual([1, 4]);
571
+ });
572
+
573
+ // Test clone
574
+ it('should create a clone of the queue', () => {
575
+ const queue = new Queue([1, 2, 3]);
576
+ const clone = queue.clone();
577
+ expect(clone.elements).toEqual(queue.elements);
578
+ clone.push(4);
579
+ expect(queue.elements).not.toContain(4);
580
+ });
581
+
582
+ // Test filter
583
+ it('should filter elements based on a predicate', () => {
584
+ const queue = new Queue([1, 2, 3, 4]);
585
+ const filtered = queue.filter(el => el % 2 === 0);
586
+ expect(filtered.elements).toEqual([2, 4]);
587
+ });
588
+
589
+ // Test map
590
+ it('should map elements to a new queue', () => {
591
+ const queue = new Queue([1, 2, 3]);
592
+ const mapped = queue.map(el => el * 2);
593
+ expect(mapped.elements).toEqual([2, 4, 6]);
594
+ });
595
+ });
596
+
597
+ describe('classic uses', () => {
598
+ it('@example Sliding Window using Queue', () => {
599
+ const nums = [2, 3, 4, 1, 5];
600
+ const k = 2;
601
+ const queue = new Queue<number>();
602
+
603
+ let maxSum = 0;
604
+ let currentSum = 0;
605
+
606
+ nums.forEach((num) => {
607
+ queue.push(num);
608
+ currentSum += num;
609
+
610
+ if (queue.length > k) {
611
+ currentSum -= queue.shift()!;
612
+ }
613
+
614
+ if (queue.length === k) {
615
+ maxSum = Math.max(maxSum, currentSum);
616
+ }
617
+ });
618
+
619
+ expect(maxSum).toBe(7); // Maximum sum is from subarray [3, 4].
620
+ });
621
+
622
+ it('@example Breadth-First Search (BFS) using Queue', () => {
623
+ const graph: { [key in number]: number[] } = {
624
+ 1: [2, 3],
625
+ 2: [4, 5],
626
+ 3: [],
627
+ 4: [],
628
+ 5: []
629
+ };
630
+
631
+ const queue = new Queue<number>();
632
+ const visited: number[] = [];
633
+
634
+ queue.push(1);
635
+
636
+ while (!queue.isEmpty()) {
637
+ const node = queue.shift()!;
638
+ if (!visited.includes(node)) {
639
+ visited.push(node);
640
+ graph[node].forEach(neighbor => queue.push(neighbor));
641
+ }
642
+ }
643
+
644
+ expect(visited).toEqual([1, 2, 3, 4, 5]); // Expected BFS traversal order.
645
+ });
646
+
647
+ it('Task Scheduling using Queue', () => {
648
+ const tasks = ['A', 'A', 'A', 'B', 'B', 'B'];
649
+ const cooldown = 2;
650
+
651
+ const taskQueue = new Queue<string>();
652
+ const cooldownQueue = new Queue<string>();
653
+
654
+ for (const task of tasks) {
655
+ while (!cooldownQueue.isEmpty() && cooldownQueue.first === task) {
656
+ cooldownQueue.shift();
657
+ taskQueue.push('idle');
658
+ }
659
+
660
+ taskQueue.push(task);
661
+ cooldownQueue.push(task);
662
+ if (cooldownQueue.length > cooldown) {
663
+ cooldownQueue.shift();
664
+ }
665
+ }
666
+
667
+ const scheduled = taskQueue.elements;
668
+ expect(scheduled).toEqual(['A', 'idle', 'A', 'idle', 'A', 'B', 'B', 'idle', 'idle', 'B']);
669
+ });
670
+ });