queue-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.
- package/dist/data-structures/base/iterable-element-base.d.ts +14 -40
- package/dist/data-structures/base/iterable-element-base.js +14 -11
- package/dist/data-structures/base/linear-base.d.ts +277 -0
- package/dist/data-structures/base/linear-base.js +552 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +50 -37
- package/dist/data-structures/binary-tree/avl-tree.d.ts +64 -0
- package/dist/data-structures/binary-tree/avl-tree.js +64 -0
- package/dist/data-structures/binary-tree/binary-tree.js +5 -5
- package/dist/data-structures/binary-tree/bst.js +11 -11
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
- package/dist/data-structures/binary-tree/tree-multi-map.js +210 -40
- package/dist/data-structures/graph/abstract-graph.js +2 -2
- package/dist/data-structures/heap/heap.d.ts +3 -11
- package/dist/data-structures/heap/heap.js +0 -10
- package/dist/data-structures/heap/max-heap.d.ts +2 -2
- package/dist/data-structures/heap/min-heap.d.ts +2 -2
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
- package/dist/data-structures/linked-list/doubly-linked-list.js +131 -146
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +79 -75
- package/dist/data-structures/linked-list/singly-linked-list.js +217 -169
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
- package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -2
- package/dist/data-structures/queue/deque.d.ts +130 -91
- package/dist/data-structures/queue/deque.js +269 -169
- package/dist/data-structures/queue/queue.d.ts +84 -40
- package/dist/data-structures/queue/queue.js +134 -50
- package/dist/data-structures/stack/stack.d.ts +3 -11
- package/dist/data-structures/stack/stack.js +0 -10
- package/dist/data-structures/trie/trie.d.ts +4 -3
- package/dist/data-structures/trie/trie.js +3 -0
- package/dist/types/data-structures/base/base.d.ts +9 -4
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
- package/dist/types/data-structures/queue/deque.d.ts +2 -3
- package/dist/types/data-structures/queue/queue.d.ts +2 -2
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +29 -20
- package/src/data-structures/base/linear-base.ts +649 -0
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +51 -36
- package/src/data-structures/binary-tree/avl-tree.ts +64 -0
- package/src/data-structures/binary-tree/binary-tree.ts +5 -5
- package/src/data-structures/binary-tree/bst.ts +9 -9
- package/src/data-structures/binary-tree/tree-multi-map.ts +214 -40
- package/src/data-structures/graph/abstract-graph.ts +2 -2
- package/src/data-structures/heap/heap.ts +3 -14
- package/src/data-structures/heap/max-heap.ts +2 -2
- package/src/data-structures/heap/min-heap.ts +2 -2
- package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
- package/src/data-structures/linked-list/singly-linked-list.ts +241 -185
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/priority-queue.ts +2 -2
- package/src/data-structures/queue/deque.ts +286 -183
- package/src/data-structures/queue/queue.ts +149 -63
- package/src/data-structures/stack/stack.ts +3 -18
- package/src/data-structures/trie/trie.ts +7 -3
- package/src/types/data-structures/base/base.ts +17 -8
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
- package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
- package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
- package/src/types/data-structures/queue/deque.ts +2 -3
- 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
|
|
112
|
-
* specified key and
|
|
113
|
-
* @param {K} key - The `key` parameter
|
|
114
|
-
*
|
|
115
|
-
* @
|
|
116
|
-
*
|
|
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
|
-
|
|
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
|
|
133
|
-
*
|
|
134
|
-
* @param
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* `values`
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
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
|
|
154
|
-
|
|
155
|
-
|
|
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
|
|
181
|
+
return super.add(key, values);
|
|
170
182
|
}
|
|
171
|
-
}
|
|
172
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
1553
|
-
const levelSize = queue.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
449
|
-
|
|
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
|
-
|
|
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
|
-
|
|
470
|
-
|
|
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.
|
|
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
|
|
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
|
-
* //
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
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
|
|
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
|
|
119
|
-
*
|
|
120
|
-
* @param {K} key - The `key` parameter
|
|
121
|
-
*
|
|
122
|
-
* @
|
|
123
|
-
*
|
|
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(
|
|
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
|
|
138
|
-
*
|
|
139
|
-
* @param
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* @param {V} [
|
|
143
|
-
* you want to add to the TreeMultiMap.
|
|
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
|
|
158
|
-
|
|
159
|
-
|
|
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
|
|
344
|
+
return super.add(key, values);
|
|
174
345
|
}
|
|
175
|
-
}
|
|
176
|
-
|
|
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.
|
|
360
|
-
for (let i = 0; i < queue.
|
|
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
|
|
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
|
|
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
|
|
509
|
+
callback: ElementCallback<E, R, EM>,
|
|
521
510
|
comparator: Comparator<EM>,
|
|
522
511
|
toElementFn?: (rawElement: RM) => EM,
|
|
523
512
|
thisArg?: any
|