min-heap-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 (67) hide show
  1. package/dist/data-structures/base/iterable-element-base.d.ts +14 -40
  2. package/dist/data-structures/base/iterable-element-base.js +14 -11
  3. package/dist/data-structures/base/linear-base.d.ts +277 -0
  4. package/dist/data-structures/base/linear-base.js +552 -0
  5. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
  6. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +50 -37
  7. package/dist/data-structures/binary-tree/avl-tree.d.ts +64 -0
  8. package/dist/data-structures/binary-tree/avl-tree.js +64 -0
  9. package/dist/data-structures/binary-tree/binary-tree.js +5 -5
  10. package/dist/data-structures/binary-tree/bst.js +11 -11
  11. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
  12. package/dist/data-structures/binary-tree/tree-multi-map.js +210 -40
  13. package/dist/data-structures/graph/abstract-graph.js +2 -2
  14. package/dist/data-structures/heap/heap.d.ts +3 -11
  15. package/dist/data-structures/heap/heap.js +0 -10
  16. package/dist/data-structures/heap/max-heap.d.ts +2 -2
  17. package/dist/data-structures/heap/min-heap.d.ts +2 -2
  18. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
  19. package/dist/data-structures/linked-list/doubly-linked-list.js +131 -146
  20. package/dist/data-structures/linked-list/singly-linked-list.d.ts +79 -75
  21. package/dist/data-structures/linked-list/singly-linked-list.js +217 -169
  22. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
  23. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
  24. package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -2
  25. package/dist/data-structures/queue/deque.d.ts +130 -91
  26. package/dist/data-structures/queue/deque.js +269 -169
  27. package/dist/data-structures/queue/queue.d.ts +84 -40
  28. package/dist/data-structures/queue/queue.js +134 -50
  29. package/dist/data-structures/stack/stack.d.ts +3 -11
  30. package/dist/data-structures/stack/stack.js +0 -10
  31. package/dist/data-structures/trie/trie.d.ts +4 -3
  32. package/dist/data-structures/trie/trie.js +3 -0
  33. package/dist/types/data-structures/base/base.d.ts +9 -4
  34. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
  35. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  36. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
  37. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
  38. package/dist/types/data-structures/queue/deque.d.ts +2 -3
  39. package/dist/types/data-structures/queue/queue.d.ts +2 -2
  40. package/package.json +2 -2
  41. package/src/data-structures/base/iterable-element-base.ts +29 -20
  42. package/src/data-structures/base/linear-base.ts +649 -0
  43. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +51 -36
  44. package/src/data-structures/binary-tree/avl-tree.ts +64 -0
  45. package/src/data-structures/binary-tree/binary-tree.ts +5 -5
  46. package/src/data-structures/binary-tree/bst.ts +9 -9
  47. package/src/data-structures/binary-tree/tree-multi-map.ts +214 -40
  48. package/src/data-structures/graph/abstract-graph.ts +2 -2
  49. package/src/data-structures/heap/heap.ts +3 -14
  50. package/src/data-structures/heap/max-heap.ts +2 -2
  51. package/src/data-structures/heap/min-heap.ts +2 -2
  52. package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
  53. package/src/data-structures/linked-list/singly-linked-list.ts +241 -185
  54. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
  55. package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
  56. package/src/data-structures/priority-queue/priority-queue.ts +2 -2
  57. package/src/data-structures/queue/deque.ts +286 -183
  58. package/src/data-structures/queue/queue.ts +149 -63
  59. package/src/data-structures/stack/stack.ts +3 -18
  60. package/src/data-structures/trie/trie.ts +7 -3
  61. package/src/types/data-structures/base/base.ts +17 -8
  62. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
  63. package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
  64. package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
  65. package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
  66. package/src/types/data-structures/queue/deque.ts +2 -3
  67. package/src/types/data-structures/queue/queue.ts +2 -2
@@ -100,6 +100,7 @@ export class AVLTreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, M
100
100
  specifyComparable: this._specifyComparable,
101
101
  toEntryFn: this._toEntryFn,
102
102
  isReverse: this._isReverse,
103
+ isMapMode: this._isMapMode,
103
104
  ...options
104
105
  });
105
106
  }
@@ -108,19 +109,23 @@ export class AVLTreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, M
108
109
  * Time Complexity: O(1)
109
110
  * Space Complexity: O(1)
110
111
  *
