stack-typed 1.53.7 → 1.53.8
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/common/index.js +5 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +2 -2
- package/dist/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/data-structures/binary-tree/binary-tree.js +2 -2
- package/dist/data-structures/binary-tree/bst.d.ts +53 -23
- package/dist/data-structures/binary-tree/bst.js +59 -25
- package/dist/data-structures/binary-tree/index.d.ts +1 -1
- package/dist/data-structures/binary-tree/index.js +1 -1
- package/dist/data-structures/binary-tree/{rb-tree.d.ts → red-black-tree.d.ts} +49 -0
- package/dist/data-structures/binary-tree/{rb-tree.js → red-black-tree.js} +50 -1
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +2 -2
- package/dist/data-structures/binary-tree/tree-multi-map.js +5 -5
- package/dist/data-structures/hash/hash-map.d.ts +30 -0
- package/dist/data-structures/hash/hash-map.js +30 -0
- package/dist/data-structures/heap/heap.d.ts +20 -3
- package/dist/data-structures/heap/heap.js +31 -11
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +36 -1
- package/dist/data-structures/linked-list/doubly-linked-list.js +56 -9
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +34 -1
- package/dist/data-structures/linked-list/singly-linked-list.js +54 -10
- package/dist/data-structures/queue/deque.d.ts +37 -8
- package/dist/data-structures/queue/deque.js +73 -29
- package/dist/data-structures/queue/queue.d.ts +41 -1
- package/dist/data-structures/queue/queue.js +51 -9
- package/dist/data-structures/stack/stack.d.ts +27 -10
- package/dist/data-structures/stack/stack.js +39 -20
- package/dist/data-structures/trie/trie.d.ts +8 -3
- package/dist/data-structures/trie/trie.js +8 -3
- package/package.json +2 -2
- package/src/common/index.ts +7 -1
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +2 -2
- package/src/data-structures/binary-tree/binary-tree.ts +2 -2
- package/src/data-structures/binary-tree/bst.ts +64 -25
- package/src/data-structures/binary-tree/index.ts +1 -1
- package/src/data-structures/binary-tree/{rb-tree.ts → red-black-tree.ts} +50 -1
- package/src/data-structures/binary-tree/tree-multi-map.ts +3 -3
- package/src/data-structures/hash/hash-map.ts +30 -0
- package/src/data-structures/heap/heap.ts +33 -10
- package/src/data-structures/linked-list/doubly-linked-list.ts +62 -8
- package/src/data-structures/linked-list/singly-linked-list.ts +60 -10
- package/src/data-structures/queue/deque.ts +72 -28
- package/src/data-structures/queue/queue.ts +50 -7
- package/src/data-structures/stack/stack.ts +39 -20
- package/src/data-structures/trie/trie.ts +8 -3
|
@@ -95,32 +95,48 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
95
95
|
* 6. Balance Variability: Can become unbalanced; special types maintain balance.
|
|
96
96
|
* 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.
|
|
97
97
|
* @example
|
|
98
|
-
* //
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
98
|
+
* // Merge 3 sorted datasets
|
|
99
|
+
* const dataset1 = new BST<number, string>([
|
|
100
|
+
* [1, 'A'],
|
|
101
|
+
* [7, 'G']
|
|
102
|
+
* ]);
|
|
103
|
+
* const dataset2 = [
|
|
104
|
+
* [2, 'B'],
|
|
105
|
+
* [6, 'F']
|
|
106
|
+
* ];
|
|
107
|
+
* const dataset3 = new BST<number, string>([
|
|
108
|
+
* [3, 'C'],
|
|
109
|
+
* [5, 'E'],
|
|
110
|
+
* [4, 'D']
|
|
111
|
+
* ]);
|
|
102
112
|
*
|
|
103
|
-
* //
|
|
104
|
-
* const
|
|
105
|
-
*
|
|
106
|
-
*
|
|
113
|
+
* // Merge datasets into a single BinarySearchTree
|
|
114
|
+
* const merged = new BST<number, string>(dataset1);
|
|
115
|
+
* merged.addMany(dataset2);
|
|
116
|
+
* merged.merge(dataset3);
|
|
107
117
|
*
|
|
108
|
-
* //
|
|
109
|
-
* console.log(
|
|
110
|
-
* console.log(findKthSmallest(3)); // 4
|
|
111
|
-
* console.log(findKthSmallest(7)); // 8
|
|
118
|
+
* // Verify merged dataset is in sorted order
|
|
119
|
+
* console.log([...merged.values()]); // ['A', 'B', 'C', 'D', 'E', 'F', 'G']
|
|
112
120
|
* @example
|
|
113
121
|
* // Find elements in a range
|
|
114
122
|
* const bst = new BST<number>([10, 5, 15, 3, 7, 12, 18]);
|
|
115
123
|
* console.log(bst.search(new Range(5, 10))); // [10, 5, 7]
|
|
116
|
-
* console.log(bst.
|
|
124
|
+
* console.log(bst.rangeSearch([4, 12], node => node.key.toString())); // ['10', '12', '5', '7']
|
|
117
125
|
* console.log(bst.search(new Range(4, 12, true, false))); // [10, 5, 7]
|
|
118
|
-
* console.log(bst.
|
|
126
|
+
* console.log(bst.rangeSearch([15, 20])); // [15, 18]
|
|
119
127
|
* console.log(bst.search(new Range(15, 20, false))); // [18]
|
|
120
128
|
* @example
|
|
121
129
|
* // Find lowest common ancestor
|
|
122
130
|
* const bst = new BST<number>([20, 10, 30, 5, 15, 25, 35, 3, 7, 12, 18]);
|
|
123
131
|
*
|
|
132
|
+
* // LCA helper function
|
|
133
|
+
* const findLCA = (num1: number, num2: number): number | undefined => {
|
|
134
|
+
* const path1 = bst.getPathToRoot(num1);
|
|
135
|
+
* const path2 = bst.getPathToRoot(num2);
|
|
136
|
+
* // Find the first common ancestor
|
|
137
|
+
* return findFirstCommon(path1, path2);
|
|
138
|
+
* };
|
|
139
|
+
*
|
|
124
140
|
* function findFirstCommon(arr1: number[], arr2: number[]): number | undefined {
|
|
125
141
|
* for (const num of arr1) {
|
|
126
142
|
* if (arr2.indexOf(num) !== -1) {
|
|
@@ -130,14 +146,6 @@ export class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNod
|
|
|
130
146
|
* return undefined;
|
|
131
147
|
* }
|
|
132
148
|
*
|
|
133
|
-
* // LCA helper function
|
|
134
|
-
* const findLCA = (num1: number, num2: number): number | undefined => {
|
|
135
|
-
* const path1 = bst.getPathToRoot(num1);
|
|
136
|
-
* const path2 = bst.getPathToRoot(num2);
|
|
137
|
-
* // Find the first common ancestor
|
|
138
|
-
* return findFirstCommon(path1, path2);
|
|
139
|
-
* };
|
|
140
|
-
*
|
|
141
149
|
* // Assertions
|
|
142
150
|
* console.log(findLCA(3, 10)); // 7
|
|
143
151
|
* console.log(findLCA(5, 35)); // 15
|
|
@@ -233,11 +241,11 @@ export class BST<
|
|
|
233
241
|
* value associated with a key in a key-value pair.
|
|
234
242
|
* @returns either a NODE object or undefined.
|
|
235
243
|
*/
|
|
236
|
-
override
|
|
244
|
+
protected override _keyValueNodeEntryRawToNodeAndValue(
|
|
237
245
|
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
|
|
238
246
|
value?: V
|
|
239
247
|
): [OptNode<NODE>, V | undefined] {
|
|
240
|
-
const [node, entryValue] = super.
|
|
248
|
+
const [node, entryValue] = super._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
241
249
|
if (node === null) return [undefined, undefined];
|
|
242
250
|
return [node, value ?? entryValue];
|
|
243
251
|
}
|
|
@@ -299,7 +307,7 @@ export class BST<
|
|
|
299
307
|
* @returns a boolean value.
|
|
300
308
|
*/
|
|
301
309
|
override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
|
|
302
|
-
const [newNode, newValue] = this.
|
|
310
|
+
const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
303
311
|
if (newNode === undefined) return false;
|
|
304
312
|
|
|
305
313
|
if (this._root === undefined) {
|
|
@@ -609,6 +617,37 @@ export class BST<
|
|
|
609
617
|
return ans;
|
|
610
618
|
}
|
|
611
619
|
|
|
620
|
+
/**
|
|
621
|
+
* Time Complexity: O(log n)
|
|
622
|
+
* Space Complexity: O(n)
|
|
623
|
+
*
|
|
624
|
+
* The `rangeSearch` function searches for nodes within a specified range in a binary search tree.
|
|
625
|
+
* @param {Range<K> | [K, K]} range - The `range` parameter in the `rangeSearch` function can be
|
|
626
|
+
* either a `Range` object or an array of two elements representing the range boundaries.
|
|
627
|
+
* @param {C} callback - The `callback` parameter in the `rangeSearch` function is a callback
|
|
628
|
+
* function that is used to process each node that is found within the specified range during the
|
|
629
|
+
* search operation. It is of type `NodeCallback<NODE>`, where `NODE` is the type of nodes in the
|
|
630
|
+
* data structure.
|
|
631
|
+
* @param {BTNRep<K, V, NODE> | R} startNode - The `startNode` parameter in the `rangeSearch`
|
|
632
|
+
* function represents the node from which the search for nodes within the specified range will
|
|
633
|
+
* begin. It is the starting point for the range search operation.
|
|
634
|
+
* @param {IterationType} iterationType - The `iterationType` parameter in the `rangeSearch` function
|
|
635
|
+
* is used to specify the type of iteration to be performed during the search operation. It has a
|
|
636
|
+
* default value of `this.iterationType`, which suggests that it is likely a property of the class or
|
|
637
|
+
* object that the `rangeSearch`
|
|
638
|
+
* @returns The `rangeSearch` function is returning the result of calling the `search` method with
|
|
639
|
+
* the specified parameters.
|
|
640
|
+
*/
|
|
641
|
+
rangeSearch<C extends NodeCallback<NODE>>(
|
|
642
|
+
range: Range<K> | [K, K],
|
|
643
|
+
callback: C = this._DEFAULT_NODE_CALLBACK as C,
|
|
644
|
+
startNode: BTNRep<K, V, NODE> | R = this._root,
|
|
645
|
+
iterationType: IterationType = this.iterationType
|
|
646
|
+
) {
|
|
647
|
+
const searchRange: Range<K> = range instanceof Range ? range : new Range(range[0], range[1]);
|
|
648
|
+
return this.search(searchRange, false, callback, startNode, iterationType);
|
|
649
|
+
}
|
|
650
|
+
|
|
612
651
|
/**
|
|
613
652
|
* Time Complexity: O(log n)
|
|
614
653
|
* Space Complexity: O(1)
|
|
@@ -54,6 +54,55 @@ export class RedBlackTreeNode<
|
|
|
54
54
|
/**
|
|
55
55
|
* 1. Efficient self-balancing, but not completely balanced. Compared with AVLTree, the addition and deletion efficiency is high but the query efficiency is slightly lower.
|
|
56
56
|
* 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
|
|
57
|
+
* @example
|
|
58
|
+
* // Find elements in a range
|
|
59
|
+
* const bst = new RedBlackTree<number>([10, 5, 15, 3, 7, 12, 18]);
|
|
60
|
+
* console.log(bst.search(new Range(5, 10))); // [5, 10, 7]
|
|
61
|
+
* console.log(bst.search(new Range(4, 12))); // [5, 10, 12, 7]
|
|
62
|
+
* console.log(bst.search(new Range(15, 20))); // [15, 18]
|
|
63
|
+
* @example
|
|
64
|
+
* // using Red-Black Tree as a price-based index for stock data
|
|
65
|
+
* // Define the structure of individual stock records
|
|
66
|
+
* interface StockRecord {
|
|
67
|
+
* price: number; // Stock price (key for indexing)
|
|
68
|
+
* symbol: string; // Stock ticker symbol
|
|
69
|
+
* volume: number; // Trade volume
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* // Simulate stock market data as it might come from an external feed
|
|
73
|
+
* const marketStockData: StockRecord[] = [
|
|
74
|
+
* { price: 142.5, symbol: 'AAPL', volume: 1000000 },
|
|
75
|
+
* { price: 335.2, symbol: 'MSFT', volume: 800000 },
|
|
76
|
+
* { price: 3285.04, symbol: 'AMZN', volume: 500000 },
|
|
77
|
+
* { price: 267.98, symbol: 'META', volume: 750000 },
|
|
78
|
+
* { price: 234.57, symbol: 'GOOGL', volume: 900000 }
|
|
79
|
+
* ];
|
|
80
|
+
*
|
|
81
|
+
* // Extend the stock record type to include metadata for database usage
|
|
82
|
+
* type StockTableRecord = StockRecord & { lastUpdated: Date };
|
|
83
|
+
*
|
|
84
|
+
* // Create a Red-Black Tree to index stock records by price
|
|
85
|
+
* // Simulates a database index with stock price as the key for quick lookups
|
|
86
|
+
* const priceIndex = new RedBlackTree<number, StockTableRecord, StockRecord>(marketStockData, {
|
|
87
|
+
* toEntryFn: stockRecord => [
|
|
88
|
+
* stockRecord.price, // Use stock price as the key
|
|
89
|
+
* {
|
|
90
|
+
* ...stockRecord,
|
|
91
|
+
* lastUpdated: new Date() // Add a timestamp for when the record was indexed
|
|
92
|
+
* }
|
|
93
|
+
* ]
|
|
94
|
+
* });
|
|
95
|
+
*
|
|
96
|
+
* // Query the stock with the highest price
|
|
97
|
+
* const highestPricedStock = priceIndex.getRightMost();
|
|
98
|
+
* console.log(priceIndex.get(highestPricedStock)?.symbol); // 'AMZN' // Amazon has the highest price
|
|
99
|
+
*
|
|
100
|
+
* // Query stocks within a specific price range (200 to 400)
|
|
101
|
+
* const stocksInRange = priceIndex.rangeSearch(
|
|
102
|
+
* [200, 400], // Price range
|
|
103
|
+
* node => priceIndex.get(node)?.symbol // Extract stock symbols for the result
|
|
104
|
+
* );
|
|
105
|
+
* console.log(stocksInRange); // ['GOOGL', 'MSFT', 'META']
|
|
57
106
|
*/
|
|
58
107
|
export class RedBlackTree<
|
|
59
108
|
K = any,
|
|
@@ -207,7 +256,7 @@ export class RedBlackTree<
|
|
|
207
256
|
* returns true. If the node cannot be added or updated, the method returns false.
|
|
208
257
|
*/
|
|
209
258
|
override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V): boolean {
|
|
210
|
-
const [newNode, newValue] = this.
|
|
259
|
+
const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value);
|
|
211
260
|
if (!this.isRealNode(newNode)) return false;
|
|
212
261
|
|
|
213
262
|
const insertStatus = this._insert(newNode);
|
|
@@ -17,7 +17,7 @@ import type {
|
|
|
17
17
|
TreeMultiMapOptions
|
|
18
18
|
} from '../../types';
|
|
19
19
|
import { IBinaryTree } from '../../interfaces';
|
|
20
|
-
import { RedBlackTree, RedBlackTreeNode } from './
|
|
20
|
+
import { RedBlackTree, RedBlackTreeNode } from './red-black-tree';
|
|
21
21
|
|
|
22
22
|
export class TreeMultiMapNode<
|
|
23
23
|
K = any,
|
|
@@ -157,7 +157,7 @@ export class TreeMultiMap<
|
|
|
157
157
|
* times the key-value pair should be added to the data structure. If not provided, it defaults to 1.
|
|
158
158
|
* @returns either a NODE object or undefined.
|
|
159
159
|
*/
|
|
160
|
-
override
|
|
160
|
+
protected override _keyValueNodeEntryRawToNodeAndValue(
|
|
161
161
|
keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R,
|
|
162
162
|
value?: V,
|
|
163
163
|
count = 1
|
|
@@ -212,7 +212,7 @@ export class TreeMultiMap<
|
|
|
212
212
|
* was successful, and false otherwise.
|
|
213
213
|
*/
|
|
214
214
|
override add(keyNodeEntryOrRaw: BTNRep<K, V, NODE> | R, value?: V, count = 1): boolean {
|
|
215
|
-
const [newNode, newValue] = this.
|
|
215
|
+
const [newNode, newValue] = this._keyValueNodeEntryRawToNodeAndValue(keyNodeEntryOrRaw, value, count);
|
|
216
216
|
const orgCount = newNode?.count || 0;
|
|
217
217
|
const isSuccessAdded = super.add(newNode, newValue);
|
|
218
218
|
|
|
@@ -97,6 +97,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
+
* Time Complexity: O(1)
|
|
101
|
+
* Space Complexity: O(1)
|
|
102
|
+
*
|
|
100
103
|
* The function checks if a given element is an array with exactly two elements.
|
|
101
104
|
* @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any
|
|
102
105
|
* data type.
|
|
@@ -107,6 +110,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
107
110
|
}
|
|
108
111
|
|
|
109
112
|
/**
|
|
113
|
+
* Time Complexity: O(1)
|
|
114
|
+
* Space Complexity: O(1)
|
|
115
|
+
*
|
|
110
116
|
* The function checks if the size of an object is equal to zero and returns a boolean value.
|
|
111
117
|
* @returns A boolean value indicating whether the size of the object is 0 or not.
|
|
112
118
|
*/
|
|
@@ -115,6 +121,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
115
121
|
}
|
|
116
122
|
|
|
117
123
|
/**
|
|
124
|
+
* Time Complexity: O(1)
|
|
125
|
+
* Space Complexity: O(1)
|
|
126
|
+
*
|
|
118
127
|
* The clear() function resets the state of an object by clearing its internal store, object map, and
|
|
119
128
|
* size.
|
|
120
129
|
*/
|
|
@@ -125,6 +134,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
125
134
|
}
|
|
126
135
|
|
|
127
136
|
/**
|
|
137
|
+
* Time Complexity: O(1)
|
|
138
|
+
* Space Complexity: O(1)
|
|
139
|
+
*
|
|
128
140
|
* The `set` function adds a key-value pair to a map-like data structure, incrementing the size if
|
|
129
141
|
* the key is not already present.
|
|
130
142
|
* @param {K} key - The key parameter is the key used to identify the value in the data structure. It
|
|
@@ -150,6 +162,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
150
162
|
}
|
|
151
163
|
|
|
152
164
|
/**
|
|
165
|
+
* Time Complexity: O(k)
|
|
166
|
+
* Space Complexity: O(k)
|
|
167
|
+
*
|
|
153
168
|
* The function `setMany` takes an iterable collection of objects, maps each object to a key-value
|
|
154
169
|
* pair using a mapping function, and sets each key-value pair in the current object.
|
|
155
170
|
* @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type
|
|
@@ -175,6 +190,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
175
190
|
}
|
|
176
191
|
|
|
177
192
|
/**
|
|
193
|
+
* Time Complexity: O(1)
|
|
194
|
+
* Space Complexity: O(1)
|
|
195
|
+
*
|
|
178
196
|
* The `get` function retrieves a value from a map based on a given key, either from an object map or
|
|
179
197
|
* a string map.
|
|
180
198
|
* @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be
|
|
@@ -192,6 +210,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
192
210
|
}
|
|
193
211
|
|
|
194
212
|
/**
|
|
213
|
+
* Time Complexity: O(1)
|
|
214
|
+
* Space Complexity: O(1)
|
|
215
|
+
*
|
|
195
216
|
* The `has` function checks if a given key exists in the `_objMap` or `_store` based on whether it
|
|
196
217
|
* is an object key or not.
|
|
197
218
|
* @param {K} key - The parameter "key" is of type K, which means it can be any type.
|
|
@@ -207,6 +228,9 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
207
228
|
}
|
|
208
229
|
|
|
209
230
|
/**
|
|
231
|
+
* Time Complexity: O(1)
|
|
232
|
+
* Space Complexity: O(1)
|
|
233
|
+
*
|
|
210
234
|
* The `delete` function removes an element from a map-like data structure based on the provided key.
|
|
211
235
|
* @param {K} key - The `key` parameter is the key of the element that you want to delete from the
|
|
212
236
|
* data structure.
|
|
@@ -579,6 +603,9 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
579
603
|
}
|
|
580
604
|
|
|
581
605
|
/**
|
|
606
|
+
* Time Complexity: O(k)
|
|
607
|
+
* Space Complexity: O(k)
|
|
608
|
+
*
|
|
582
609
|
* The function `setMany` takes an iterable collection, converts each element into a key-value pair
|
|
583
610
|
* using a provided function, and sets each key-value pair in the current object, returning an array
|
|
584
611
|
* of booleans indicating the success of each set operation.
|
|
@@ -605,6 +632,9 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
605
632
|
}
|
|
606
633
|
|
|
607
634
|
/**
|
|
635
|
+
* Time Complexity: O(1)
|
|
636
|
+
* Space Complexity: O(1)
|
|
637
|
+
*
|
|
608
638
|
* The function checks if a given key exists in a map, using different logic depending on whether the
|
|
609
639
|
* key is a weak key or not.
|
|
610
640
|
* @param {K} key - The `key` parameter is the key that is being checked for existence in the map.
|
|
@@ -207,12 +207,7 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
|
|
|
207
207
|
if (comparator) this._comparator = comparator;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
for (const el of elements) {
|
|
212
|
-
if (this.toElementFn) this.add(this.toElementFn(el as R));
|
|
213
|
-
else this.add(el as E);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
210
|
+
this.addMany(elements);
|
|
216
211
|
}
|
|
217
212
|
|
|
218
213
|
protected _elements: E[] = [];
|
|
@@ -254,14 +249,42 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
|
|
|
254
249
|
* Time Complexity: O(log n)
|
|
255
250
|
* Space Complexity: O(1)
|
|
256
251
|
*
|
|
257
|
-
*
|
|
258
|
-
* @param element - The element to
|
|
252
|
+
* The add function pushes an element into an array and then triggers a bubble-up operation.
|
|
253
|
+
* @param {E} element - The `element` parameter represents the element that you want to add to the
|
|
254
|
+
* data structure.
|
|
255
|
+
* @returns The `add` method is returning a boolean value, which is the result of calling the
|
|
256
|
+
* `_bubbleUp` method with the index `this.elements.length - 1` as an argument.
|
|
259
257
|
*/
|
|
260
258
|
add(element: E): boolean {
|
|
261
|
-
this._elements.push(element);
|
|
259
|
+
this._elements.push(element as E);
|
|
262
260
|
return this._bubbleUp(this.elements.length - 1);
|
|
263
261
|
}
|
|
264
262
|
|
|
263
|
+
/**
|
|
264
|
+
* Time Complexity: O(k log n)
|
|
265
|
+
* Space Complexity: O(1)
|
|
266
|
+
*
|
|
267
|
+
* The `addMany` function iterates over elements and adds them to a collection, returning an array of
|
|
268
|
+
* boolean values indicating success or failure.
|
|
269
|
+
* @param {Iterable<E> | Iterable<R>} elements - The `elements` parameter in the `addMany` method is
|
|
270
|
+
* an iterable containing elements of type `E` or `R`. The method iterates over each element in the
|
|
271
|
+
* iterable and adds them to the data structure. If a transformation function `_toElementFn` is
|
|
272
|
+
* provided, it transforms the element
|
|
273
|
+
* @returns The `addMany` method returns an array of boolean values indicating whether each element
|
|
274
|
+
* in the input iterable was successfully added to the data structure.
|
|
275
|
+
*/
|
|
276
|
+
addMany(elements: Iterable<E> | Iterable<R>): boolean[] {
|
|
277
|
+
const ans: boolean[] = [];
|
|
278
|
+
for (const el of elements) {
|
|
279
|
+
if (this._toElementFn) {
|
|
280
|
+
ans.push(this.add(this._toElementFn(el as R)));
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
ans.push(this.add(el as E));
|
|
284
|
+
}
|
|
285
|
+
return ans;
|
|
286
|
+
}
|
|
287
|
+
|
|
265
288
|
/**
|
|
266
289
|
* Time Complexity: O(log n)
|
|
267
290
|
* Space Complexity: O(1)
|
|
@@ -473,7 +496,7 @@ export class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>
|
|
|
473
496
|
}
|
|
474
497
|
|
|
475
498
|
/**
|
|
476
|
-
* Time Complexity: O(n
|
|
499
|
+
* Time Complexity: O(n)
|
|
477
500
|
* Space Complexity: O(n)
|
|
478
501
|
*
|
|
479
502
|
* The `map` function creates a new heap by applying a callback function to each element of the
|
|
@@ -524,18 +524,15 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
524
524
|
* `DoublyLinkedListOptions<E, R>`. It is an optional parameter that allows you to pass additional
|
|
525
525
|
* configuration options to customize the behavior of the DoublyLinkedList.
|
|
526
526
|
*/
|
|
527
|
-
constructor(
|
|
527
|
+
constructor(
|
|
528
|
+
elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>> = [],
|
|
529
|
+
options?: DoublyLinkedListOptions<E, R>
|
|
530
|
+
) {
|
|
528
531
|
super(options);
|
|
529
532
|
this._head = undefined;
|
|
530
533
|
this._tail = undefined;
|
|
531
534
|
this._size = 0;
|
|
532
|
-
|
|
533
|
-
for (const el of elements) {
|
|
534
|
-
if (this.toElementFn) {
|
|
535
|
-
this.push(this.toElementFn(el as R));
|
|
536
|
-
} else this.push(el as E);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
535
|
+
this.pushMany(elements);
|
|
539
536
|
}
|
|
540
537
|
|
|
541
538
|
protected _head: DoublyLinkedListNode<E> | undefined;
|
|
@@ -700,6 +697,57 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
700
697
|
return true;
|
|
701
698
|
}
|
|
702
699
|
|
|
700
|
+
/**
|
|
701
|
+
* Time Complexity: O(k)
|
|
702
|
+
* Space Complexity: O(k)
|
|
703
|
+
*
|
|
704
|
+
* The function `pushMany` iterates over elements and pushes them into a data structure, applying a
|
|
705
|
+
* transformation function if provided.
|
|
706
|
+
* @param {Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>} elements - The `elements`
|
|
707
|
+
* parameter in the `pushMany` function can accept an iterable containing elements of type `E`, `R`,
|
|
708
|
+
* or `DoublyLinkedListNode<E>`. The function iterates over each element in the iterable and pushes
|
|
709
|
+
* it onto the linked list. If a transformation function `to
|
|
710
|
+
* @returns The `pushMany` function is returning an array of boolean values (`ans`) which indicate
|
|
711
|
+
* the success or failure of pushing each element into the data structure.
|
|
712
|
+
*/
|
|
713
|
+
pushMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>) {
|
|
714
|
+
const ans: boolean[] = [];
|
|
715
|
+
for (const el of elements) {
|
|
716
|
+
if (this.toElementFn) {
|
|
717
|
+
ans.push(this.push(this.toElementFn(el as R)));
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
ans.push(this.push(el as E | DoublyLinkedListNode<E>));
|
|
721
|
+
}
|
|
722
|
+
return ans;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Time Complexity: O(k)
|
|
727
|
+
* Space Complexity: O(k)
|
|
728
|
+
*
|
|
729
|
+
* The function `unshiftMany` iterates through a collection of elements and adds them to the
|
|
730
|
+
* beginning of a Doubly Linked List, returning an array of boolean values indicating the success of
|
|
731
|
+
* each insertion.
|
|
732
|
+
* @param {Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>} elements - The `elements`
|
|
733
|
+
* parameter in the `unshiftMany` function can accept an iterable containing elements of type `E`,
|
|
734
|
+
* `R`, or `DoublyLinkedListNode<E>`. The function iterates over each element in the iterable and
|
|
735
|
+
* performs an `unshift` operation on the doubly linked list
|
|
736
|
+
* @returns The `unshiftMany` function returns an array of boolean values indicating the success of
|
|
737
|
+
* each unshift operation performed on the elements passed as input.
|
|
738
|
+
*/
|
|
739
|
+
unshiftMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>) {
|
|
740
|
+
const ans: boolean[] = [];
|
|
741
|
+
for (const el of elements) {
|
|
742
|
+
if (this.toElementFn) {
|
|
743
|
+
ans.push(this.unshift(this.toElementFn(el as R)));
|
|
744
|
+
continue;
|
|
745
|
+
}
|
|
746
|
+
ans.push(this.unshift(el as E | DoublyLinkedListNode<E>));
|
|
747
|
+
}
|
|
748
|
+
return ans;
|
|
749
|
+
}
|
|
750
|
+
|
|
703
751
|
/**
|
|
704
752
|
* Time Complexity: O(n)
|
|
705
753
|
* Space Complexity: O(1)
|
|
@@ -1182,6 +1230,12 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
1182
1230
|
* Time Complexity: O(n)
|
|
1183
1231
|
* Space Complexity: O(1)
|
|
1184
1232
|
*
|
|
1233
|
+
* The function `countOccurrences` iterates through a doubly linked list and counts the occurrences
|
|
1234
|
+
* of a specified element or nodes that satisfy a given predicate.
|
|
1235
|
+
* @param {E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)} elementOrNode
|
|
1236
|
+
* - The `elementOrNode` parameter in the `countOccurrences` method can accept three types of values:
|
|
1237
|
+
* @returns The `countOccurrences` method returns the number of occurrences of the specified element,
|
|
1238
|
+
* node, or predicate function in the doubly linked list.
|
|
1185
1239
|
*/
|
|
1186
1240
|
countOccurrences(elementOrNode: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)): number {
|
|
1187
1241
|
const predicate = this._ensurePredicate(elementOrNode);
|
|
@@ -60,17 +60,12 @@ export class SinglyLinkedListNode<E = any> {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R, SinglyLinkedList<E, R>> {
|
|
63
|
-
constructor(
|
|
63
|
+
constructor(
|
|
64
|
+
elements: Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>> = [],
|
|
65
|
+
options?: SinglyLinkedListOptions<E, R>
|
|
66
|
+
) {
|
|
64
67
|
super(options);
|
|
65
|
-
|
|
66
|
-
for (const el of elements) {
|
|
67
|
-
if (this.toElementFn) {
|
|
68
|
-
this.push(this.toElementFn(el as R));
|
|
69
|
-
} else {
|
|
70
|
-
this.push(el as E);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
68
|
+
this.pushMany(elements);
|
|
74
69
|
}
|
|
75
70
|
|
|
76
71
|
protected _head: SinglyLinkedListNode<E> | undefined;
|
|
@@ -211,6 +206,55 @@ export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
211
206
|
return true;
|
|
212
207
|
}
|
|
213
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Time Complexity: O(k)
|
|
211
|
+
* Space Complexity: O(k)
|
|
212
|
+
*
|
|
213
|
+
* The function `pushMany` iterates over elements and pushes them into a data structure, applying a
|
|
214
|
+
* transformation function if provided.
|
|
215
|
+
* @param {Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>>} elements - The `elements`
|
|
216
|
+
* parameter in the `pushMany` function can accept an iterable containing elements of type `E`, `R`,
|
|
217
|
+
* or `SinglyLinkedListNode<E>`.
|
|
218
|
+
* @returns The `pushMany` function returns an array of boolean values indicating whether each
|
|
219
|
+
* element was successfully pushed into the data structure.
|
|
220
|
+
*/
|
|
221
|
+
pushMany(elements: Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>>) {
|
|
222
|
+
const ans: boolean[] = [];
|
|
223
|
+
for (const el of elements) {
|
|
224
|
+
if (this.toElementFn) {
|
|
225
|
+
ans.push(this.push(this.toElementFn(el as R)));
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
ans.push(this.push(el as E | SinglyLinkedListNode<E>));
|
|
229
|
+
}
|
|
230
|
+
return ans;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Time Complexity: O(k)
|
|
235
|
+
* Space Complexity: O(k)
|
|
236
|
+
*
|
|
237
|
+
* The function `unshiftMany` iterates over elements and adds them to a data structure, optionally
|
|
238
|
+
* converting them using a provided function.
|
|
239
|
+
* @param {Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>>} elements - The `elements`
|
|
240
|
+
* parameter in the `unshiftMany` function can accept an iterable containing elements of type `E`,
|
|
241
|
+
* `R`, or `SinglyLinkedListNode<E>`. The function iterates over each element in the iterable and
|
|
242
|
+
* performs an `unshift` operation on the linked list for each
|
|
243
|
+
* @returns The `unshiftMany` function is returning an array of boolean values, where each value
|
|
244
|
+
* represents the result of calling the `unshift` method on the current instance of the class.
|
|
245
|
+
*/
|
|
246
|
+
unshiftMany(elements: Iterable<E> | Iterable<R> | Iterable<SinglyLinkedListNode<E>>) {
|
|
247
|
+
const ans: boolean[] = [];
|
|
248
|
+
for (const el of elements) {
|
|
249
|
+
if (this.toElementFn) {
|
|
250
|
+
ans.push(this.unshift(this.toElementFn(el as R)));
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
ans.push(this.unshift(el as E | SinglyLinkedListNode<E>));
|
|
254
|
+
}
|
|
255
|
+
return ans;
|
|
256
|
+
}
|
|
257
|
+
|
|
214
258
|
/**
|
|
215
259
|
* Time Complexity: O(n)
|
|
216
260
|
* Space Complexity: O(1)
|
|
@@ -399,6 +443,9 @@ export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
399
443
|
}
|
|
400
444
|
|
|
401
445
|
/**
|
|
446
|
+
* Time Complexity: O(1)
|
|
447
|
+
* Space Complexity: O(1)
|
|
448
|
+
*
|
|
402
449
|
* The function checks if the length of a data structure is equal to zero and returns a boolean value indicating
|
|
403
450
|
* whether it is empty or not.
|
|
404
451
|
* @returns A boolean value indicating whether the length of the object is equal to 0.
|
|
@@ -408,6 +455,9 @@ export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|
|
408
455
|
}
|
|
409
456
|
|
|
410
457
|
/**
|
|
458
|
+
* Time Complexity: O(1)
|
|
459
|
+
* Space Complexity: O(1)
|
|
460
|
+
*
|
|
411
461
|
* The `clear` function resets the linked list by setting the head, tail, and length to undefined and 0 respectively.
|
|
412
462
|
*/
|
|
413
463
|
clear(): void {
|