min-heap-typed 1.50.2 → 1.50.3
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-base.d.ts +6 -0
- package/dist/data-structures/binary-tree/avl-tree.d.ts +29 -1
- package/dist/data-structures/binary-tree/avl-tree.js +33 -1
- package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +22 -0
- package/dist/data-structures/binary-tree/binary-indexed-tree.js +22 -0
- package/dist/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/data-structures/binary-tree/binary-tree.js +1 -1
- package/dist/data-structures/binary-tree/bst.d.ts +46 -13
- package/dist/data-structures/binary-tree/bst.js +46 -13
- package/dist/data-structures/binary-tree/rb-tree.d.ts +54 -2
- package/dist/data-structures/binary-tree/rb-tree.js +73 -15
- package/dist/data-structures/binary-tree/segment-tree.d.ts +99 -6
- package/dist/data-structures/binary-tree/segment-tree.js +127 -10
- package/dist/data-structures/binary-tree/tree-multimap.d.ts +35 -2
- package/dist/data-structures/binary-tree/tree-multimap.js +38 -0
- package/dist/data-structures/graph/abstract-graph.d.ts +0 -78
- package/dist/data-structures/graph/abstract-graph.js +0 -189
- package/dist/data-structures/graph/directed-graph.d.ts +59 -0
- package/dist/data-structures/graph/directed-graph.js +105 -0
- package/dist/data-structures/graph/undirected-graph.d.ts +60 -7
- package/dist/data-structures/graph/undirected-graph.js +126 -18
- package/dist/data-structures/hash/hash-map.d.ts +143 -23
- package/dist/data-structures/hash/hash-map.js +196 -62
- package/dist/data-structures/heap/heap.d.ts +29 -19
- package/dist/data-structures/heap/heap.js +29 -20
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +71 -25
- package/dist/data-structures/linked-list/doubly-linked-list.js +83 -25
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +26 -3
- package/dist/data-structures/linked-list/singly-linked-list.js +34 -3
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +2 -2
- package/dist/data-structures/linked-list/skip-linked-list.js +2 -2
- package/dist/data-structures/matrix/matrix.d.ts +1 -1
- package/dist/data-structures/matrix/matrix.js +1 -1
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +10 -0
- package/dist/data-structures/priority-queue/max-priority-queue.js +10 -0
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -0
- package/dist/data-structures/priority-queue/min-priority-queue.js +11 -0
- package/dist/data-structures/priority-queue/priority-queue.d.ts +8 -0
- package/dist/data-structures/priority-queue/priority-queue.js +8 -0
- package/dist/data-structures/queue/deque.d.ts +95 -21
- package/dist/data-structures/queue/deque.js +100 -16
- package/dist/data-structures/queue/queue.d.ts +65 -45
- package/dist/data-structures/queue/queue.js +65 -45
- package/dist/data-structures/stack/stack.d.ts +36 -22
- package/dist/data-structures/stack/stack.js +36 -22
- package/dist/data-structures/tree/tree.d.ts +57 -3
- package/dist/data-structures/tree/tree.js +77 -11
- package/dist/data-structures/trie/trie.d.ts +100 -36
- package/dist/data-structures/trie/trie.js +115 -36
- package/package.json +2 -2
- package/src/data-structures/base/iterable-base.ts +12 -0
- package/src/data-structures/binary-tree/avl-tree.ts +37 -3
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +22 -0
- package/src/data-structures/binary-tree/binary-tree.ts +1 -1
- package/src/data-structures/binary-tree/bst.ts +46 -13
- package/src/data-structures/binary-tree/rb-tree.ts +79 -18
- package/src/data-structures/binary-tree/segment-tree.ts +145 -11
- package/src/data-structures/binary-tree/tree-multimap.ts +42 -3
- package/src/data-structures/graph/abstract-graph.ts +0 -211
- package/src/data-structures/graph/directed-graph.ts +122 -0
- package/src/data-structures/graph/undirected-graph.ts +143 -19
- package/src/data-structures/hash/hash-map.ts +228 -76
- package/src/data-structures/heap/heap.ts +31 -20
- package/src/data-structures/linked-list/doubly-linked-list.ts +96 -29
- package/src/data-structures/linked-list/singly-linked-list.ts +42 -6
- package/src/data-structures/linked-list/skip-linked-list.ts +2 -2
- package/src/data-structures/matrix/matrix.ts +1 -1
- package/src/data-structures/priority-queue/max-priority-queue.ts +10 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +11 -0
- package/src/data-structures/priority-queue/priority-queue.ts +8 -0
- package/src/data-structures/queue/deque.ts +118 -22
- package/src/data-structures/queue/queue.ts +68 -45
- package/src/data-structures/stack/stack.ts +39 -23
- package/src/data-structures/tree/tree.ts +89 -15
- package/src/data-structures/trie/trie.ts +131 -40
|
@@ -22,9 +22,6 @@ import { isWeakKey, rangeCheck } from '../../utils';
|
|
|
22
22
|
* 4. Unordered Collection: HashMap does not guarantee the order of entries, and the order may change over time.
|
|
23
23
|
*/
|
|
24
24
|
export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
|
|
25
|
-
protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};
|
|
26
|
-
protected _objMap: Map<object, V> = new Map();
|
|
27
|
-
|
|
28
25
|
/**
|
|
29
26
|
* The constructor function initializes a HashMap object with an optional initial collection and
|
|
30
27
|
* options.
|
|
@@ -48,6 +45,28 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
47
|
|
|
48
|
+
protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The function returns the store object, which is a dictionary of HashMapStoreItem objects.
|
|
52
|
+
* @returns The store property is being returned. It is a dictionary-like object with string keys and
|
|
53
|
+
* values of type HashMapStoreItem<K, V>.
|
|
54
|
+
*/
|
|
55
|
+
get store(): { [p: string]: HashMapStoreItem<K, V> } {
|
|
56
|
+
return this._store;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected _objMap: Map<object, V> = new Map();
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The function returns the object map.
|
|
63
|
+
* @returns The `objMap` property is being returned, which is a `Map` object with keys of type
|
|
64
|
+
* `object` and values of type `V`.
|
|
65
|
+
*/
|
|
66
|
+
get objMap(): Map<object, V> {
|
|
67
|
+
return this._objMap;
|
|
68
|
+
}
|
|
69
|
+
|
|
51
70
|
protected _toEntryFn: (rawElement: R) => [K, V] = (rawElement: R) => {
|
|
52
71
|
if (this.isEntry(rawElement)) {
|
|
53
72
|
// TODO, For performance optimization, it may be necessary to only inspect the first element traversed.
|
|
@@ -67,16 +86,6 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
67
86
|
return this._toEntryFn;
|
|
68
87
|
}
|
|
69
88
|
|
|
70
|
-
/**
|
|
71
|
-
* The hasFn function is a function that takes in an item and returns a boolean
|
|
72
|
-
* indicating whether the item is contained within the hash table.
|
|
73
|
-
*
|
|
74
|
-
* @return The hash function
|
|
75
|
-
*/
|
|
76
|
-
get hasFn() {
|
|
77
|
-
return this._hashFn;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
89
|
protected _size = 0;
|
|
81
90
|
|
|
82
91
|
/**
|
|
@@ -87,6 +96,18 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
87
96
|
return this._size;
|
|
88
97
|
}
|
|
89
98
|
|
|
99
|
+
protected _hashFn: (key: K) => string = (key: K) => String(key);
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* The hasFn function is a function that takes in an item and returns a boolean
|
|
103
|
+
* indicating whether the item is contained within the hash table.
|
|
104
|
+
*
|
|
105
|
+
* @return The hash function
|
|
106
|
+
*/
|
|
107
|
+
get hashFn() {
|
|
108
|
+
return this._hashFn;
|
|
109
|
+
}
|
|
110
|
+
|
|
90
111
|
/**
|
|
91
112
|
* The function checks if a given element is an array with exactly two elements.
|
|
92
113
|
* @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any
|
|
@@ -126,13 +147,13 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
126
147
|
*/
|
|
127
148
|
set(key: K, value: V): boolean {
|
|
128
149
|
if (this._isObjKey(key)) {
|
|
129
|
-
if (!this.
|
|
150
|
+
if (!this.objMap.has(key)) {
|
|
130
151
|
this._size++;
|
|
131
152
|
}
|
|
132
|
-
this.
|
|
153
|
+
this.objMap.set(key, value);
|
|
133
154
|
} else {
|
|
134
155
|
const strKey = this._getNoObjKey(key);
|
|
135
|
-
if (this.
|
|
156
|
+
if (this.store[strKey] === undefined) {
|
|
136
157
|
this._size++;
|
|
137
158
|
}
|
|
138
159
|
this._store[strKey] = { key, value };
|
|
@@ -174,7 +195,7 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
174
195
|
*/
|
|
175
196
|
override get(key: K): V | undefined {
|
|
176
197
|
if (this._isObjKey(key)) {
|
|
177
|
-
return this.
|
|
198
|
+
return this.objMap.get(key);
|
|
178
199
|
} else {
|
|
179
200
|
const strKey = this._getNoObjKey(key);
|
|
180
201
|
return this._store[strKey]?.value;
|
|
@@ -189,10 +210,10 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
189
210
|
*/
|
|
190
211
|
override has(key: K): boolean {
|
|
191
212
|
if (this._isObjKey(key)) {
|
|
192
|
-
return this.
|
|
213
|
+
return this.objMap.has(key);
|
|
193
214
|
} else {
|
|
194
215
|
const strKey = this._getNoObjKey(key);
|
|
195
|
-
return strKey in this.
|
|
216
|
+
return strKey in this.store;
|
|
196
217
|
}
|
|
197
218
|
}
|
|
198
219
|
|
|
@@ -205,15 +226,15 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
205
226
|
*/
|
|
206
227
|
delete(key: K): boolean {
|
|
207
228
|
if (this._isObjKey(key)) {
|
|
208
|
-
if (this.
|
|
229
|
+
if (this.objMap.has(key)) {
|
|
209
230
|
this._size--;
|
|
210
231
|
}
|
|
211
232
|
|
|
212
|
-
return this.
|
|
233
|
+
return this.objMap.delete(key);
|
|
213
234
|
} else {
|
|
214
235
|
const strKey = this._getNoObjKey(key);
|
|
215
|
-
if (strKey in this.
|
|
216
|
-
delete this.
|
|
236
|
+
if (strKey in this.store) {
|
|
237
|
+
delete this.store[strKey];
|
|
217
238
|
this._size--;
|
|
218
239
|
return true;
|
|
219
240
|
}
|
|
@@ -221,6 +242,11 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
221
242
|
}
|
|
222
243
|
}
|
|
223
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Time Complexity: O(n)
|
|
247
|
+
* Space Complexity: O(n)
|
|
248
|
+
*/
|
|
249
|
+
|
|
224
250
|
/**
|
|
225
251
|
* The clone function creates a new HashMap with the same key-value pairs as
|
|
226
252
|
* this one. The clone function is useful for creating a copy of an existing
|
|
@@ -229,7 +255,7 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
229
255
|
* @return A new hashmap with the same values as this one
|
|
230
256
|
*/
|
|
231
257
|
clone(): HashMap<K, V, R> {
|
|
232
|
-
return new HashMap<K, V, R>(this, { hashFn: this.
|
|
258
|
+
return new HashMap<K, V, R>(this, { hashFn: this.hashFn, toEntryFn: this.toEntryFn });
|
|
233
259
|
}
|
|
234
260
|
|
|
235
261
|
/**
|
|
@@ -260,11 +286,6 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
260
286
|
return resultMap;
|
|
261
287
|
}
|
|
262
288
|
|
|
263
|
-
/**
|
|
264
|
-
* Time Complexity: O(n)
|
|
265
|
-
* Space Complexity: O(n)
|
|
266
|
-
*/
|
|
267
|
-
|
|
268
289
|
/**
|
|
269
290
|
* Time Complexity: O(n)
|
|
270
291
|
* Space Complexity: O(n)
|
|
@@ -309,27 +330,37 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
309
330
|
* object map.
|
|
310
331
|
*/
|
|
311
332
|
protected* _getIterator(): IterableIterator<[K, V]> {
|
|
312
|
-
for (const node of Object.values(this.
|
|
333
|
+
for (const node of Object.values(this.store)) {
|
|
313
334
|
yield [node.key, node.value] as [K, V];
|
|
314
335
|
}
|
|
315
|
-
for (const node of this.
|
|
336
|
+
for (const node of this.objMap) {
|
|
316
337
|
yield node as [K, V];
|
|
317
338
|
}
|
|
318
339
|
}
|
|
319
340
|
|
|
320
|
-
|
|
321
|
-
|
|
341
|
+
/**
|
|
342
|
+
* The function checks if a given key is an object or a function.
|
|
343
|
+
* @param {any} key - The parameter "key" can be of any type.
|
|
344
|
+
* @returns a boolean value.
|
|
345
|
+
*/
|
|
322
346
|
protected _isObjKey(key: any): key is object | ((...args: any[]) => any) {
|
|
323
347
|
const keyType = typeof key;
|
|
324
348
|
return (keyType === 'object' || keyType === 'function') && key !== null;
|
|
325
349
|
}
|
|
326
350
|
|
|
351
|
+
/**
|
|
352
|
+
* The function `_getNoObjKey` takes a key and returns a string representation of the key, handling
|
|
353
|
+
* different types of keys.
|
|
354
|
+
* @param {K} key - The `key` parameter is of type `K`, which represents the type of the key being
|
|
355
|
+
* passed to the `_getNoObjKey` function.
|
|
356
|
+
* @returns a string value.
|
|
357
|
+
*/
|
|
327
358
|
protected _getNoObjKey(key: K): string {
|
|
328
359
|
const keyType = typeof key;
|
|
329
360
|
|
|
330
361
|
let strKey: string;
|
|
331
362
|
if (keyType !== 'string' && keyType !== 'number' && keyType !== 'symbol') {
|
|
332
|
-
strKey = this.
|
|
363
|
+
strKey = this.hashFn(key);
|
|
333
364
|
} else {
|
|
334
365
|
if (keyType === 'number') {
|
|
335
366
|
// TODO numeric key should has its own hash
|
|
@@ -348,10 +379,6 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|
|
348
379
|
* 3. Time Complexity: Similar to HashMap, LinkedHashMap offers constant-time performance for get and put operations in most cases.
|
|
349
380
|
*/
|
|
350
381
|
export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
|
|
351
|
-
protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};
|
|
352
|
-
protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();
|
|
353
|
-
protected _head: HashMapLinkedNode<K, V | undefined>;
|
|
354
|
-
protected _tail: HashMapLinkedNode<K, V | undefined>;
|
|
355
382
|
protected readonly _sentinel: HashMapLinkedNode<K, V | undefined>;
|
|
356
383
|
|
|
357
384
|
/**
|
|
@@ -386,6 +413,69 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
386
413
|
}
|
|
387
414
|
}
|
|
388
415
|
|
|
416
|
+
protected _hashFn: (key: K) => string = (key: K) => String(key);
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* The function returns the hash function used for generating a hash value for a given key.
|
|
420
|
+
* @returns The hash function that takes a key of type K and returns a string.
|
|
421
|
+
*/
|
|
422
|
+
get hashFn(): (key: K) => string {
|
|
423
|
+
return this._hashFn;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
protected _objHashFn: (key: K) => object = (key: K) => <object>key;
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* The function returns the object hash function.
|
|
430
|
+
* @returns The function `objHashFn` is being returned.
|
|
431
|
+
*/
|
|
432
|
+
get objHashFn(): (key: K) => object {
|
|
433
|
+
return this._objHashFn;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* The function returns a record of HashMapLinkedNode objects with string keys.
|
|
440
|
+
* @returns The method is returning a Record object, which is a TypeScript type that represents an
|
|
441
|
+
* object with string keys and values that are HashMapLinkedNode objects with keys of type K and
|
|
442
|
+
* values of type V or undefined.
|
|
443
|
+
*/
|
|
444
|
+
get noObjMap(): Record<string, HashMapLinkedNode<K, V | undefined>> {
|
|
445
|
+
return this._noObjMap;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* The function returns the WeakMap object used to map objects to HashMapLinkedNode instances.
|
|
452
|
+
* @returns The `objMap` property is being returned.
|
|
453
|
+
*/
|
|
454
|
+
get objMap(): WeakMap<object, HashMapLinkedNode<K, V | undefined>> {
|
|
455
|
+
return this._objMap;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
protected _head: HashMapLinkedNode<K, V | undefined>;
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* The function returns the head node of a HashMapLinkedNode.
|
|
462
|
+
* @returns The method `getHead()` is returning a `HashMapLinkedNode` object with key type `K` and
|
|
463
|
+
* value type `V | undefined`.
|
|
464
|
+
*/
|
|
465
|
+
get head(): HashMapLinkedNode<K, V | undefined> {
|
|
466
|
+
return this._head;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
protected _tail: HashMapLinkedNode<K, V | undefined>;
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* The function returns the tail node of a HashMapLinkedNode.
|
|
473
|
+
* @returns The `_tail` property of type `HashMapLinkedNode<K, V | undefined>` is being returned.
|
|
474
|
+
*/
|
|
475
|
+
get tail(): HashMapLinkedNode<K, V | undefined> {
|
|
476
|
+
return this._tail;
|
|
477
|
+
}
|
|
478
|
+
|
|
389
479
|
protected _toEntryFn: (rawElement: R) => [K, V] = (rawElement: R) => {
|
|
390
480
|
if (this.isEntry(rawElement)) {
|
|
391
481
|
// TODO, For performance optimization, it may be necessary to only inspect the first element traversed.
|
|
@@ -415,6 +505,11 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
415
505
|
return this._size;
|
|
416
506
|
}
|
|
417
507
|
|
|
508
|
+
/**
|
|
509
|
+
* Time Complexity: O(1)
|
|
510
|
+
* Space Complexity: O(1)
|
|
511
|
+
*/
|
|
512
|
+
|
|
418
513
|
/**
|
|
419
514
|
* Time Complexity: O(1)
|
|
420
515
|
* Space Complexity: O(1)
|
|
@@ -425,9 +520,14 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
425
520
|
*/
|
|
426
521
|
get first() {
|
|
427
522
|
if (this._size === 0) return;
|
|
428
|
-
return <[K, V]>[this.
|
|
523
|
+
return <[K, V]>[this.head.key, this.head.value];
|
|
429
524
|
}
|
|
430
525
|
|
|
526
|
+
/**
|
|
527
|
+
* Time Complexity: O(1)
|
|
528
|
+
* Space Complexity: O(1)
|
|
529
|
+
*/
|
|
530
|
+
|
|
431
531
|
/**
|
|
432
532
|
* Time Complexity: O(1)
|
|
433
533
|
* Space Complexity: O(1)
|
|
@@ -438,14 +538,14 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
438
538
|
*/
|
|
439
539
|
get last() {
|
|
440
540
|
if (this._size === 0) return;
|
|
441
|
-
return <[K, V]>[this.
|
|
541
|
+
return <[K, V]>[this.tail.key, this.tail.value];
|
|
442
542
|
}
|
|
443
543
|
|
|
444
544
|
/**
|
|
445
545
|
* The `begin()` function in TypeScript iterates over a linked list and yields key-value pairs.
|
|
446
546
|
*/
|
|
447
547
|
* begin() {
|
|
448
|
-
let node = this.
|
|
548
|
+
let node = this.head;
|
|
449
549
|
while (node !== this._sentinel) {
|
|
450
550
|
yield [node.key, node.value];
|
|
451
551
|
node = node.next;
|
|
@@ -457,13 +557,18 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
457
557
|
* key and value.
|
|
458
558
|
*/
|
|
459
559
|
* reverseBegin() {
|
|
460
|
-
let node = this.
|
|
560
|
+
let node = this.tail;
|
|
461
561
|
while (node !== this._sentinel) {
|
|
462
562
|
yield [node.key, node.value];
|
|
463
563
|
node = node.prev;
|
|
464
564
|
}
|
|
465
565
|
}
|
|
466
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Time Complexity: O(1)
|
|
569
|
+
* Space Complexity: O(1)
|
|
570
|
+
*/
|
|
571
|
+
|
|
467
572
|
/**
|
|
468
573
|
* Time Complexity: O(1)
|
|
469
574
|
* Space Complexity: O(1)
|
|
@@ -481,23 +586,23 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
481
586
|
const isNewKey = !this.has(key); // Check if the key is new
|
|
482
587
|
|
|
483
588
|
if (isWeakKey(key)) {
|
|
484
|
-
const hash = this.
|
|
485
|
-
node = this.
|
|
589
|
+
const hash = this.objHashFn(key);
|
|
590
|
+
node = this.objMap.get(hash);
|
|
486
591
|
|
|
487
592
|
if (!node && isNewKey) {
|
|
488
593
|
// Create new node
|
|
489
|
-
node = { key: <K>hash, value, prev: this.
|
|
490
|
-
this.
|
|
594
|
+
node = { key: <K>hash, value, prev: this.tail, next: this._sentinel };
|
|
595
|
+
this.objMap.set(hash, node);
|
|
491
596
|
} else if (node) {
|
|
492
597
|
// Update the value of an existing node
|
|
493
598
|
node.value = value;
|
|
494
599
|
}
|
|
495
600
|
} else {
|
|
496
|
-
const hash = this.
|
|
497
|
-
node = this.
|
|
601
|
+
const hash = this.hashFn(key);
|
|
602
|
+
node = this.noObjMap[hash];
|
|
498
603
|
|
|
499
604
|
if (!node && isNewKey) {
|
|
500
|
-
this.
|
|
605
|
+
this.noObjMap[hash] = node = { key, value, prev: this.tail, next: this._sentinel };
|
|
501
606
|
} else if (node) {
|
|
502
607
|
// Update the value of an existing node
|
|
503
608
|
node.value = value;
|
|
@@ -510,8 +615,8 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
510
615
|
this._head = node;
|
|
511
616
|
this._sentinel.next = node;
|
|
512
617
|
} else {
|
|
513
|
-
this.
|
|
514
|
-
node.prev = this.
|
|
618
|
+
this.tail.next = node;
|
|
619
|
+
node.prev = this.tail; // Make sure that the prev of the new node points to the current tail node
|
|
515
620
|
}
|
|
516
621
|
this._tail = node;
|
|
517
622
|
this._sentinel.prev = node;
|
|
@@ -546,14 +651,19 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
546
651
|
*/
|
|
547
652
|
override has(key: K): boolean {
|
|
548
653
|
if (isWeakKey(key)) {
|
|
549
|
-
const hash = this.
|
|
550
|
-
return this.
|
|
654
|
+
const hash = this.objHashFn(key);
|
|
655
|
+
return this.objMap.has(hash);
|
|
551
656
|
} else {
|
|
552
|
-
const hash = this.
|
|
553
|
-
return hash in this.
|
|
657
|
+
const hash = this.hashFn(key);
|
|
658
|
+
return hash in this.noObjMap;
|
|
554
659
|
}
|
|
555
660
|
}
|
|
556
661
|
|
|
662
|
+
/**
|
|
663
|
+
* Time Complexity: O(1)
|
|
664
|
+
* Space Complexity: O(1)
|
|
665
|
+
*/
|
|
666
|
+
|
|
557
667
|
/**
|
|
558
668
|
* Time Complexity: O(1)
|
|
559
669
|
* Space Complexity: O(1)
|
|
@@ -569,18 +679,23 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
569
679
|
*/
|
|
570
680
|
override get(key: K): V | undefined {
|
|
571
681
|
if (isWeakKey(key)) {
|
|
572
|
-
const hash = this.
|
|
573
|
-
const node = this.
|
|
682
|
+
const hash = this.objHashFn(key);
|
|
683
|
+
const node = this.objMap.get(hash);
|
|
574
684
|
return node ? node.value : undefined;
|
|
575
685
|
} else {
|
|
576
|
-
const hash = this.
|
|
577
|
-
const node = this.
|
|
686
|
+
const hash = this.hashFn(key);
|
|
687
|
+
const node = this.noObjMap[hash];
|
|
578
688
|
return node ? node.value : undefined;
|
|
579
689
|
}
|
|
580
690
|
}
|
|
581
691
|
|
|
582
692
|
/**
|
|
583
|
-
* Time Complexity: O(n)
|
|
693
|
+
* Time Complexity: O(n)
|
|
694
|
+
* Space Complexity: O(1)
|
|
695
|
+
* /
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Time Complexity: O(n)
|
|
584
699
|
* Space Complexity: O(1)
|
|
585
700
|
*
|
|
586
701
|
* The function `at` retrieves the key-value pair at a specified index in a linked list.
|
|
@@ -592,7 +707,7 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
592
707
|
*/
|
|
593
708
|
at(index: number): V | undefined {
|
|
594
709
|
rangeCheck(index, 0, this._size - 1);
|
|
595
|
-
let node = this.
|
|
710
|
+
let node = this.head;
|
|
596
711
|
while (index--) {
|
|
597
712
|
node = node.next;
|
|
598
713
|
}
|
|
@@ -600,6 +715,11 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
600
715
|
}
|
|
601
716
|
|
|
602
717
|
/**
|
|
718
|
+
* Time Complexity: O(1)
|
|
719
|
+
* Space Complexity: O(1)
|
|
720
|
+
* /
|
|
721
|
+
|
|
722
|
+
/**
|
|
603
723
|
* Time Complexity: O(1)
|
|
604
724
|
* Space Complexity: O(1)
|
|
605
725
|
*
|
|
@@ -613,27 +733,27 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
613
733
|
let node;
|
|
614
734
|
|
|
615
735
|
if (isWeakKey(key)) {
|
|
616
|
-
const hash = this.
|
|
736
|
+
const hash = this.objHashFn(key);
|
|
617
737
|
// Get nodes from WeakMap
|
|
618
|
-
node = this.
|
|
738
|
+
node = this.objMap.get(hash);
|
|
619
739
|
|
|
620
740
|
if (!node) {
|
|
621
741
|
return false; // If the node does not exist, return false
|
|
622
742
|
}
|
|
623
743
|
|
|
624
744
|
// Remove nodes from WeakMap
|
|
625
|
-
this.
|
|
745
|
+
this.objMap.delete(hash);
|
|
626
746
|
} else {
|
|
627
|
-
const hash = this.
|
|
747
|
+
const hash = this.hashFn(key);
|
|
628
748
|
// Get nodes from noObjMap
|
|
629
|
-
node = this.
|
|
749
|
+
node = this.noObjMap[hash];
|
|
630
750
|
|
|
631
751
|
if (!node) {
|
|
632
752
|
return false; // If the node does not exist, return false
|
|
633
753
|
}
|
|
634
754
|
|
|
635
755
|
// Remove nodes from orgMap
|
|
636
|
-
delete this.
|
|
756
|
+
delete this.noObjMap[hash];
|
|
637
757
|
}
|
|
638
758
|
|
|
639
759
|
// Remove node from doubly linked list
|
|
@@ -642,6 +762,11 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
642
762
|
}
|
|
643
763
|
|
|
644
764
|
/**
|
|
765
|
+
* Time Complexity: O(n)
|
|
766
|
+
* Space Complexity: O(1)
|
|
767
|
+
* /
|
|
768
|
+
|
|
769
|
+
/**
|
|
645
770
|
* Time Complexity: O(n)
|
|
646
771
|
* Space Complexity: O(1)
|
|
647
772
|
*
|
|
@@ -652,7 +777,7 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
652
777
|
*/
|
|
653
778
|
deleteAt(index: number): boolean {
|
|
654
779
|
rangeCheck(index, 0, this._size - 1);
|
|
655
|
-
let node = this.
|
|
780
|
+
let node = this.head;
|
|
656
781
|
while (index--) {
|
|
657
782
|
node = node.next;
|
|
658
783
|
}
|
|
@@ -660,6 +785,11 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
660
785
|
}
|
|
661
786
|
|
|
662
787
|
/**
|
|
788
|
+
* Time Complexity: O(1)
|
|
789
|
+
* Space Complexity: O(1)
|
|
790
|
+
* /
|
|
791
|
+
|
|
792
|
+
/**
|
|
663
793
|
* Time Complexity: O(1)
|
|
664
794
|
* Space Complexity: O(1)
|
|
665
795
|
*
|
|
@@ -682,6 +812,11 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
682
812
|
}
|
|
683
813
|
|
|
684
814
|
/**
|
|
815
|
+
* Time Complexity: O(1)
|
|
816
|
+
* Space Complexity: O(1)
|
|
817
|
+
* /
|
|
818
|
+
|
|
819
|
+
/**
|
|
685
820
|
* Time Complexity: O(1)
|
|
686
821
|
* Space Complexity: O(1)
|
|
687
822
|
*
|
|
@@ -708,7 +843,7 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
708
843
|
* of the original `LinkedHashMap` object.
|
|
709
844
|
*/
|
|
710
845
|
clone(): LinkedHashMap<K, V> {
|
|
711
|
-
const cloned = new LinkedHashMap<K, V>([], { hashFn: this.
|
|
846
|
+
const cloned = new LinkedHashMap<K, V>([], { hashFn: this.hashFn, objHashFn: this.objHashFn });
|
|
712
847
|
for (const entry of this) {
|
|
713
848
|
const [key, value] = entry;
|
|
714
849
|
cloned.set(key, value);
|
|
@@ -717,6 +852,11 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
717
852
|
}
|
|
718
853
|
|
|
719
854
|
/**
|
|
855
|
+
* Time Complexity: O(n)
|
|
856
|
+
* Space Complexity: O(n)
|
|
857
|
+
* /
|
|
858
|
+
|
|
859
|
+
/**
|
|
720
860
|
* Time Complexity: O(n)
|
|
721
861
|
* Space Complexity: O(n)
|
|
722
862
|
*
|
|
@@ -744,6 +884,11 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
744
884
|
}
|
|
745
885
|
|
|
746
886
|
/**
|
|
887
|
+
* Time Complexity: O(n)
|
|
888
|
+
* Space Complexity: O(n)
|
|
889
|
+
* /
|
|
890
|
+
|
|
891
|
+
/**
|
|
747
892
|
* Time Complexity: O(n)
|
|
748
893
|
* Space Complexity: O(n)
|
|
749
894
|
*
|
|
@@ -791,11 +936,13 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
791
936
|
return this.set(key, value);
|
|
792
937
|
}
|
|
793
938
|
|
|
794
|
-
protected _hashFn: (key: K) => string = (key: K) => String(key);
|
|
795
|
-
|
|
796
|
-
protected _objHashFn: (key: K) => object = (key: K) => <object>key;
|
|
797
|
-
|
|
798
939
|
/**
|
|
940
|
+
* Time Complexity: O(n)
|
|
941
|
+
* Space Complexity: O(1)
|
|
942
|
+
* where n is the number of entries in the LinkedHashMap.
|
|
943
|
+
* /
|
|
944
|
+
|
|
945
|
+
/**
|
|
799
946
|
* Time Complexity: O(n)
|
|
800
947
|
* Space Complexity: O(1)
|
|
801
948
|
* where n is the number of entries in the LinkedHashMap.
|
|
@@ -803,13 +950,18 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
803
950
|
* The above function is an iterator that yields key-value pairs from a linked list.
|
|
804
951
|
*/
|
|
805
952
|
protected* _getIterator() {
|
|
806
|
-
let node = this.
|
|
953
|
+
let node = this.head;
|
|
807
954
|
while (node !== this._sentinel) {
|
|
808
955
|
yield [node.key, node.value] as [K, V];
|
|
809
956
|
node = node.next;
|
|
810
957
|
}
|
|
811
958
|
}
|
|
812
959
|
|
|
960
|
+
/**
|
|
961
|
+
* Time Complexity: O(1)
|
|
962
|
+
* Space Complexity: O(1)
|
|
963
|
+
*/
|
|
964
|
+
|
|
813
965
|
/**
|
|
814
966
|
* Time Complexity: O(1)
|
|
815
967
|
* Space Complexity: O(1)
|
|
@@ -825,11 +977,11 @@ export class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBa
|
|
|
825
977
|
prev.next = next;
|
|
826
978
|
next.prev = prev;
|
|
827
979
|
|
|
828
|
-
if (node === this.
|
|
980
|
+
if (node === this.head) {
|
|
829
981
|
this._head = next;
|
|
830
982
|
}
|
|
831
983
|
|
|
832
|
-
if (node === this.
|
|
984
|
+
if (node === this.tail) {
|
|
833
985
|
this._tail = prev;
|
|
834
986
|
}
|
|
835
987
|
|