111
- * The function `createNode` overrides the method to create a new AVLTreeMultiMapNode with a
112
- * specified key and an empty array of values.
113
- * @param {K} key - The `key` parameter in the `createNode` method represents the key of the node
114
- * that will be created in the AVLTreeMultiMap.
115
- * @returns An AVLTreeMultiMapNode object is being returned, initialized with the provided key and an
116
- * empty array.
112
+ * The `createNode` function in TypeScript overrides the default implementation to create a new
113
+ * AVLTreeMultiMapNode with a specified key and value array.
114
+ * @param {K} key - The `key` parameter represents the key of the node being created in the
115
+ * AVLTreeMultiMap.
116
+ * @param {V[]} value - The `value` parameter in the `createNode` method represents an array of
117
+ * values associated with a specific key in the AVLTreeMultiMapNode. If no value is provided when
118
+ * calling the method, an empty array `[]` is used as the default value.
119
+ * @returns An AVLTreeMultiMapNode object is being returned, with the specified key and value. If the
120
+ * AVLTreeMultiMap is in map mode, an empty array is used as the value, otherwise the provided value
121
+ * array is used.
117
122
  */
118
- override createNode(key: K): AVLTreeMultiMapNode<K, V> {
119
- return new AVLTreeMultiMapNode<K, V>(key, []);
123
+ override createNode(key: K, value: V[] = []): AVLTreeMultiMapNode<K, V> {
124
+ return new AVLTreeMultiMapNode<K, V>(key, this._isMapMode ? [] : value);
120
125
  }
121
126
 
122
127
  override add(
123
- node: K | AVLTreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined
128
+ keyNodeOrEntry: K | AVLTreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined
124
129
  ): boolean;
125
130
 
126
131
  override add(key: K, value: V): boolean;
@@ -129,17 +134,16 @@ export class AVLTreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, M
129
134
  * Time Complexity: O(log n)
130
135
  * Space Complexity: O(log n)
131
136
  *
132
- * The function `add` in TypeScript overrides the superclass method to add key-value pairs to an AVL
133
- * tree multi-map.
134
- * @param {K | AVLTreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined | K} keyNodeOrEntry - The `keyNodeOrEntry`
135
- * parameter in the `override add` method can be either a key-value pair entry or just a key. If it
136
- * is a key-value pair entry, it will be in the format `[key, values]`, where `key` is the key and
137
- * `values`
138
- * @param {V} [value] - The `value` parameter in the `override add` method represents the value that
139
- * you want to add to the AVLTreeMultiMap. It can be a single value or an array of values associated
140
- * with a specific key.
141
- * @returns The `override add` method is returning a boolean value, which indicates whether the
142
- * addition operation was successful or not.
137
+ * The function `add` in this TypeScript code overrides the superclass method to add key-value pairs
138
+ * to an AVLTreeMultiMap, handling different input types and scenarios.
139
+ * @param [key] - The `key` parameter in the `override add` method represents the key of the entry to
140
+ * be added to the AVLTreeMultiMap. It can be of type `K`, which is the key type of the map. The key
141
+ * can be a single key value, a node of the AVLTree
142
+ * @param {V[]} [values] - The `values` parameter in the `add` method represents an array of values
143
+ * that you want to add to the AVLTreeMultiMap. It can contain one or more values associated with a
144
+ * specific key.
145
+ * @returns The `add` method is returning a boolean value, which indicates whether the operation was
146
+ * successful or not.
143
147
  */
144
148
  override add(
145
149
  keyNodeOrEntry: K | AVLTreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined | K,
@@ -150,27 +154,38 @@ export class AVLTreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, M
150
154
  const _commonAdd = (key?: BTNOptKeyOrNull<K>, values?: V[]) => {
151
155
  if (key === undefined || key === null) return false;
152
156
 
153
- const existingValues = this.get(key);
154
- if (existingValues !== undefined && values !== undefined) {
155
- for (const value of values) existingValues.push(value);
156
- return true;
157
- }
158
-
159
- const existingNode = this.getNode(key);
160
- if (this.isRealNode(existingNode)) {
161
- if (existingValues === undefined) {
162
- super.add(key, values);
163
- return true;
164
- }
165
- if (values !== undefined) {
157
+ const _addToValues = () => {
158
+ const existingValues = this.get(key);
159
+ if (existingValues !== undefined && values !== undefined) {
166
160
  for (const value of values) existingValues.push(value);
167
161
  return true;
162
+ }
163
+ return false;
164
+ };
165
+
166
+ const _addByNode = () => {
167
+ const existingNode = this.getNode(key);
168
+ if (this.isRealNode(existingNode)) {
169
+ const existingValues = this.get(existingNode);
170
+ if (existingValues === undefined) {
171
+ super.add(key, values);
172
+ return true;
173
+ }
174
+ if (values !== undefined) {
175
+ for (const value of values) existingValues.push(value);
176
+ return true;
177
+ } else {
178
+ return false;
179
+ }
168
180
  } else {
169
- return false;
181
+ return super.add(key, values);
170
182
  }
171
- } else {
172
- return super.add(key, values);
183
+ };
184
+
185
+ if (this._isMapMode) {
186
+ return _addByNode() || _addToValues();
173
187
  }
188
+ return _addToValues() || _addByNode();
174
189
  };
175
190
 
176
191
  if (this.isEntry(keyNodeOrEntry)) {
@@ -60,6 +60,70 @@ export class AVLTreeNode<K = any, V = any> extends BSTNode<K, V> {
60
60
  * 5. Efficient Lookups: Offers O(log n) search time, where 'n' is the number of nodes, due to its balanced nature.
61
61
  * 6. Complex Insertions and Deletions: Due to rebalancing, these operations are more complex than in a regular BST.
62
62
  * 7. Path Length: The path length from the root to any leaf is longer compared to an unbalanced BST, but shorter than a linear chain of nodes.
63
+ * @example
64
+ * // Find elements in a range
65
+ * // 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.
66
+ * type Datum = { timestamp: Date; temperature: number };
67
+ * // Fixed dataset of CPU temperature readings
68
+ * const cpuData: Datum[] = [
69
+ * { timestamp: new Date('2024-12-02T00:00:00'), temperature: 55.1 },
70
+ * { timestamp: new Date('2024-12-02T00:01:00'), temperature: 56.3 },
71
+ * { timestamp: new Date('2024-12-02T00:02:00'), temperature: 54.8 },
72
+ * { timestamp: new Date('2024-12-02T00:03:00'), temperature: 57.2 },
73
+ * { timestamp: new Date('2024-12-02T00:04:00'), temperature: 58.0 },
74
+ * { timestamp: new Date('2024-12-02T00:05:00'), temperature: 59.4 },
75
+ * { timestamp: new Date('2024-12-02T00:06:00'), temperature: 60.1 },
76
+ * { timestamp: new Date('2024-12-02T00:07:00'), temperature: 61.3 },
77
+ * { timestamp: new Date('2024-12-02T00:08:00'), temperature: 62.0 },
78
+ * { timestamp: new Date('2024-12-02T00:09:00'), temperature: 63.5 },
79
+ * { timestamp: new Date('2024-12-02T00:10:00'), temperature: 64.0 },
80
+ * { timestamp: new Date('2024-12-02T00:11:00'), temperature: 62.8 },
81
+ * { timestamp: new Date('2024-12-02T00:12:00'), temperature: 61.5 },
82
+ * { timestamp: new Date('2024-12-02T00:13:00'), temperature: 60.2 },
83
+ * { timestamp: new Date('2024-12-02T00:14:00'), temperature: 59.8 },
84
+ * { timestamp: new Date('2024-12-02T00:15:00'), temperature: 58.6 },
85
+ * { timestamp: new Date('2024-12-02T00:16:00'), temperature: 57.4 },
86
+ * { timestamp: new Date('2024-12-02T00:17:00'), temperature: 56.2 },
87
+ * { timestamp: new Date('2024-12-02T00:18:00'), temperature: 55.7 },
88
+ * { timestamp: new Date('2024-12-02T00:19:00'), temperature: 54.5 },
89
+ * { timestamp: new Date('2024-12-02T00:20:00'), temperature: 53.2 },
90
+ * { timestamp: new Date('2024-12-02T00:21:00'), temperature: 52.8 },
91
+ * { timestamp: new Date('2024-12-02T00:22:00'), temperature: 51.9 },
92
+ * { timestamp: new Date('2024-12-02T00:23:00'), temperature: 50.5 },
93
+ * { timestamp: new Date('2024-12-02T00:24:00'), temperature: 49.8 },
94
+ * { timestamp: new Date('2024-12-02T00:25:00'), temperature: 48.7 },
95
+ * { timestamp: new Date('2024-12-02T00:26:00'), temperature: 47.5 },
96
+ * { timestamp: new Date('2024-12-02T00:27:00'), temperature: 46.3 },
97
+ * { timestamp: new Date('2024-12-02T00:28:00'), temperature: 45.9 },
98
+ * { timestamp: new Date('2024-12-02T00:29:00'), temperature: 45.0 }
99
+ * ];
100
+ *
101
+ * // Create an AVL tree to store CPU temperature data
102
+ * const cpuTemperatureTree = new AVLTree<Date, number, Datum>(cpuData, {
103
+ * toEntryFn: ({ timestamp, temperature }) => [timestamp, temperature]
104
+ * });
105
+ *
106
+ * // Query a specific time range (e.g., from 00:05 to 00:15)
107
+ * const rangeStart = new Date('2024-12-02T00:05:00');
108
+ * const rangeEnd = new Date('2024-12-02T00:15:00');
109
+ * const rangeResults = cpuTemperatureTree.rangeSearch([rangeStart, rangeEnd], node => ({
110
+ * minute: node ? node.key.getMinutes() : 0,
111
+ * temperature: cpuTemperatureTree.get(node ? node.key : undefined)
112
+ * }));
113
+ *
114
+ * console.log(rangeResults); // [
115
+ * // { minute: 5, temperature: 59.4 },
116
+ * // { minute: 6, temperature: 60.1 },
117
+ * // { minute: 7, temperature: 61.3 },
118
+ * // { minute: 8, temperature: 62 },
119
+ * // { minute: 9, temperature: 63.5 },
120
+ * // { minute: 10, temperature: 64 },
121
+ * // { minute: 11, temperature: 62.8 },
122
+ * // { minute: 12, temperature: 61.5 },
123
+ * // { minute: 13, temperature: 60.2 },
124
+ * // { minute: 14, temperature: 59.8 },
125
+ * // { minute: 15, temperature: 58.6 }
126
+ * // ]
63
127
  */
64
128
  export class AVLTree<K = any, V = any, R = object, MK = any, MV = any, MR = object>
65
129
  extends BST<K, V, R, MK, MV, MR>
@@ -544,7 +544,7 @@ export class BinaryTree<K = any, V = any, R = object, MK = any, MV = any, MR = o
544
544
  const queue = new Queue<BinaryTreeNode<K, V>>([this._root]);
545
545
  let potentialParent: BinaryTreeNode<K, V> | undefined; // Record the parent node of the potential insertion location
546
546
 
547
- while (queue.size > 0) {
547
+ while (queue.length > 0) {
548
548
  const cur = queue.shift();
549
549
 
550
550
  if (!cur) continue;
@@ -1530,7 +1530,7 @@ export class BinaryTree<K = any, V = any, R = object, MK = any, MV = any, MR = o
1530
1530
  ]);
1531
1531
 
1532
1532
  const dfs = (level: number) => {
1533
- if (queue.size === 0) return;
1533
+ if (queue.length === 0) return;
1534
1534
 
1535
1535
  const current = queue.shift()!;
1536
1536
  ans.push(callback(current));
@@ -1549,8 +1549,8 @@ export class BinaryTree<K = any, V = any, R = object, MK = any, MV = any, MR = o
1549
1549
  dfs(0);
1550
1550
  } else {
1551
1551
  const queue = new Queue<OptNodeOrNull<BinaryTreeNode<K, V>>>([startNode]);
1552
- while (queue.size > 0) {
1553
- const levelSize = queue.size;
1552
+ while (queue.length > 0) {
1553
+ const levelSize = queue.length;
1554
1554
 
1555
1555
  for (let i = 0; i < levelSize; i++) {
1556
1556
  const current = queue.shift()!;
@@ -1609,7 +1609,7 @@ export class BinaryTree<K = any, V = any, R = object, MK = any, MV = any, MR = o
1609
1609
  dfs(startNode);
1610
1610
  } else {
1611
1611
  const queue = new Queue([startNode]);
1612
- while (queue.size > 0) {
1612
+ while (queue.length > 0) {
1613
1613
  const cur = queue.shift();
1614
1614
  if (this.isRealNode(cur)) {
1615
1615
  if (this.isLeaf(cur)) {
@@ -441,14 +441,14 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
441
441
  if (arr.length === 0) return;
442
442
 
443
443
  const mid = Math.floor((arr.length - 1) / 2);
444
- let { key, value } = arr[mid];
444
+ const { key, value } = arr[mid];
445
445
  const { orgIndex } = arr[mid];
446
446
  if (this.isRaw(key)) {
447
447
  const entry = this._toEntryFn!(key);
448
- key = entry[0];
449
- value = entry[1] ?? value;
448
+ inserted[orgIndex] = this.add(entry);
449
+ } else {
450
+ inserted[orgIndex] = this.add(key, value);
450
451
  }
451
- inserted[orgIndex] = this.add(key, value);
452
452
  _dfs(arr.slice(0, mid));
453
453
  _dfs(arr.slice(mid + 1));
454
454
  };
@@ -462,14 +462,14 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
462
462
  const [l, r] = popped;
463
463
  if (l <= r) {
464
464
  const m = l + Math.floor((r - l) / 2);
465
- let { key, value } = sorted[m];
465
+ const { key, value } = sorted[m];
466
466
  const { orgIndex } = sorted[m];
467
467
  if (this.isRaw(key)) {
468
468
  const entry = this._toEntryFn!(key);
469
- key = entry[0];
470
- value = entry[1] ?? value;
469
+ inserted[orgIndex] = this.add(entry);
470
+ } else {
471
+ inserted[orgIndex] = this.add(key, value);
471
472
  }
472
- inserted[orgIndex] = this.add(key, value);
473
473
  stack.push([m + 1, r]);
474
474
  stack.push([l, m - 1]);
475
475
  }
@@ -792,7 +792,7 @@ export class BST<K = any, V = any, R = object, MK = any, MV = any, MR = object>
792
792
  return ans;
793
793
  } else {
794
794
  const queue = new Queue<BSTNode<K, V>>([this._root]);
795
- while (queue.size > 0) {
795
+ while (queue.length > 0) {
796
796
  const cur = queue.shift();
797
797
  if (this.isRealNode(cur)) {
798
798
  const compared = this._compare(cur.key, targetKey);
@@ -21,7 +21,7 @@ export class TreeMultiMapNode<K = any, V = any> extends RedBlackTreeNode<K, V[]>
21
21
  * @param {V[]} value - The `value` parameter in the constructor represents an array of values of
22
22
  * type `V`.
23
23
  */
24
- constructor(key: K, value: V[]) {
24
+ constructor(key: K, value?: V[]) {
25
25
  super(key, value);
26
26
  }
27
27
 
@@ -55,11 +55,169 @@ export class TreeMultiMapNode<K = any, V = any> extends RedBlackTreeNode<K, V[]>
55
55
  /**
56
56
  *
57
57
  * @example
58
- * // Find elements in a range
59
- * const tmm = new TreeMultiMap<number>([10, 5, 15, 3, 7, 12, 18]);
60
- * console.log(tmm.search(new Range(5, 10))); // [5, 7, 10]
61
- * console.log(tmm.search(new Range(4, 12))); // [5, 7, 10, 12]
62
- * console.log(tmm.search(new Range(15, 20))); // [15, 18]
58
+ * // players ranked by score with their equipment
59
+ * type Equipment = {
60
+ * name: string; // Equipment name
61
+ * quality: 'legendary' | 'epic' | 'rare' | 'common';
62
+ * level: number;
63
+ * };
64
+ *
65
+ * type Player = {
66
+ * name: string;
67
+ * score: number;
68
+ * equipments: Equipment[];
69
+ * };
70
+ *
71
+ * // Mock player data with their scores and equipment
72
+ * const players: Player[] = [
73
+ * {
74
+ * name: 'DragonSlayer',
75
+ * score: 8750,
76
+ * equipments: [
77
+ * { name: 'AWM', quality: 'legendary', level: 85 },
78
+ * { name: 'Level 3 Helmet', quality: 'epic', level: 80 },
79
+ * { name: 'Extended Quickdraw Mag', quality: 'rare', level: 75 },
80
+ * { name: 'Compensator', quality: 'epic', level: 78 },
81
+ * { name: 'Vertical Grip', quality: 'rare', level: 72 }
82
+ * ]
83
+ * },
84
+ * {
85
+ * name: 'ShadowNinja',
86
+ * score: 7200,
87
+ * equipments: [
88
+ * { name: 'M416', quality: 'epic', level: 75 },
89
+ * { name: 'Ghillie Suit', quality: 'rare', level: 70 },
90
+ * { name: 'Red Dot Sight', quality: 'common', level: 65 },
91
+ * { name: 'Extended QuickDraw Mag', quality: 'rare', level: 68 }
92
+ * ]
93
+ * },
94
+ * {
95
+ * name: 'RuneMaster',
96
+ * score: 9100,
97
+ * equipments: [
98
+ * { name: 'KAR98K', quality: 'legendary', level: 90 },
99
+ * { name: 'Level 3 Vest', quality: 'legendary', level: 85 },
100
+ * { name: 'Holographic Sight', quality: 'epic', level: 82 },
101
+ * { name: 'Suppressor', quality: 'legendary', level: 88 },
102
+ * { name: 'Level 3 Backpack', quality: 'epic', level: 80 }
103
+ * ]
104
+ * },
105
+ * {
106
+ * name: 'BattleKing',
107
+ * score: 8500,
108
+ * equipments: [
109
+ * { name: 'AUG', quality: 'epic', level: 82 },
110
+ * { name: 'Red Dot Sight', quality: 'rare', level: 75 },
111
+ * { name: 'Extended Mag', quality: 'common', level: 70 },
112
+ * { name: 'Tactical Stock', quality: 'rare', level: 76 }
113
+ * ]
114
+ * },
115
+ * {
116
+ * name: 'SniperElite',
117
+ * score: 7800,
118
+ * equipments: [
119
+ * { name: 'M24', quality: 'legendary', level: 88 },
120
+ * { name: 'Compensator', quality: 'epic', level: 80 },
121
+ * { name: 'Scope 8x', quality: 'legendary', level: 85 },
122
+ * { name: 'Level 2 Helmet', quality: 'rare', level: 75 }
123
+ * ]
124
+ * },
125
+ * {
126
+ * name: 'RushMaster',
127
+ * score: 7500,
128
+ * equipments: [
129
+ * { name: 'Vector', quality: 'rare', level: 72 },
130
+ * { name: 'Level 2 Helmet', quality: 'common', level: 65 },
131
+ * { name: 'Quickdraw Mag', quality: 'common', level: 60 },
132
+ * { name: 'Laser Sight', quality: 'rare', level: 68 }
133
+ * ]
134
+ * },
135
+ * {
136
+ * name: 'GhostWarrior',
137
+ * score: 8200,
138
+ * equipments: [
139
+ * { name: 'SCAR-L', quality: 'epic', level: 78 },
140
+ * { name: 'Extended Quickdraw Mag', quality: 'rare', level: 70 },
141
+ * { name: 'Holographic Sight', quality: 'epic', level: 75 },
142
+ * { name: 'Suppressor', quality: 'rare', level: 72 },
143
+ * { name: 'Vertical Grip', quality: 'common', level: 65 }
144
+ * ]
145
+ * },
146
+ * {
147
+ * name: 'DeathDealer',
148
+ * score: 7300,
149
+ * equipments: [
150
+ * { name: 'SKS', quality: 'epic', level: 76 },
151
+ * { name: 'Holographic Sight', quality: 'rare', level: 68 },
152
+ * { name: 'Extended Mag', quality: 'common', level: 65 }
153
+ * ]
154
+ * },
155
+ * {
156
+ * name: 'StormRider',
157
+ * score: 8900,
158
+ * equipments: [
159
+ * { name: 'MK14', quality: 'legendary', level: 92 },
160
+ * { name: 'Level 3 Backpack', quality: 'legendary', level: 85 },
161
+ * { name: 'Scope 8x', quality: 'epic', level: 80 },
162
+ * { name: 'Suppressor', quality: 'legendary', level: 88 },
163
+ * { name: 'Tactical Stock', quality: 'rare', level: 75 }
164
+ * ]
165
+ * },
166
+ * {
167
+ * name: 'CombatLegend',
168
+ * score: 7600,
169
+ * equipments: [
170
+ * { name: 'UMP45', quality: 'rare', level: 74 },
171
+ * { name: 'Level 2 Vest', quality: 'common', level: 67 },
172
+ * { name: 'Red Dot Sight', quality: 'common', level: 62 },
173
+ * { name: 'Extended Mag', quality: 'rare', level: 70 }
174
+ * ]
175
+ * }
176
+ * ];
177
+ *
178
+ * // Create a TreeMultiMap for player rankings
179
+ * const playerRankings = new TreeMultiMap<number, Equipment, Player>(players, {
180
+ * toEntryFn: ({ score, equipments }) => [score, equipments],
181
+ * isMapMode: false
182
+ * });
183
+ *
184
+ * const topPlayersEquipments = playerRankings.rangeSearch([8900, 10000], node => playerRankings.get(node));
185
+ * console.log(topPlayersEquipments); // [
186
+ * // [
187
+ * // {
188
+ * // name: 'MK14',
189
+ * // quality: 'legendary',
190
+ * // level: 92
191
+ * // },
192
+ * // { name: 'Level 3 Backpack', quality: 'legendary', level: 85 },
193
+ * // {
194
+ * // name: 'Scope 8x',
195
+ * // quality: 'epic',
196
+ * // level: 80
197
+ * // },
198
+ * // { name: 'Suppressor', quality: 'legendary', level: 88 },
199
+ * // {
200
+ * // name: 'Tactical Stock',
201
+ * // quality: 'rare',
202
+ * // level: 75
203
+ * // }
204
+ * // ],
205
+ * // [
206
+ * // { name: 'KAR98K', quality: 'legendary', level: 90 },
207
+ * // {
208
+ * // name: 'Level 3 Vest',
209
+ * // quality: 'legendary',
210
+ * // level: 85
211
+ * // },
212
+ * // { name: 'Holographic Sight', quality: 'epic', level: 82 },
213
+ * // {
214
+ * // name: 'Suppressor',
215
+ * // quality: 'legendary',
216
+ * // level: 88
217
+ * // },
218
+ * // { name: 'Level 3 Backpack', quality: 'epic', level: 80 }
219
+ * // ]
220
+ * // ]
63
221
  */
64
222
  export class TreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, MR = object>
65
223
  extends RedBlackTree<K, V[], R, MK, MV[], MR>
@@ -82,7 +240,7 @@ export class TreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, MR =
82
240
  > = [],
83
241
  options?: TreeMultiMapOptions<K, V[], R>
84
242
  ) {
85
- super([], { ...options, isMapMode: true });
243
+ super([], { ...options });
86
244
  if (keysNodesEntriesOrRaws) {
87
245
  this.addMany(keysNodesEntriesOrRaws);
88
246
  }
@@ -107,6 +265,7 @@ export class TreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, MR =
107
265
  specifyComparable: this._specifyComparable,
108
266
  toEntryFn: this._toEntryFn,
109
267
  isReverse: this._isReverse,
268
+ isMapMode: this._isMapMode,
110
269
  ...options
111
270
  });
112
271
  }
@@ -115,18 +274,23 @@ export class TreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, MR =
115
274
  * Time Complexity: O(1)
116
275
  * Space Complexity: O(1)
117
276
  *
118
- * The function `createNode` overrides the method to create a new `TreeMultiMapNode` with a specified
119
- * key and an empty array of values.
120
- * @param {K} key - The `key` parameter in the `createNode` method represents the key of the node
121
- * that will be created in the TreeMultiMap data structure.
122
- * @returns A new instance of `TreeMultiMapNode<K, V>` is being returned, with the specified key and
123
- * an empty array as its value.
277
+ * The function `createNode` overrides the creation of a new TreeMultiMapNode with a specified key
278
+ * and value array.
279
+ * @param {K} key - The `key` parameter represents the key of the node being created in the
280
+ * `TreeMultiMap`.
281
+ * @param {V[]} value - The `value` parameter in the `createNode` method represents an array of
282
+ * values associated with a specific key in the TreeMultiMap data structure.
283
+ * @returns A new instance of `TreeMultiMapNode<K, V>` is being returned with the specified key and
284
+ * value. If `_isMapMode` is true, an empty array is passed as the value, otherwise the provided
285
+ * value is used.
124
286
  */
125
- override createNode(key: K): TreeMultiMapNode<K, V> {
126
- return new TreeMultiMapNode<K, V>(key, []);
287
+ override createNode(key: K, value: V[] = []): TreeMultiMapNode<K, V> {
288
+ return new TreeMultiMapNode<K, V>(key, this._isMapMode ? [] : value);
127
289
  }
128
290
 
129
- override add(node: K | TreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined): boolean;
291
+ override add(
292
+ keyNodeOrEntry: K | TreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined
293
+ ): boolean;
130
294
 
131
295
  override add(key: K, value: V): boolean;
132
296
 
@@ -134,14 +298,13 @@ export class TreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, MR =
134
298
  * Time Complexity: O(log n)
135
299
  * Space Complexity: O(log n)
136
300
  *
137
- * The function `add` in TypeScript overrides the superclass method to add key-value pairs to a
138
- * TreeMultiMapNode, handling different input types and scenarios.
139
- * @param {K | TreeMultiMapNode<K, V> | [K | null | undefined, V[] | undefined] | null | undefined} keyNodeOrEntry - The `keyNodeOrEntry`
140
- * parameter in the `override add` method can be either a `BTNRep` object containing a key, an array
141
- * of values, and a `TreeMultiMapNode`, or just a key.
142
- * @param {V} [value] - The `value` parameter in the `override add` method represents the value that
143
- * you want to add to the TreeMultiMap. If the key is already present in the map, the new value will
144
- * be added to the existing list of values associated with that key. If the key is not present,
301
+ * The function overrides the add method to handle different types of input for a TreeMultiMap data
302
+ * structure.
303
+ * @param [key] - The `key` parameter in the `override add` method represents the key of the entry to
304
+ * be added to the TreeMultiMap. It can be of type `K`, which is the key type of the TreeMultiMap, or
305
+ * it can be a TreeMultiMapNode containing the key and its
306
+ * @param {V[]} [values] - The `values` parameter in the `add` method represents an array of values
307
+ * that you want to add to the TreeMultiMap. It can contain one or more values of type `V`.
145
308
  * @returns The `add` method is returning a boolean value, which indicates whether the operation was
146
309
  * successful or not.
147
310
  */
@@ -154,27 +317,38 @@ export class TreeMultiMap<K = any, V = any, R = object, MK = any, MV = any, MR =
154
317
  const _commonAdd = (key?: BTNOptKeyOrNull<K>, values?: V[]) => {
155
318
  if (key === undefined || key === null) return false;
156
319
 
157
- const existingValues = this.get(key);
158
- if (existingValues !== undefined && values !== undefined) {
159
- for (const value of values) existingValues.push(value);
160
- return true;
161
- }
162
-
163
- const existingNode = this.getNode(key);
164
- if (this.isRealNode(existingNode)) {
165
- if (existingValues === undefined) {
166
- super.add(key, values);
167
- return true;
168
- }
169
- if (values !== undefined) {
320
+ const _addToValues = () => {
321
+ const existingValues = this.get(key);
322
+ if (existingValues !== undefined && values !== undefined) {
170
323
  for (const value of values) existingValues.push(value);
171
324
  return true;
325
+ }
326
+ return false;
327
+ };
328
+
329
+ const _addByNode = () => {
330
+ const existingNode = this.getNode(key);
331
+ if (this.isRealNode(existingNode)) {
332
+ const existingValues = this.get(existingNode);
333
+ if (existingValues === undefined) {
334
+ super.add(key, values);
335
+ return true;
336
+ }
337
+ if (values !== undefined) {
338
+ for (const value of values) existingValues.push(value);
339
+ return true;
340
+ } else {
341
+ return false;
342
+ }
172
343
  } else {
173
- return false;
344
+ return super.add(key, values);
174
345
  }
175
- } else {
176
- return super.add(key, values);
346
+ };
347
+
348
+ if (this._isMapMode) {
349
+ return _addByNode() || _addToValues();
177
350
  }
351
+ return _addToValues() || _addByNode();
178
352
  };
179
353
 
180
354
  if (this.isEntry(keyNodeOrEntry)) {
@@ -356,8 +356,8 @@ export abstract class AbstractGraph<
356
356
  const queue = new Queue<VO>([vertex1]);
357
357
  visited.set(vertex1, true);
358
358
  let cost = 0;
359
- while (queue.size > 0) {
360
- for (let i = 0; i < queue.size; i++) {
359
+ while (queue.length > 0) {
360
+ for (let i = 0; i < queue.length; i++) {
361
361
  const cur = queue.shift();
362
362
  if (cur === vertex2) {
363
363
  return cost;
@@ -185,7 +185,7 @@ import { IterableElementBase } from '../base';
185
185
  * ]);
186
186
  * console.log(scheduleTasks(tasks, 2)); // expectedMap
187
187
  */
188
- export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>> {
188
+ export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
189
189
  /**
190
190
  * The constructor initializes a heap data structure with optional elements and options.
191
191
  * @param elements - The `elements` parameter is an iterable object that contains the initial
@@ -416,17 +416,6 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
416
416
  return result;
417
417
  }
418
418
 
419
- /**
420
- * Time Complexity: O(n)
421
- * Space Complexity: O(n)
422
- *
423
- * Convert the heap to an array.
424
- * @returns An array containing the elements of the heap.
425
- */
426
- toArray(): E[] {
427
- return [...this.elements];
428
- }
429
-
430
419
  /**
431
420
  * Time Complexity: O(n)
432
421
  * Space Complexity: O(n)
@@ -483,7 +472,7 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
483
472
  * @returns The `filter` method is returning a new `Heap` object that contains the elements that pass
484
473
  * the filter condition specified by the `callback` function.
485
474
  */
486
- filter(callback: ElementCallback<E, R, boolean, Heap<E, R>>, thisArg?: any): Heap<E, R> {
475
+ filter(callback: ElementCallback<E, R, boolean>, thisArg?: any): Heap<E, R> {
487
476
  const filteredList = new Heap<E, R>([], { toElementFn: this.toElementFn, comparator: this.comparator });
488
477
  let index = 0;
489
478
  for (const current of this) {
@@ -517,7 +506,7 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
517
506
  * @returns a new instance of the `Heap` class with the mapped elements.
518
507
  */
519
508
  map<EM, RM>(
520
- callback: ElementCallback<E, R, EM, Heap<E, R>>,
509
+ callback: ElementCallback<E, R, EM>,
521
510
  comparator: Comparator<EM>,
522
511
  toElementFn?: (rawElement: RM) => EM,
523
512
  thisArg?: any