data-structure-typed 1.54.3 → 2.0.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 (174) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/benchmark/report.html +26 -2
  3. package/benchmark/report.json +292 -42
  4. package/dist/cjs/data-structures/base/iterable-element-base.d.ts +14 -40
  5. package/dist/cjs/data-structures/base/iterable-element-base.js +14 -11
  6. package/dist/cjs/data-structures/base/iterable-element-base.js.map +1 -1
  7. package/dist/cjs/data-structures/base/linear-base.d.ts +277 -0
  8. package/dist/cjs/data-structures/base/linear-base.js +553 -0
  9. package/dist/cjs/data-structures/base/linear-base.js.map +1 -0
  10. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
  11. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +50 -37
  12. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  13. package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +64 -0
  14. package/dist/cjs/data-structures/binary-tree/avl-tree.js +64 -0
  15. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  16. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +62 -0
  17. package/dist/cjs/data-structures/binary-tree/binary-tree.js +67 -5
  18. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  19. package/dist/cjs/data-structures/binary-tree/bst.d.ts +3 -3
  20. package/dist/cjs/data-structures/binary-tree/bst.js +14 -14
  21. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  22. package/dist/cjs/data-structures/binary-tree/red-black-tree.d.ts +1 -7
  23. package/dist/cjs/data-structures/binary-tree/red-black-tree.js +1 -7
  24. package/dist/cjs/data-structures/binary-tree/red-black-tree.js.map +1 -1
  25. package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
  26. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +210 -40
  27. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  28. package/dist/cjs/data-structures/graph/abstract-graph.js +2 -2
  29. package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
  30. package/dist/cjs/data-structures/heap/heap.d.ts +3 -11
  31. package/dist/cjs/data-structures/heap/heap.js +0 -10
  32. package/dist/cjs/data-structures/heap/heap.js.map +1 -1
  33. package/dist/cjs/data-structures/heap/max-heap.d.ts +2 -2
  34. package/dist/cjs/data-structures/heap/max-heap.js.map +1 -1
  35. package/dist/cjs/data-structures/heap/min-heap.d.ts +2 -2
  36. package/dist/cjs/data-structures/heap/min-heap.js.map +1 -1
  37. package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
  38. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +131 -146
  39. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  40. package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +79 -75
  41. package/dist/cjs/data-structures/linked-list/singly-linked-list.js +217 -169
  42. package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
  43. package/dist/cjs/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
  44. package/dist/cjs/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  45. package/dist/cjs/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
  46. package/dist/cjs/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  47. package/dist/cjs/data-structures/priority-queue/priority-queue.d.ts +2 -2
  48. package/dist/cjs/data-structures/priority-queue/priority-queue.js.map +1 -1
  49. package/dist/cjs/data-structures/queue/deque.d.ts +130 -91
  50. package/dist/cjs/data-structures/queue/deque.js +269 -169
  51. package/dist/cjs/data-structures/queue/deque.js.map +1 -1
  52. package/dist/cjs/data-structures/queue/queue.d.ts +84 -40
  53. package/dist/cjs/data-structures/queue/queue.js +134 -50
  54. package/dist/cjs/data-structures/queue/queue.js.map +1 -1
  55. package/dist/cjs/data-structures/stack/stack.d.ts +3 -11
  56. package/dist/cjs/data-structures/stack/stack.js +0 -10
  57. package/dist/cjs/data-structures/stack/stack.js.map +1 -1
  58. package/dist/cjs/data-structures/trie/trie.d.ts +4 -3
  59. package/dist/cjs/data-structures/trie/trie.js +3 -0
  60. package/dist/cjs/data-structures/trie/trie.js.map +1 -1
  61. package/dist/cjs/types/data-structures/base/base.d.ts +9 -4
  62. package/dist/cjs/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
  63. package/dist/cjs/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  64. package/dist/cjs/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
  65. package/dist/cjs/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
  66. package/dist/cjs/types/data-structures/queue/deque.d.ts +2 -3
  67. package/dist/cjs/types/data-structures/queue/queue.d.ts +2 -2
  68. package/dist/esm/data-structures/base/iterable-element-base.d.ts +14 -40
  69. package/dist/esm/data-structures/base/iterable-element-base.js +14 -11
  70. package/dist/esm/data-structures/base/iterable-element-base.js.map +1 -1
  71. package/dist/esm/data-structures/base/linear-base.d.ts +277 -0
  72. package/dist/esm/data-structures/base/linear-base.js +549 -0
  73. package/dist/esm/data-structures/base/linear-base.js.map +1 -0
  74. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
  75. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js +50 -36
  76. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  77. package/dist/esm/data-structures/binary-tree/avl-tree.d.ts +64 -0
  78. package/dist/esm/data-structures/binary-tree/avl-tree.js +64 -0
  79. package/dist/esm/data-structures/binary-tree/avl-tree.js.map +1 -1
  80. package/dist/esm/data-structures/binary-tree/binary-tree.d.ts +62 -0
  81. package/dist/esm/data-structures/binary-tree/binary-tree.js +67 -5
  82. package/dist/esm/data-structures/binary-tree/binary-tree.js.map +1 -1
  83. package/dist/esm/data-structures/binary-tree/bst.d.ts +3 -3
  84. package/dist/esm/data-structures/binary-tree/bst.js +14 -12
  85. package/dist/esm/data-structures/binary-tree/bst.js.map +1 -1
  86. package/dist/esm/data-structures/binary-tree/red-black-tree.d.ts +1 -7
  87. package/dist/esm/data-structures/binary-tree/red-black-tree.js +1 -7
  88. package/dist/esm/data-structures/binary-tree/red-black-tree.js.map +1 -1
  89. package/dist/esm/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
  90. package/dist/esm/data-structures/binary-tree/tree-multi-map.js +210 -39
  91. package/dist/esm/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  92. package/dist/esm/data-structures/graph/abstract-graph.js +2 -2
  93. package/dist/esm/data-structures/graph/abstract-graph.js.map +1 -1
  94. package/dist/esm/data-structures/heap/heap.d.ts +3 -11
  95. package/dist/esm/data-structures/heap/heap.js +0 -10
  96. package/dist/esm/data-structures/heap/heap.js.map +1 -1
  97. package/dist/esm/data-structures/heap/max-heap.d.ts +2 -2
  98. package/dist/esm/data-structures/heap/max-heap.js.map +1 -1
  99. package/dist/esm/data-structures/heap/min-heap.d.ts +2 -2
  100. package/dist/esm/data-structures/heap/min-heap.js.map +1 -1
  101. package/dist/esm/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
  102. package/dist/esm/data-structures/linked-list/doubly-linked-list.js +132 -148
  103. package/dist/esm/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  104. package/dist/esm/data-structures/linked-list/singly-linked-list.d.ts +79 -75
  105. package/dist/esm/data-structures/linked-list/singly-linked-list.js +217 -170
  106. package/dist/esm/data-structures/linked-list/singly-linked-list.js.map +1 -1
  107. package/dist/esm/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
  108. package/dist/esm/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  109. package/dist/esm/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
  110. package/dist/esm/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  111. package/dist/esm/data-structures/priority-queue/priority-queue.d.ts +2 -2
  112. package/dist/esm/data-structures/priority-queue/priority-queue.js.map +1 -1
  113. package/dist/esm/data-structures/queue/deque.d.ts +130 -91
  114. package/dist/esm/data-structures/queue/deque.js +269 -169
  115. package/dist/esm/data-structures/queue/deque.js.map +1 -1
  116. package/dist/esm/data-structures/queue/queue.d.ts +84 -40
  117. package/dist/esm/data-structures/queue/queue.js +135 -51
  118. package/dist/esm/data-structures/queue/queue.js.map +1 -1
  119. package/dist/esm/data-structures/stack/stack.d.ts +3 -11
  120. package/dist/esm/data-structures/stack/stack.js +0 -10
  121. package/dist/esm/data-structures/stack/stack.js.map +1 -1
  122. package/dist/esm/data-structures/trie/trie.d.ts +4 -3
  123. package/dist/esm/data-structures/trie/trie.js +3 -0
  124. package/dist/esm/data-structures/trie/trie.js.map +1 -1
  125. package/dist/esm/types/data-structures/base/base.d.ts +9 -4
  126. package/dist/esm/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
  127. package/dist/esm/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  128. package/dist/esm/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
  129. package/dist/esm/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
  130. package/dist/esm/types/data-structures/queue/deque.d.ts +2 -3
  131. package/dist/esm/types/data-structures/queue/queue.d.ts +2 -2
  132. package/dist/umd/data-structure-typed.js +1246 -635
  133. package/dist/umd/data-structure-typed.min.js +3 -3
  134. package/dist/umd/data-structure-typed.min.js.map +1 -1
  135. package/package.json +6 -6
  136. package/src/data-structures/base/iterable-element-base.ts +29 -20
  137. package/src/data-structures/base/linear-base.ts +649 -0
  138. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +51 -36
  139. package/src/data-structures/binary-tree/avl-tree.ts +64 -0
  140. package/src/data-structures/binary-tree/binary-tree.ts +5 -5
  141. package/src/data-structures/binary-tree/bst.ts +9 -9
  142. package/src/data-structures/binary-tree/tree-multi-map.ts +214 -40
  143. package/src/data-structures/graph/abstract-graph.ts +2 -2
  144. package/src/data-structures/heap/heap.ts +3 -14
  145. package/src/data-structures/heap/max-heap.ts +2 -2
  146. package/src/data-structures/heap/min-heap.ts +2 -2
  147. package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
  148. package/src/data-structures/linked-list/singly-linked-list.ts +241 -185
  149. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
  150. package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
  151. package/src/data-structures/priority-queue/priority-queue.ts +2 -2
  152. package/src/data-structures/queue/deque.ts +286 -183
  153. package/src/data-structures/queue/queue.ts +149 -63
  154. package/src/data-structures/stack/stack.ts +3 -18
  155. package/src/data-structures/trie/trie.ts +7 -3
  156. package/src/types/data-structures/base/base.ts +17 -8
  157. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
  158. package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
  159. package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
  160. package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
  161. package/src/types/data-structures/queue/deque.ts +2 -3
  162. package/src/types/data-structures/queue/queue.ts +2 -2
  163. package/test/integration/all-in-one.test.ts +1 -1
  164. package/test/integration/avl-tree.test.ts +1 -1
  165. package/test/integration/bst.test.ts +2 -2
  166. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +168 -0
  167. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +15 -14
  168. package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +1 -1
  169. package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +165 -7
  170. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +135 -27
  171. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +111 -11
  172. package/test/unit/data-structures/queue/deque.test.ts +241 -60
  173. package/test/unit/data-structures/queue/queue.test.ts +118 -19
  174. package/test/unit/unrestricted-interconversion.test.ts +1 -1
@@ -570,3 +570,171 @@ describe('AVLTreeMultiMap iterative methods not map mode', () => {
570
570
  expect(cloned.get(cloned.root?.right?.key)).toEqual(['c']);
571
571
  });
572
572
  });
573
+
574
+ describe('classic use', () => {
575
+ // Test suite for TreeMultiMap with player ranking and equipment
576
+ it('players ranked by score with their equipment', () => {
577
+ type Equipment = {
578
+ name: string; // Equipment name
579
+ quality: 'legendary' | 'epic' | 'rare' | 'common';
580
+ level: number;
581
+ };
582
+
583
+ type Player = {
584
+ name: string;
585
+ score: number;
586
+ equipments: Equipment[];
587
+ };
588
+
589
+ // Mock player data with their scores and equipment
590
+ const players: Player[] = [
591
+ {
592
+ name: 'DragonSlayer',
593
+ score: 8750,
594
+ equipments: [
595
+ { name: 'AWM', quality: 'legendary', level: 85 },
596
+ { name: 'Level 3 Helmet', quality: 'epic', level: 80 },
597
+ { name: 'Extended Quickdraw Mag', quality: 'rare', level: 75 },
598
+ { name: 'Compensator', quality: 'epic', level: 78 },
599
+ { name: 'Vertical Grip', quality: 'rare', level: 72 }
600
+ ]
601
+ },
602
+ {
603
+ name: 'ShadowNinja',
604
+ score: 7200,
605
+ equipments: [
606
+ { name: 'M416', quality: 'epic', level: 75 },
607
+ { name: 'Ghillie Suit', quality: 'rare', level: 70 },
608
+ { name: 'Red Dot Sight', quality: 'common', level: 65 },
609
+ { name: 'Extended QuickDraw Mag', quality: 'rare', level: 68 }
610
+ ]
611
+ },
612
+ {
613
+ name: 'RuneMaster',
614
+ score: 9100,
615
+ equipments: [
616
+ { name: 'KAR98K', quality: 'legendary', level: 90 },
617
+ { name: 'Level 3 Vest', quality: 'legendary', level: 85 },
618
+ { name: 'Holographic Sight', quality: 'epic', level: 82 },
619
+ { name: 'Suppressor', quality: 'legendary', level: 88 },
620
+ { name: 'Level 3 Backpack', quality: 'epic', level: 80 }
621
+ ]
622
+ },
623
+ {
624
+ name: 'BattleKing',
625
+ score: 8500,
626
+ equipments: [
627
+ { name: 'AUG', quality: 'epic', level: 82 },
628
+ { name: 'Red Dot Sight', quality: 'rare', level: 75 },
629
+ { name: 'Extended Mag', quality: 'common', level: 70 },
630
+ { name: 'Tactical Stock', quality: 'rare', level: 76 }
631
+ ]
632
+ },
633
+ {
634
+ name: 'SniperElite',
635
+ score: 7800,
636
+ equipments: [
637
+ { name: 'M24', quality: 'legendary', level: 88 },
638
+ { name: 'Compensator', quality: 'epic', level: 80 },
639
+ { name: 'Scope 8x', quality: 'legendary', level: 85 },
640
+ { name: 'Level 2 Helmet', quality: 'rare', level: 75 }
641
+ ]
642
+ },
643
+ {
644
+ name: 'RushMaster',
645
+ score: 7500,
646
+ equipments: [
647
+ { name: 'Vector', quality: 'rare', level: 72 },
648
+ { name: 'Level 2 Helmet', quality: 'common', level: 65 },
649
+ { name: 'Quickdraw Mag', quality: 'common', level: 60 },
650
+ { name: 'Laser Sight', quality: 'rare', level: 68 }
651
+ ]
652
+ },
653
+ {
654
+ name: 'GhostWarrior',
655
+ score: 8200,
656
+ equipments: [
657
+ { name: 'SCAR-L', quality: 'epic', level: 78 },
658
+ { name: 'Extended Quickdraw Mag', quality: 'rare', level: 70 },
659
+ { name: 'Holographic Sight', quality: 'epic', level: 75 },
660
+ { name: 'Suppressor', quality: 'rare', level: 72 },
661
+ { name: 'Vertical Grip', quality: 'common', level: 65 }
662
+ ]
663
+ },
664
+ {
665
+ name: 'DeathDealer',
666
+ score: 7300,
667
+ equipments: [
668
+ { name: 'SKS', quality: 'epic', level: 76 },
669
+ { name: 'Holographic Sight', quality: 'rare', level: 68 },
670
+ { name: 'Extended Mag', quality: 'common', level: 65 }
671
+ ]
672
+ },
673
+ {
674
+ name: 'StormRider',
675
+ score: 8900,
676
+ equipments: [
677
+ { name: 'MK14', quality: 'legendary', level: 92 },
678
+ { name: 'Level 3 Backpack', quality: 'legendary', level: 85 },
679
+ { name: 'Scope 8x', quality: 'epic', level: 80 },
680
+ { name: 'Suppressor', quality: 'legendary', level: 88 },
681
+ { name: 'Tactical Stock', quality: 'rare', level: 75 }
682
+ ]
683
+ },
684
+ {
685
+ name: 'CombatLegend',
686
+ score: 7600,
687
+ equipments: [
688
+ { name: 'UMP45', quality: 'rare', level: 74 },
689
+ { name: 'Level 2 Vest', quality: 'common', level: 67 },
690
+ { name: 'Red Dot Sight', quality: 'common', level: 62 },
691
+ { name: 'Extended Mag', quality: 'rare', level: 70 }
692
+ ]
693
+ }
694
+ ];
695
+
696
+ // Create a TreeMultiMap for player rankings
697
+ const playerRankings = new AVLTreeMultiMap<number, Equipment, Player>(players, {
698
+ toEntryFn: ({ score, equipments }) => [score, equipments],
699
+ isMapMode: false
700
+ });
701
+
702
+ const topPlayersEquipments = playerRankings.rangeSearch([8900, 10000], node => playerRankings.get(node));
703
+ expect(topPlayersEquipments).toEqual([
704
+ [
705
+ {
706
+ name: 'MK14',
707
+ quality: 'legendary',
708
+ level: 92
709
+ },
710
+ { name: 'Level 3 Backpack', quality: 'legendary', level: 85 },
711
+ {
712
+ name: 'Scope 8x',
713
+ quality: 'epic',
714
+ level: 80
715
+ },
716
+ { name: 'Suppressor', quality: 'legendary', level: 88 },
717
+ {
718
+ name: 'Tactical Stock',
719
+ quality: 'rare',
720
+ level: 75
721
+ }
722
+ ],
723
+ [
724
+ { name: 'KAR98K', quality: 'legendary', level: 90 },
725
+ {
726
+ name: 'Level 3 Vest',
727
+ quality: 'legendary',
728
+ level: 85
729
+ },
730
+ { name: 'Holographic Sight', quality: 'epic', level: 82 },
731
+ {
732
+ name: 'Suppressor',
733
+ quality: 'legendary',
734
+ level: 88
735
+ },
736
+ { name: 'Level 3 Backpack', quality: 'epic', level: 80 }
737
+ ]
738
+ ]);
739
+ });
740
+ });
@@ -1,4 +1,4 @@
1
- import { AVLTree, AVLTreeNode, BinaryTreeNode, BSTNode, Range } from '../../../../src';
1
+ import { AVLTree, AVLTreeNode, BinaryTreeNode, BSTNode } from '../../../../src';
2
2
 
3
3
  describe('AVL Tree Test', () => {
4
4
  it('should perform various operations on a AVL Tree', () => {
@@ -546,6 +546,7 @@ describe('AVLTree iterative methods not map mode', () => {
546
546
  describe('classic use', () => {
547
547
  // Test case for finding elements in a given range
548
548
  it('@example Find elements in a range', () => {
549
+ // In interval queries, AVL trees, with their strictly balanced structure and lower height, offer better query efficiency, making them ideal for frequent and high-performance interval queries. In contrast, Red-Black trees, with lower update costs, are more suitable for scenarios involving frequent insertions and deletions where the requirements for interval queries are less demanding.
549
550
  type Datum = { timestamp: Date; temperature: number };
550
551
  // Fixed dataset of CPU temperature readings
551
552
  const cpuData: Datum[] = [
@@ -594,18 +595,18 @@ describe('classic use', () => {
594
595
  temperature: cpuTemperatureTree.get(node ? node.key : undefined)
595
596
  }));
596
597
 
597
- expect(rangeResults).toEqual( [
598
- { minute: 5, temperature: 59.4 },
599
- { minute: 6, temperature: 60.1 },
600
- { minute: 7, temperature: 61.3 },
601
- { minute: 8, temperature: 62 },
602
- { minute: 9, temperature: 63.5 },
603
- { minute: 10, temperature: 64 },
604
- { minute: 11, temperature: 62.8 },
605
- { minute: 12, temperature: 61.5 },
606
- { minute: 13, temperature: 60.2 },
607
- { minute: 14, temperature: 59.8 },
608
- { minute: 15, temperature: 58.6 }
609
- ]);
598
+ expect(rangeResults).toEqual([
599
+ { minute: 5, temperature: 59.4 },
600
+ { minute: 6, temperature: 60.1 },
601
+ { minute: 7, temperature: 61.3 },
602
+ { minute: 8, temperature: 62 },
603
+ { minute: 9, temperature: 63.5 },
604
+ { minute: 10, temperature: 64 },
605
+ { minute: 11, temperature: 62.8 },
606
+ { minute: 12, temperature: 61.5 },
607
+ { minute: 13, temperature: 60.2 },
608
+ { minute: 14, temperature: 59.8 },
609
+ { minute: 15, temperature: 58.6 }
610
+ ]);
610
611
  });
611
612
  });
@@ -1,4 +1,4 @@
1
- import { BinaryTreeNode, BSTNode, Range, RedBlackTree, RedBlackTreeNode } from '../../../../src';
1
+ import { BinaryTreeNode, BSTNode, RedBlackTree, RedBlackTreeNode } from '../../../../src';
2
2
  import { getRandomInt, getRandomIntArray, magnitude } from '../../../utils';
3
3
  import { OrderedMap } from 'js-sdsl';
4
4
 
@@ -1,4 +1,4 @@
1
- import { BinaryTreeNode, BSTNode, Range, TreeMultiMap, TreeMultiMapNode } from '../../../../src';
1
+ import { BinaryTreeNode, BSTNode, TreeMultiMap, TreeMultiMapNode } from '../../../../src';
2
2
  import { getRandomInt } from '../../../utils';
3
3
 
4
4
  import { isDebugTest } from '../../../config';
@@ -837,11 +837,169 @@ describe('real world data', () => {
837
837
  });
838
838
 
839
839
  describe('classic use', () => {
840
- // Test case for finding elements in a given range
841
- it('@example Find elements in a range', () => {
842
- const tmm = new TreeMultiMap<number>([10, 5, 15, 3, 7, 12, 18]);
843
- expect(tmm.search(new Range(5, 10))).toEqual([5, 7, 10]);
844
- expect(tmm.search(new Range(4, 12))).toEqual([5, 7, 10, 12]);
845
- expect(tmm.search(new Range(15, 20))).toEqual([15, 18]);
840
+ // Test suite for TreeMultiMap with player ranking and equipment
841
+ it('@example players ranked by score with their equipment', () => {
842
+ type Equipment = {
843
+ name: string; // Equipment name
844
+ quality: 'legendary' | 'epic' | 'rare' | 'common';
845
+ level: number;
846
+ };
847
+
848
+ type Player = {
849
+ name: string;
850
+ score: number;
851
+ equipments: Equipment[];
852
+ };
853
+
854
+ // Mock player data with their scores and equipment
855
+ const players: Player[] = [
856
+ {
857
+ name: 'DragonSlayer',
858
+ score: 8750,
859
+ equipments: [
860
+ { name: 'AWM', quality: 'legendary', level: 85 },
861
+ { name: 'Level 3 Helmet', quality: 'epic', level: 80 },
862
+ { name: 'Extended Quickdraw Mag', quality: 'rare', level: 75 },
863
+ { name: 'Compensator', quality: 'epic', level: 78 },
864
+ { name: 'Vertical Grip', quality: 'rare', level: 72 }
865
+ ]
866
+ },
867
+ {
868
+ name: 'ShadowNinja',
869
+ score: 7200,
870
+ equipments: [
871
+ { name: 'M416', quality: 'epic', level: 75 },
872
+ { name: 'Ghillie Suit', quality: 'rare', level: 70 },
873
+ { name: 'Red Dot Sight', quality: 'common', level: 65 },
874
+ { name: 'Extended QuickDraw Mag', quality: 'rare', level: 68 }
875
+ ]
876
+ },
877
+ {
878
+ name: 'RuneMaster',
879
+ score: 9100,
880
+ equipments: [
881
+ { name: 'KAR98K', quality: 'legendary', level: 90 },
882
+ { name: 'Level 3 Vest', quality: 'legendary', level: 85 },
883
+ { name: 'Holographic Sight', quality: 'epic', level: 82 },
884
+ { name: 'Suppressor', quality: 'legendary', level: 88 },
885
+ { name: 'Level 3 Backpack', quality: 'epic', level: 80 }
886
+ ]
887
+ },
888
+ {
889
+ name: 'BattleKing',
890
+ score: 8500,
891
+ equipments: [
892
+ { name: 'AUG', quality: 'epic', level: 82 },
893
+ { name: 'Red Dot Sight', quality: 'rare', level: 75 },
894
+ { name: 'Extended Mag', quality: 'common', level: 70 },
895
+ { name: 'Tactical Stock', quality: 'rare', level: 76 }
896
+ ]
897
+ },
898
+ {
899
+ name: 'SniperElite',
900
+ score: 7800,
901
+ equipments: [
902
+ { name: 'M24', quality: 'legendary', level: 88 },
903
+ { name: 'Compensator', quality: 'epic', level: 80 },
904
+ { name: 'Scope 8x', quality: 'legendary', level: 85 },
905
+ { name: 'Level 2 Helmet', quality: 'rare', level: 75 }
906
+ ]
907
+ },
908
+ {
909
+ name: 'RushMaster',
910
+ score: 7500,
911
+ equipments: [
912
+ { name: 'Vector', quality: 'rare', level: 72 },
913
+ { name: 'Level 2 Helmet', quality: 'common', level: 65 },
914
+ { name: 'Quickdraw Mag', quality: 'common', level: 60 },
915
+ { name: 'Laser Sight', quality: 'rare', level: 68 }
916
+ ]
917
+ },
918
+ {
919
+ name: 'GhostWarrior',
920
+ score: 8200,
921
+ equipments: [
922
+ { name: 'SCAR-L', quality: 'epic', level: 78 },
923
+ { name: 'Extended Quickdraw Mag', quality: 'rare', level: 70 },
924
+ { name: 'Holographic Sight', quality: 'epic', level: 75 },
925
+ { name: 'Suppressor', quality: 'rare', level: 72 },
926
+ { name: 'Vertical Grip', quality: 'common', level: 65 }
927
+ ]
928
+ },
929
+ {
930
+ name: 'DeathDealer',
931
+ score: 7300,
932
+ equipments: [
933
+ { name: 'SKS', quality: 'epic', level: 76 },
934
+ { name: 'Holographic Sight', quality: 'rare', level: 68 },
935
+ { name: 'Extended Mag', quality: 'common', level: 65 }
936
+ ]
937
+ },
938
+ {
939
+ name: 'StormRider',
940
+ score: 8900,
941
+ equipments: [
942
+ { name: 'MK14', quality: 'legendary', level: 92 },
943
+ { name: 'Level 3 Backpack', quality: 'legendary', level: 85 },
944
+ { name: 'Scope 8x', quality: 'epic', level: 80 },
945
+ { name: 'Suppressor', quality: 'legendary', level: 88 },
946
+ { name: 'Tactical Stock', quality: 'rare', level: 75 }
947
+ ]
948
+ },
949
+ {
950
+ name: 'CombatLegend',
951
+ score: 7600,
952
+ equipments: [
953
+ { name: 'UMP45', quality: 'rare', level: 74 },
954
+ { name: 'Level 2 Vest', quality: 'common', level: 67 },
955
+ { name: 'Red Dot Sight', quality: 'common', level: 62 },
956
+ { name: 'Extended Mag', quality: 'rare', level: 70 }
957
+ ]
958
+ }
959
+ ];
960
+
961
+ // Create a TreeMultiMap for player rankings
962
+ const playerRankings = new TreeMultiMap<number, Equipment, Player>(players, {
963
+ toEntryFn: ({ score, equipments }) => [score, equipments],
964
+ isMapMode: false
965
+ });
966
+
967
+ const topPlayersEquipments = playerRankings.rangeSearch([8900, 10000], node => playerRankings.get(node));
968
+ expect(topPlayersEquipments).toEqual([
969
+ [
970
+ {
971
+ name: 'MK14',
972
+ quality: 'legendary',
973
+ level: 92
974
+ },
975
+ { name: 'Level 3 Backpack', quality: 'legendary', level: 85 },
976
+ {
977
+ name: 'Scope 8x',
978
+ quality: 'epic',
979
+ level: 80
980
+ },
981
+ { name: 'Suppressor', quality: 'legendary', level: 88 },
982
+ {
983
+ name: 'Tactical Stock',
984
+ quality: 'rare',
985
+ level: 75
986
+ }
987
+ ],
988
+ [
989
+ { name: 'KAR98K', quality: 'legendary', level: 90 },
990
+ {
991
+ name: 'Level 3 Vest',
992
+ quality: 'legendary',
993
+ level: 85
994
+ },
995
+ { name: 'Holographic Sight', quality: 'epic', level: 82 },
996
+ {
997
+ name: 'Suppressor',
998
+ quality: 'legendary',
999
+ level: 88
1000
+ },
1001
+ { name: 'Level 3 Backpack', quality: 'epic', level: 80 }
1002
+ ]
1003
+ ]);
846
1004
  });
847
1005
  });
@@ -32,14 +32,14 @@ describe('DoublyLinkedList Operation Test', () => {
32
32
  });
33
33
 
34
34
  it('should deleteAt', () => {
35
- expect(list.deleteAt(1)).toBe(true);
36
- expect(list.deleteAt(-1)).toBe(false);
37
- expect(list.deleteAt(list.size)).toBe(false);
38
- expect(list.size).toBe(4);
39
- expect(list.deleteAt(4)).toBe(false);
35
+ expect(list.deleteAt(1)).toBe(2);
36
+ expect(list.deleteAt(-1)).toBe(undefined);
37
+ expect(list.deleteAt(list.length)).toBe(undefined);
38
+ expect(list.length).toBe(4);
39
+ expect(list.deleteAt(4)).toBe(undefined);
40
40
  expect([...list]).toEqual([1, 3, 4, 5]);
41
41
  expect(list.isEmpty()).toBe(false);
42
- expect(list.deleteAt(3)).toBe(true);
42
+ expect(list.deleteAt(3)).toBe(5);
43
43
  expect([...list]).toEqual([1, 3, 4]);
44
44
  });
45
45
 
@@ -103,7 +103,7 @@ describe('DoublyLinkedList Operation Test', () => {
103
103
  });
104
104
 
105
105
  it('should initialize an empty list', () => {
106
- expect(list.size).toBe(0);
106
+ expect(list.length).toBe(0);
107
107
  expect(list.head).toBe(undefined);
108
108
  expect(list.tail).toBe(undefined);
109
109
  });
@@ -119,17 +119,36 @@ describe('DoublyLinkedList Operation Test', () => {
119
119
  list.push(1);
120
120
  list.push(2);
121
121
  list.push(3);
122
- expect(list.size).toBe(3);
122
+ expect(list.length).toBe(3);
123
123
  expect(list.head!.value).toBe(1);
124
124
  expect(list.tail!.value).toBe(3);
125
125
  });
126
126
 
127
+ it('push with maxLen', () => {
128
+ const list = new DoublyLinkedList<number>([], { maxLen: 10 });
129
+ for (let i = 0; i < 1000; i++) {
130
+ list.push(i);
131
+ }
132
+ expect(list.maxLen).toBe(10);
133
+ expect(list.length).toBe(10);
134
+ expect(list.first).toBe(990);
135
+
136
+ list.clear();
137
+ for (let i = 0; i < 1000; i++) {
138
+ list.unshift(i);
139
+ }
140
+
141
+ expect(list.maxLen).toBe(10);
142
+ expect(list.length).toBe(10);
143
+ expect(list.last).toBe(990);
144
+ });
145
+
127
146
  it('should pop elements from the end of the list', () => {
128
147
  list.push(1);
129
148
  list.push(2);
130
149
  const poppedValue = list.pop();
131
150
  expect(poppedValue).toBe(2);
132
- expect(list.size).toBe(1);
151
+ expect(list.length).toBe(1);
133
152
  expect(list.head!.value).toBe(1);
134
153
  expect(list.tail!.value).toBe(1);
135
154
  list.pop();
@@ -145,19 +164,19 @@ describe('DoublyLinkedList Operation Test', () => {
145
164
 
146
165
  // Inserting at the beginning
147
166
  list.addAt(0, 0);
148
- expect(list.size).toBe(4);
167
+ expect(list.length).toBe(4);
149
168
  expect(list.at(0)).toBe(0);
150
169
  expect(list.at(1)).toBe(1);
151
170
 
152
171
  // Inserting in the middle
153
172
  list.addAt(2, 1.5);
154
- expect(list.size).toBe(5);
173
+ expect(list.length).toBe(5);
155
174
  expect(list.at(2)).toBe(1.5);
156
175
  expect(list.at(3)).toBe(2);
157
176
 
158
177
  // Inserting at the end
159
178
  list.addAt(5, 4);
160
- expect(list.size).toBe(6);
179
+ expect(list.length).toBe(6);
161
180
  expect(list.at(5)).toBe(4);
162
181
  expect(list.tail!.value).toBe(4);
163
182
  expect(list.at(-1)).toBe(undefined);
@@ -171,18 +190,18 @@ describe('DoublyLinkedList Operation Test', () => {
171
190
 
172
191
  // Deleting from the beginning
173
192
  const deletedValue = list.deleteAt(0);
174
- expect(deletedValue).toBe(true);
175
- expect(list.size).toBe(2);
193
+ expect(deletedValue).toBe(1);
194
+ expect(list.length).toBe(2);
176
195
  expect(list.head!.value).toBe(2);
177
196
 
178
197
  // Deleting from the middle
179
198
  list.deleteAt(0); // Deleting the second element
180
- expect(list.size).toBe(1);
199
+ expect(list.length).toBe(1);
181
200
  expect(list.head!.value).toBe(3);
182
201
 
183
202
  // Deleting from the end
184
203
  list.deleteAt(0);
185
- expect(list.size).toBe(0);
204
+ expect(list.length).toBe(0);
186
205
  expect(list.head).toBe(undefined);
187
206
  expect(list.tail).toBe(undefined);
188
207
  });
@@ -193,16 +212,16 @@ describe('DoublyLinkedList Operation Test', () => {
193
212
  list.push(3);
194
213
 
195
214
  list.delete(2);
196
- expect(list.size).toBe(2);
215
+ expect(list.length).toBe(2);
197
216
  expect(list.head!.value).toBe(1);
198
217
  expect(list.tail!.value).toBe(3);
199
218
 
200
219
  list.delete(1);
201
- expect(list.size).toBe(1);
220
+ expect(list.length).toBe(1);
202
221
  expect(list.head!.value).toBe(3);
203
222
 
204
223
  list.delete(3);
205
- expect(list.size).toBe(0);
224
+ expect(list.length).toBe(0);
206
225
  expect(list.head).toBe(undefined);
207
226
  expect(list.tail).toBe(undefined);
208
227
  });
@@ -307,7 +326,7 @@ describe('DoublyLinkedList Operation Test', () => {
307
326
 
308
327
  list.clear();
309
328
 
310
- expect(list.size).toBe(0);
329
+ expect(list.length).toBe(0);
311
330
  expect(list.head).toBe(undefined);
312
331
  expect(list.tail).toBe(undefined);
313
332
  });
@@ -447,6 +466,95 @@ describe('DoublyLinkedList Operation Test', () => {
447
466
  });
448
467
  });
449
468
 
469
+ describe('DoublyLinkedList Additional Methods', () => {
470
+ // Slice method implementation and test
471
+ test('slice should return a new list with specified range', () => {
472
+ const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
473
+ const slicedList = list.slice(1, 4);
474
+
475
+ expect(slicedList.toArray()).toEqual([2, 3, 4]);
476
+ expect(list.length).toBe(5); // Original list unchanged
477
+ });
478
+
479
+ // Splice method implementation
480
+ test('splice should modify list and return removed elements', () => {
481
+ const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
482
+ const removedList = list.splice(2, 2, 6, 7);
483
+
484
+ expect(list.toArray()).toEqual([1, 2, 6, 7, 5]);
485
+ expect(removedList.toArray()).toEqual([3, 4]);
486
+ });
487
+
488
+ // Concat method test
489
+ test('concat should combine multiple lists', () => {
490
+ const list1 = new DoublyLinkedList([1, 2]);
491
+ const list2 = new DoublyLinkedList([3, 4]);
492
+ const list3 = new DoublyLinkedList([5, 6]);
493
+
494
+ const concatenatedList = list1.concat(list2, list3);
495
+ expect(concatenatedList.toArray()).toEqual([1, 2, 3, 4, 5, 6]);
496
+ });
497
+
498
+ // Sort method test
499
+ test('sort should order elements in ascending order', () => {
500
+ const list = new DoublyLinkedList([5, 2, 8, 1, 9]);
501
+ list.sort((a, b) => a - b);
502
+
503
+ expect(list.toArray()).toEqual([1, 2, 5, 8, 9]);
504
+ });
505
+
506
+ // Reverse method test
507
+ test('reverse should invert the list order', () => {
508
+ const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
509
+ list.reverse();
510
+
511
+ expect(list.toArray()).toEqual([5, 4, 3, 2, 1]);
512
+ });
513
+
514
+ // Join method test
515
+ test('join should convert list to string with separator', () => {
516
+ const list = new DoublyLinkedList(['a', 'b', 'c']);
517
+
518
+ expect(list.join('-')).toBe('a-b-c');
519
+ expect(list.join()).toBe('a,b,c');
520
+ });
521
+
522
+ // IndexOf method test
523
+ test('indexOf should return first occurrence index', () => {
524
+ const list = new DoublyLinkedList([1, 2, 3, 2, 1]);
525
+
526
+ expect(list.indexOf(2)).toBe(1);
527
+ expect(list.indexOf(4)).toBe(-1);
528
+ });
529
+
530
+ // LastIndexOf method test
531
+ test('lastIndexOf should return last occurrence index', () => {
532
+ const list = new DoublyLinkedList([1, 2, 3, 2, 1]);
533
+
534
+ expect(list.lastIndexOf(2)).toBe(3);
535
+ expect(list.lastIndexOf(4)).toBe(-1);
536
+ });
537
+
538
+ // findIndex method test
539
+ test('findIndex should return first occurrence index', () => {
540
+ const list = new DoublyLinkedList([1, 2, 3, 2, 1]);
541
+ expect(list.findIndex(item => item === 2)).toBe(1);
542
+ expect(list.findIndex(item => item === 4)).toBe(-1);
543
+ });
544
+
545
+ // fill method test
546
+ test('fill should return fill all the list', () => {
547
+ let list = new DoublyLinkedList([1, 2, 3, 2, 1]);
548
+ expect([...list.fill(9)]).toEqual([9, 9, 9, 9, 9]);
549
+ list = new DoublyLinkedList([1, 2, 3, 2, 1]);
550
+ expect([...list.fill(9, 2, 3)]).toEqual([1, 2, 9, 2, 1]);
551
+ list = new DoublyLinkedList([1, 2, 3, 2, 1]);
552
+ expect([...list.fill(9, -3, -2)]).toEqual([1, 2, 9, 2, 1]);
553
+ list = new DoublyLinkedList([1, 2, 3, 2, 1]);
554
+ expect([...list.fill(9, -2, -3)]).toEqual([1, 2, 3, 2, 1]);
555
+ });
556
+ });
557
+
450
558
  describe('iterable methods', () => {
451
559
  it('should forEach, some, every, filter, map, reduce of the deque', () => {
452
560
  const dl = new DoublyLinkedList<number>();
@@ -578,7 +686,7 @@ describe('classic use', () => {
578
686
  const initialNode = this.currentSong;
579
687
 
580
688
  // Loop through the playlist twice
581
- for (let i = 0; i < this.playlist.size * 2; i++) {
689
+ for (let i = 0; i < this.playlist.length * 2; i++) {
582
690
  playedSongs.push(this.currentSong!.value);
583
691
  this.currentSong = this.currentSong!.next || this.playlist.head; // Loop back to the start if needed
584
692
  }
@@ -700,7 +808,7 @@ describe('classic use', () => {
700
808
  }
701
809
 
702
810
  // Check capacity
703
- if (this.list.size >= this.capacity) {
811
+ if (this.list.length >= this.capacity) {
704
812
  // Delete the least recently used element (the tail of the linked list)
705
813
  const removedNode = this.list.tail;
706
814
  if (removedNode) {
@@ -745,9 +853,9 @@ describe('classic use', () => {
745
853
  this.map.clear();
746
854
  }
747
855
 
748
- // Get the current cache size
749
- get size(): number {
750
- return this.list.size;
856
+ // Get the current cache length
857
+ get length(): number {
858
+ return this.list.length;
751
859
  }
752
860
 
753
861
  // Check if it is empty
@@ -806,7 +914,7 @@ describe('classic use', () => {
806
914
 
807
915
  expect(cache.delete('a')).toBe(true);
808
916
  expect(cache.get('a')).toBeUndefined();
809
- expect(cache.size).toBe(1);
917
+ expect(cache.length).toBe(1);
810
918
 
811
919
  // Should support clearing cache
812
920
  cache.clear();
@@ -814,7 +922,7 @@ describe('classic use', () => {
814
922
  cache.set('b', 2);
815
923
  cache.clear();
816
924
 
817
- expect(cache.size).toBe(0);
925
+ expect(cache.length).toBe(0);
818
926
  expect(cache.isEmpty).toBe(true);
819
927
  });
820
928