undirected-graph-typed 1.51.9 → 1.52.2
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/index.d.ts +2 -1
- package/dist/data-structures/base/index.js +2 -1
- package/dist/data-structures/base/iterable-element-base.d.ts +171 -0
- package/dist/data-structures/base/iterable-element-base.js +225 -0
- package/dist/data-structures/base/{iterable-base.d.ts → iterable-entry-base.d.ts} +4 -147
- package/dist/data-structures/base/{iterable-base.js → iterable-entry-base.js} +12 -189
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +13 -13
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +6 -6
- package/dist/data-structures/binary-tree/avl-tree.d.ts +13 -13
- package/dist/data-structures/binary-tree/avl-tree.js +6 -6
- package/dist/data-structures/binary-tree/binary-tree.d.ts +99 -99
- package/dist/data-structures/binary-tree/binary-tree.js +56 -54
- package/dist/data-structures/binary-tree/bst.d.ts +37 -45
- package/dist/data-structures/binary-tree/bst.js +19 -27
- package/dist/data-structures/binary-tree/rb-tree.d.ts +10 -10
- package/dist/data-structures/binary-tree/rb-tree.js +6 -6
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +12 -12
- package/dist/data-structures/binary-tree/tree-multi-map.js +5 -5
- package/dist/data-structures/graph/directed-graph.js +2 -1
- package/dist/data-structures/hash/hash-map.d.ts +2 -2
- package/dist/data-structures/heap/heap.d.ts +43 -114
- package/dist/data-structures/heap/heap.js +59 -127
- package/dist/data-structures/heap/max-heap.d.ts +50 -4
- package/dist/data-structures/heap/max-heap.js +76 -10
- package/dist/data-structures/heap/min-heap.d.ts +51 -5
- package/dist/data-structures/heap/min-heap.js +68 -11
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +22 -28
- package/dist/data-structures/linked-list/doubly-linked-list.js +26 -28
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +22 -25
- package/dist/data-structures/linked-list/singly-linked-list.js +29 -26
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +50 -4
- package/dist/data-structures/priority-queue/max-priority-queue.js +79 -10
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +51 -5
- package/dist/data-structures/priority-queue/min-priority-queue.js +71 -11
- package/dist/data-structures/priority-queue/priority-queue.d.ts +50 -4
- package/dist/data-structures/priority-queue/priority-queue.js +70 -1
- package/dist/data-structures/queue/deque.d.ts +27 -18
- package/dist/data-structures/queue/deque.js +43 -21
- package/dist/data-structures/queue/queue.d.ts +26 -29
- package/dist/data-structures/queue/queue.js +47 -38
- package/dist/data-structures/stack/stack.d.ts +17 -22
- package/dist/data-structures/stack/stack.js +25 -24
- package/dist/data-structures/trie/trie.d.ts +18 -13
- package/dist/data-structures/trie/trie.js +26 -15
- package/dist/interfaces/binary-tree.d.ts +4 -4
- package/dist/types/common.d.ts +1 -22
- package/dist/types/data-structures/base/base.d.ts +5 -2
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +2 -3
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +20 -4
- package/dist/types/data-structures/binary-tree/bst.d.ts +5 -3
- package/dist/types/data-structures/binary-tree/rb-tree.d.ts +2 -3
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -3
- package/dist/types/data-structures/heap/heap.d.ts +3 -2
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -1
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +2 -1
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +1 -1
- package/dist/types/data-structures/queue/deque.d.ts +4 -2
- package/dist/types/data-structures/queue/queue.d.ts +4 -1
- package/dist/types/data-structures/stack/stack.d.ts +2 -1
- package/dist/types/data-structures/trie/trie.d.ts +3 -2
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +2 -1
- package/src/data-structures/base/iterable-element-base.ts +250 -0
- package/src/data-structures/base/{iterable-base.ts → iterable-entry-base.ts} +26 -217
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +26 -26
- package/src/data-structures/binary-tree/avl-tree.ts +21 -21
- package/src/data-structures/binary-tree/binary-tree.ts +166 -161
- package/src/data-structures/binary-tree/bst.ts +61 -68
- package/src/data-structures/binary-tree/rb-tree.ts +19 -19
- package/src/data-structures/binary-tree/tree-multi-map.ts +19 -19
- package/src/data-structures/graph/abstract-graph.ts +15 -14
- package/src/data-structures/graph/directed-graph.ts +9 -7
- package/src/data-structures/graph/undirected-graph.ts +7 -6
- package/src/data-structures/hash/hash-map.ts +8 -8
- package/src/data-structures/heap/heap.ts +72 -153
- package/src/data-structures/heap/max-heap.ts +88 -13
- package/src/data-structures/heap/min-heap.ts +78 -15
- package/src/data-structures/linked-list/doubly-linked-list.ts +33 -33
- package/src/data-structures/linked-list/singly-linked-list.ts +38 -30
- package/src/data-structures/priority-queue/max-priority-queue.ts +94 -13
- package/src/data-structures/priority-queue/min-priority-queue.ts +84 -15
- package/src/data-structures/priority-queue/priority-queue.ts +81 -4
- package/src/data-structures/queue/deque.ts +53 -28
- package/src/data-structures/queue/queue.ts +61 -44
- package/src/data-structures/stack/stack.ts +32 -27
- package/src/data-structures/trie/trie.ts +34 -19
- package/src/interfaces/binary-tree.ts +4 -5
- package/src/types/common.ts +2 -24
- package/src/types/data-structures/base/base.ts +14 -6
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +2 -3
- package/src/types/data-structures/binary-tree/avl-tree.ts +2 -3
- package/src/types/data-structures/binary-tree/binary-tree.ts +24 -5
- package/src/types/data-structures/binary-tree/bst.ts +9 -3
- package/src/types/data-structures/binary-tree/rb-tree.ts +2 -3
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +2 -3
- package/src/types/data-structures/graph/abstract-graph.ts +8 -8
- package/src/types/data-structures/heap/heap.ts +4 -1
- package/src/types/data-structures/linked-list/doubly-linked-list.ts +3 -1
- package/src/types/data-structures/linked-list/singly-linked-list.ts +3 -1
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -1
- package/src/types/data-structures/queue/deque.ts +6 -1
- package/src/types/data-structures/queue/queue.ts +5 -1
- package/src/types/data-structures/stack/stack.ts +3 -1
- package/src/types/data-structures/trie/trie.ts +3 -1
- package/src/types/utils/utils.ts +4 -4
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import type { PriorityQueueOptions } from '../../types';
|
|
8
|
+
import type { Comparator, ElementCallback, PriorityQueueOptions } from '../../types';
|
|
9
9
|
import { Heap } from '../heap';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -16,16 +16,93 @@ import { Heap } from '../heap';
|
|
|
16
16
|
* 5. Huffman Coding: Used to select the smallest node combination when constructing a Huffman tree.
|
|
17
17
|
* 6. Kth Largest Element in a Data Stream: Used to maintain a min-heap of size K for quickly finding the Kth largest element in stream data
|
|
18
18
|
*/
|
|
19
|
-
export class PriorityQueue<E = any> extends Heap<E> {
|
|
19
|
+
export class PriorityQueue<E = any, R = any> extends Heap<E, R> {
|
|
20
20
|
/**
|
|
21
21
|
* The constructor initializes a priority queue with optional elements and options.
|
|
22
22
|
* @param elements - The `elements` parameter is an iterable object that contains the initial
|
|
23
|
-
* elements to be added to the priority queue. It is an optional parameter and if not provided, the
|
|
23
|
+
* elements to be added to the priority queue. It is an optional parameter, and if not provided, the
|
|
24
24
|
* priority queue will be initialized as empty.
|
|
25
25
|
* @param [options] - The `options` parameter is an optional object that can be used to customize the
|
|
26
26
|
* behavior of the priority queue. It can contain the following properties:
|
|
27
27
|
*/
|
|
28
|
-
constructor(elements: Iterable<E> = [], options?: PriorityQueueOptions<E>) {
|
|
28
|
+
constructor(elements: Iterable<E> | Iterable<R> = [], options?: PriorityQueueOptions<E, R>) {
|
|
29
29
|
super(elements, options);
|
|
30
30
|
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The `clone` function returns a new instance of the `PriorityQueue` class with the same comparator
|
|
34
|
+
* and toElementFn as the original instance.
|
|
35
|
+
* @returns The method is returning a new instance of the `PriorityQueue` class with the same
|
|
36
|
+
* elements and properties as the current instance.
|
|
37
|
+
*/
|
|
38
|
+
override clone(): PriorityQueue<E, R> {
|
|
39
|
+
return new PriorityQueue<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Time Complexity: O(n)
|
|
44
|
+
* Space Complexity: O(n)
|
|
45
|
+
*
|
|
46
|
+
* The `filter` function creates a new PriorityQueue object containing elements that pass a given callback
|
|
47
|
+
* function.
|
|
48
|
+
* @param callback - The `callback` parameter is a function that will be called for each element in
|
|
49
|
+
* the heap. It takes three arguments: the current element, the index of the current element, and the
|
|
50
|
+
* heap itself. The callback function should return a boolean value indicating whether the current
|
|
51
|
+
* element should be included in the filtered list
|
|
52
|
+
* @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
|
|
53
|
+
* to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be
|
|
54
|
+
* passed as the `this` value to the `callback` function. If `thisArg` is
|
|
55
|
+
* @returns The `filter` method is returning a new `PriorityQueue` object that contains the elements that pass
|
|
56
|
+
* the filter condition specified by the `callback` function.
|
|
57
|
+
*/
|
|
58
|
+
override filter(callback: ElementCallback<E, R, boolean, PriorityQueue<E, R>>, thisArg?: any): PriorityQueue<E, R> {
|
|
59
|
+
const filteredPriorityQueue = new PriorityQueue<E, R>([], {
|
|
60
|
+
toElementFn: this.toElementFn,
|
|
61
|
+
comparator: this.comparator
|
|
62
|
+
});
|
|
63
|
+
let index = 0;
|
|
64
|
+
for (const current of this) {
|
|
65
|
+
if (callback.call(thisArg, current, index, this)) {
|
|
66
|
+
filteredPriorityQueue.add(current);
|
|
67
|
+
}
|
|
68
|
+
index++;
|
|
69
|
+
}
|
|
70
|
+
return filteredPriorityQueue;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Time Complexity: O(n log n)
|
|
75
|
+
* Space Complexity: O(n)
|
|
76
|
+
*
|
|
77
|
+
* The `map` function creates a new heap by applying a callback function to each element of the
|
|
78
|
+
* original heap.
|
|
79
|
+
* @param callback - The `callback` parameter is a function that will be called for each element in
|
|
80
|
+
* the heap. It takes three arguments: `el` (the current element), `index` (the index of the current
|
|
81
|
+
* element), and `this` (the heap itself). The callback function should return a value of
|
|
82
|
+
* @param comparator - The `comparator` parameter is a function that defines the order of the
|
|
83
|
+
* elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number
|
|
84
|
+
* if `a` should be placed before `b`, a positive number if `a` should be placed after
|
|
85
|
+
* @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw
|
|
86
|
+
* element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and
|
|
87
|
+
* returns a value of type `T`. This function is used to transform the elements of the original
|
|
88
|
+
* @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
|
|
89
|
+
* specify the value of `this` within the callback function. It is used to set the context or scope
|
|
90
|
+
* in which the callback function will be executed. If `thisArg` is provided, it will be used as the
|
|
91
|
+
* value of
|
|
92
|
+
* @returns a new instance of the `PriorityQueue` class with the mapped elements.
|
|
93
|
+
*/
|
|
94
|
+
override map<EM, RM>(
|
|
95
|
+
callback: ElementCallback<E, R, EM, PriorityQueue<E, R>>,
|
|
96
|
+
comparator: Comparator<EM>,
|
|
97
|
+
toElementFn?: (rawElement: RM) => EM,
|
|
98
|
+
thisArg?: any
|
|
99
|
+
): PriorityQueue<EM, RM> {
|
|
100
|
+
const mappedPriorityQueue: PriorityQueue<EM, RM> = new PriorityQueue<EM, RM>([], { comparator, toElementFn });
|
|
101
|
+
let index = 0;
|
|
102
|
+
for (const el of this) {
|
|
103
|
+
mappedPriorityQueue.add(callback.call(thisArg, el, index, this));
|
|
104
|
+
index++;
|
|
105
|
+
}
|
|
106
|
+
return mappedPriorityQueue;
|
|
107
|
+
}
|
|
31
108
|
}
|
|
@@ -16,9 +16,9 @@ import { calcMinUnitsRequired, rangeCheck } from '../../utils';
|
|
|
16
16
|
* 4. Efficiency: Adding and removing elements at both ends of a deque is usually very fast. However, when the dynamic array needs to expand, it may involve copying the entire array to a larger one, and this operation has a time complexity of O(n).
|
|
17
17
|
* 5. Performance jitter: Deque may experience performance jitter, but DoublyLinkedList will not
|
|
18
18
|
*/
|
|
19
|
-
export class Deque<E> extends IterableElementBase<E
|
|
19
|
+
export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E, R>> {
|
|
20
20
|
/**
|
|
21
|
-
* The constructor initializes a Deque object with
|
|
21
|
+
* The constructor initializes a Deque object with optional iterable of elements and options.
|
|
22
22
|
* @param elements - An iterable object (such as an array or a Set) that contains the initial
|
|
23
23
|
* elements to be added to the deque. It can also be an object with a `length` or `size` property
|
|
24
24
|
* that represents the number of elements in the iterable object. If no elements are provided, an
|
|
@@ -28,12 +28,13 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
28
28
|
* which determines the size of each bucket in the deque. If the `bucketSize` option is not provided
|
|
29
29
|
* or is not a number
|
|
30
30
|
*/
|
|
31
|
-
constructor(elements: IterableWithSizeOrLength<E> = [], options?: DequeOptions) {
|
|
32
|
-
super();
|
|
31
|
+
constructor(elements: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R> = [], options?: DequeOptions<E, R>) {
|
|
32
|
+
super(options);
|
|
33
33
|
|
|
34
34
|
if (options) {
|
|
35
|
-
const { bucketSize } = options;
|
|
35
|
+
const { bucketSize, maxLen } = options;
|
|
36
36
|
if (typeof bucketSize === 'number') this._bucketSize = bucketSize;
|
|
37
|
+
if (typeof maxLen === 'number' && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
let _size: number;
|
|
@@ -53,8 +54,12 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
53
54
|
this._bucketFirst = this._bucketLast = (this._bucketCount >> 1) - (needBucketNum >> 1);
|
|
54
55
|
this._firstInBucket = this._lastInBucket = (this._bucketSize - (_size % this._bucketSize)) >> 1;
|
|
55
56
|
|
|
56
|
-
for (const
|
|
57
|
-
this.
|
|
57
|
+
for (const el of elements) {
|
|
58
|
+
if (this.toElementFn) {
|
|
59
|
+
this.push(this.toElementFn(el as R));
|
|
60
|
+
} else {
|
|
61
|
+
this.push(el as E);
|
|
62
|
+
}
|
|
58
63
|
}
|
|
59
64
|
}
|
|
60
65
|
|
|
@@ -69,6 +74,17 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
69
74
|
return this._bucketSize;
|
|
70
75
|
}
|
|
71
76
|
|
|
77
|
+
protected _maxLen: number = -1;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The maxLen function returns the max length of the deque.
|
|
81
|
+
*
|
|
82
|
+
* @return The max length of the deque
|
|
83
|
+
*/
|
|
84
|
+
get maxLen() {
|
|
85
|
+
return this._maxLen;
|
|
86
|
+
}
|
|
87
|
+
|
|
72
88
|
protected _bucketFirst = 0;
|
|
73
89
|
|
|
74
90
|
/**
|
|
@@ -189,6 +205,7 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
189
205
|
}
|
|
190
206
|
this._size += 1;
|
|
191
207
|
this._buckets[this._bucketLast][this._lastInBucket] = element;
|
|
208
|
+
if (this._maxLen > 0 && this._size > this._maxLen) this.shift();
|
|
192
209
|
return true;
|
|
193
210
|
}
|
|
194
211
|
|
|
@@ -253,6 +270,7 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
253
270
|
}
|
|
254
271
|
this._size += 1;
|
|
255
272
|
this._buckets[this._bucketFirst][this._firstInBucket] = element;
|
|
273
|
+
if (this._maxLen > 0 && this._size > this._maxLen) this.pop();
|
|
256
274
|
return true;
|
|
257
275
|
}
|
|
258
276
|
|
|
@@ -326,7 +344,7 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
326
344
|
/**
|
|
327
345
|
* The below function is a generator that yields elements from a collection one by one.
|
|
328
346
|
*/
|
|
329
|
-
*
|
|
347
|
+
*begin(): Generator<E> {
|
|
330
348
|
let index = 0;
|
|
331
349
|
while (index < this.size) {
|
|
332
350
|
yield this.at(index);
|
|
@@ -338,7 +356,7 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
338
356
|
* The function `reverseBegin()` is a generator that yields elements in reverse order starting from
|
|
339
357
|
* the last element.
|
|
340
358
|
*/
|
|
341
|
-
*
|
|
359
|
+
*reverseBegin(): Generator<E> {
|
|
342
360
|
let index = this.size - 1;
|
|
343
361
|
while (index >= 0) {
|
|
344
362
|
yield this.at(index);
|
|
@@ -747,8 +765,8 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
747
765
|
* @returns The `clone()` method is returning a new instance of the `Deque` class with the same
|
|
748
766
|
* elements as the original deque (`this`) and the same bucket size.
|
|
749
767
|
*/
|
|
750
|
-
clone(): Deque<E> {
|
|
751
|
-
return new Deque<E>(
|
|
768
|
+
clone(): Deque<E, R> {
|
|
769
|
+
return new Deque<E, R>(this, { bucketSize: this.bucketSize, toElementFn: this.toElementFn });
|
|
752
770
|
}
|
|
753
771
|
|
|
754
772
|
/**
|
|
@@ -772,8 +790,8 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
772
790
|
* @returns The `filter` method is returning a new `Deque` object that contains the elements that
|
|
773
791
|
* satisfy the given predicate function.
|
|
774
792
|
*/
|
|
775
|
-
filter(predicate: ElementCallback<E, boolean
|
|
776
|
-
const newDeque = new Deque<E>([], { bucketSize: this._bucketSize });
|
|
793
|
+
filter(predicate: ElementCallback<E, R, boolean, Deque<E, R>>, thisArg?: any): Deque<E, R> {
|
|
794
|
+
const newDeque = new Deque<E, R>([], { bucketSize: this._bucketSize, toElementFn: this.toElementFn });
|
|
777
795
|
let index = 0;
|
|
778
796
|
for (const el of this) {
|
|
779
797
|
if (predicate.call(thisArg, el, index, this)) {
|
|
@@ -788,21 +806,28 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
788
806
|
* Time Complexity: O(n)
|
|
789
807
|
* Space Complexity: O(n)
|
|
790
808
|
*/
|
|
809
|
+
|
|
791
810
|
/**
|
|
792
|
-
*
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
*
|
|
796
|
-
*
|
|
797
|
-
* @param
|
|
798
|
-
* the
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
811
|
+
* The `map` function takes a callback function and applies it to each element in the deque,
|
|
812
|
+
* returning a new deque with the results.
|
|
813
|
+
* @param callback - The callback parameter is a function that will be called for each element in the
|
|
814
|
+
* deque. It takes three arguments: the current element, the index of the element, and the deque
|
|
815
|
+
* itself. It should return a value of type EM.
|
|
816
|
+
* @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to
|
|
817
|
+
* transform the raw element (`RM`) into a new element (`EM`) before adding it to the new deque. If
|
|
818
|
+
* provided, this function will be called for each raw element in the original deque.
|
|
819
|
+
* @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
|
|
820
|
+
* specify the value of `this` within the callback function. It is used to set the context or scope
|
|
821
|
+
* in which the callback function will be executed. If `thisArg` is provided, it will be used as the
|
|
822
|
+
* value of
|
|
823
|
+
* @returns a new Deque object with elements of type EM and raw elements of type RM.
|
|
824
|
+
*/
|
|
825
|
+
map<EM, RM>(
|
|
826
|
+
callback: ElementCallback<E, R, EM, Deque<E, R>>,
|
|
827
|
+
toElementFn?: (rawElement: RM) => EM,
|
|
828
|
+
thisArg?: any
|
|
829
|
+
): Deque<EM, RM> {
|
|
830
|
+
const newDeque = new Deque<EM, RM>([], { bucketSize: this._bucketSize, toElementFn });
|
|
806
831
|
let index = 0;
|
|
807
832
|
for (const el of this) {
|
|
808
833
|
newDeque.push(callback.call(thisArg, el, index, this));
|
|
@@ -823,7 +848,7 @@ export class Deque<E> extends IterableElementBase<E> {
|
|
|
823
848
|
* The above function is an implementation of the iterator protocol in TypeScript, allowing the
|
|
824
849
|
* object to be iterated over using a for...of loop.
|
|
825
850
|
*/
|
|
826
|
-
protected*
|
|
851
|
+
protected *_getIterator(): IterableIterator<E> {
|
|
827
852
|
for (let i = 0; i < this.size; ++i) {
|
|
828
853
|
yield this.at(i);
|
|
829
854
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @copyright Tyler Zeng <zrwusa@gmail.com>
|
|
4
4
|
* @class
|
|
5
5
|
*/
|
|
6
|
-
import type { ElementCallback } from '../../types';
|
|
6
|
+
import type { ElementCallback, QueueOptions } from '../../types';
|
|
7
7
|
import { IterableElementBase } from '../base';
|
|
8
8
|
import { SinglyLinkedList } from '../linked-list';
|
|
9
9
|
|
|
@@ -16,17 +16,20 @@ import { SinglyLinkedList } from '../linked-list';
|
|
|
16
16
|
* 6. Breadth-First Search (BFS): In traversal algorithms for graphs and trees, queues store elements that are to be visited.
|
|
17
17
|
* 7. Real-time Queuing: Like queuing systems in banks or supermarkets.
|
|
18
18
|
*/
|
|
19
|
-
export class Queue<E = any> extends IterableElementBase<E
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
export class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E, R>> {
|
|
20
|
+
constructor(elements: Iterable<E> | Iterable<R> = [], options?: QueueOptions<E, R>) {
|
|
21
|
+
super(options);
|
|
22
|
+
|
|
23
|
+
if (options) {
|
|
24
|
+
const { autoCompactRatio = 0.5 } = options;
|
|
25
|
+
this._autoCompactRatio = autoCompactRatio;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
28
|
if (elements) {
|
|
29
|
-
for (const el of elements)
|
|
29
|
+
for (const el of elements) {
|
|
30
|
+
if (this.toElementFn) this.push(this.toElementFn(el as R));
|
|
31
|
+
else this.push(el as E);
|
|
32
|
+
}
|
|
30
33
|
}
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -92,6 +95,25 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
92
95
|
return this.size > 0 ? this.elements[this.elements.length - 1] : undefined;
|
|
93
96
|
}
|
|
94
97
|
|
|
98
|
+
_autoCompactRatio: number = 0.5;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* This function returns the value of the autoCompactRatio property.
|
|
102
|
+
* @returns The `autoCompactRatio` property of the object, which is a number.
|
|
103
|
+
*/
|
|
104
|
+
get autoCompactRatio(): number {
|
|
105
|
+
return this._autoCompactRatio;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* The above function sets the autoCompactRatio property to a specified number in TypeScript.
|
|
110
|
+
* @param {number} v - The parameter `v` represents the value that will be assigned to the
|
|
111
|
+
* `_autoCompactRatio` property.
|
|
112
|
+
*/
|
|
113
|
+
set autoCompactRatio(v: number) {
|
|
114
|
+
this._autoCompactRatio = v;
|
|
115
|
+
}
|
|
116
|
+
|
|
95
117
|
/**
|
|
96
118
|
* Time Complexity: O(n)
|
|
97
119
|
* Space Complexity: O(n)
|
|
@@ -103,7 +125,6 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
103
125
|
*
|
|
104
126
|
* The function "fromArray" creates a new Queue object from an array of elements.Creates a queue from an existing array.
|
|
105
127
|
* @public
|
|
106
|
-
* @static
|
|
107
128
|
* @param {E[]} elements - The "elements" parameter is an array of elements of type E.
|
|
108
129
|
* @returns The method is returning a new instance of the Queue class, initialized with the elements from the input
|
|
109
130
|
* array.
|
|
@@ -149,12 +170,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
149
170
|
const first = this.first;
|
|
150
171
|
this._offset += 1;
|
|
151
172
|
|
|
152
|
-
if (this.offset
|
|
153
|
-
|
|
154
|
-
// only delete dequeued elements when reaching half size
|
|
155
|
-
// to decrease latency of shifting elements.
|
|
156
|
-
this._elements = this.elements.slice(this.offset);
|
|
157
|
-
this._offset = 0;
|
|
173
|
+
if (this.offset / this.elements.length > this.autoCompactRatio) this.compact();
|
|
158
174
|
return first;
|
|
159
175
|
}
|
|
160
176
|
|
|
@@ -190,7 +206,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
190
206
|
* @param index
|
|
191
207
|
*/
|
|
192
208
|
at(index: number): E | undefined {
|
|
193
|
-
return this.elements[index];
|
|
209
|
+
return this.elements[index + this._offset];
|
|
194
210
|
}
|
|
195
211
|
|
|
196
212
|
/**
|
|
@@ -241,6 +257,17 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
241
257
|
this._offset = 0;
|
|
242
258
|
}
|
|
243
259
|
|
|
260
|
+
/**
|
|
261
|
+
* The `compact` function in TypeScript slices the elements array based on the offset and resets the
|
|
262
|
+
* offset to zero.
|
|
263
|
+
* @returns The `compact()` method is returning a boolean value of `true`.
|
|
264
|
+
*/
|
|
265
|
+
compact(): boolean {
|
|
266
|
+
this._elements = this.elements.slice(this.offset);
|
|
267
|
+
this._offset = 0;
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
|
|
244
271
|
/**
|
|
245
272
|
* Time Complexity: O(n)
|
|
246
273
|
* Space Complexity: O(n)
|
|
@@ -254,8 +281,8 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
254
281
|
* The `clone()` function returns a new Queue object with the same elements as the original Queue.
|
|
255
282
|
* @returns The `clone()` method is returning a new instance of the `Queue` class.
|
|
256
283
|
*/
|
|
257
|
-
clone(): Queue<E> {
|
|
258
|
-
return new Queue(this.elements.slice(this.offset));
|
|
284
|
+
clone(): Queue<E, R> {
|
|
285
|
+
return new Queue(this.elements.slice(this.offset), { toElementFn: this.toElementFn });
|
|
259
286
|
}
|
|
260
287
|
|
|
261
288
|
/**
|
|
@@ -279,8 +306,8 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
279
306
|
* @returns The `filter` method is returning a new `Queue` object that contains the elements that
|
|
280
307
|
* satisfy the given predicate function.
|
|
281
308
|
*/
|
|
282
|
-
filter(predicate: ElementCallback<E, boolean
|
|
283
|
-
const newDeque = new Queue<E>([]);
|
|
309
|
+
filter(predicate: ElementCallback<E, R, boolean, Queue<E, R>>, thisArg?: any): Queue<E, R> {
|
|
310
|
+
const newDeque = new Queue<E, R>([], { toElementFn: this.toElementFn });
|
|
284
311
|
let index = 0;
|
|
285
312
|
for (const el of this) {
|
|
286
313
|
if (predicate.call(thisArg, el, index, this)) {
|
|
@@ -296,22 +323,12 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
296
323
|
* Space Complexity: O(n)
|
|
297
324
|
*/
|
|
298
325
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
* @param callback - The callback parameter is a function that will be called for each element in the
|
|
306
|
-
* queue. It takes three arguments: the current element, the index of the current element, and the
|
|
307
|
-
* queue itself. The callback function should return a new value that will be added to the new queue.
|
|
308
|
-
* @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
|
|
309
|
-
* to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be
|
|
310
|
-
* passed as the `this` value to the `callback` function. If `thisArg` is
|
|
311
|
-
* @returns The `map` function is returning a new `Queue` object with the transformed elements.
|
|
312
|
-
*/
|
|
313
|
-
map<T>(callback: ElementCallback<E, T>, thisArg?: any): Queue<T> {
|
|
314
|
-
const newDeque = new Queue<T>([]);
|
|
326
|
+
map<EM, RM>(
|
|
327
|
+
callback: ElementCallback<E, R, EM, Queue<E, R>>,
|
|
328
|
+
toElementFn?: (rawElement: RM) => EM,
|
|
329
|
+
thisArg?: any
|
|
330
|
+
): Queue<EM, RM> {
|
|
331
|
+
const newDeque = new Queue<EM, RM>([], { toElementFn });
|
|
315
332
|
let index = 0;
|
|
316
333
|
for (const el of this) {
|
|
317
334
|
newDeque.push(callback.call(thisArg, el, index, this));
|
|
@@ -331,8 +348,8 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
331
348
|
*
|
|
332
349
|
* The function `_getIterator` returns an iterable iterator for the elements in the class.
|
|
333
350
|
*/
|
|
334
|
-
protected*
|
|
335
|
-
for (const item of this.elements) {
|
|
351
|
+
protected *_getIterator(): IterableIterator<E> {
|
|
352
|
+
for (const item of this.elements.slice(this.offset)) {
|
|
336
353
|
yield item;
|
|
337
354
|
}
|
|
338
355
|
}
|
|
@@ -344,7 +361,7 @@ export class Queue<E = any> extends IterableElementBase<E> {
|
|
|
344
361
|
* 3. Memory Usage: Since each element requires additional space to store a pointer to the next element, linked lists may use more memory compared to arrays.
|
|
345
362
|
* 4. Frequent Enqueuing and Dequeuing Operations: If your application involves frequent enqueuing and dequeuing operations and is less concerned with random access, then LinkedListQueue is a good choice.
|
|
346
363
|
*/
|
|
347
|
-
export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
|
|
364
|
+
export class LinkedListQueue<E = any, R = any> extends SinglyLinkedList<E, R> {
|
|
348
365
|
/**
|
|
349
366
|
* Time Complexity: O(n)
|
|
350
367
|
* Space Complexity: O(n)
|
|
@@ -358,7 +375,7 @@ export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
|
|
|
358
375
|
* @returns The `clone()` method is returning a new instance of `LinkedListQueue` with the same
|
|
359
376
|
* values as the original `LinkedListQueue`.
|
|
360
377
|
*/
|
|
361
|
-
override clone(): LinkedListQueue<E> {
|
|
362
|
-
return new LinkedListQueue<E>(this.
|
|
378
|
+
override clone(): LinkedListQueue<E, R> {
|
|
379
|
+
return new LinkedListQueue<E, R>(this, { toElementFn: this.toElementFn });
|
|
363
380
|
}
|
|
364
381
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
-
import type { ElementCallback } from '../../types';
|
|
8
|
+
import type { ElementCallback, StackOptions } from '../../types';
|
|
9
9
|
import { IterableElementBase } from '../base';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -16,17 +16,17 @@ import { IterableElementBase } from '../base';
|
|
|
16
16
|
* 5. Expression Evaluation: Used for the evaluation of arithmetic or logical expressions, especially when dealing with parenthesis matching and operator precedence.
|
|
17
17
|
* 6. Backtracking Algorithms: In problems where multiple branches need to be explored but only one branch can be explored at a time, stacks can be used to save the state at each branching point.
|
|
18
18
|
*/
|
|
19
|
-
export class Stack<E = any> extends IterableElementBase<E
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* @param {E[]} [elements] - The `elements` parameter is an optional parameter of type `E[]`, which represents an array
|
|
23
|
-
* of elements of type `E`. It is used to initialize the `_elements` property of the class. If the `elements` parameter
|
|
24
|
-
* is provided and is an array, it is assigned to the `_elements
|
|
25
|
-
*/
|
|
26
|
-
constructor(elements: Iterable<E> = []) {
|
|
27
|
-
super();
|
|
19
|
+
export class Stack<E = any, R = any> extends IterableElementBase<E, R, Stack<E, R>> {
|
|
20
|
+
constructor(elements: Iterable<E> | Iterable<R> = [], options?: StackOptions<E, R>) {
|
|
21
|
+
super(options);
|
|
28
22
|
if (elements) {
|
|
29
|
-
for (const el of elements)
|
|
23
|
+
for (const el of elements) {
|
|
24
|
+
if (this.toElementFn) {
|
|
25
|
+
this.push(this.toElementFn(el as R));
|
|
26
|
+
} else {
|
|
27
|
+
this.push(el as E);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -192,8 +192,8 @@ export class Stack<E = any> extends IterableElementBase<E> {
|
|
|
192
192
|
* The `clone()` function returns a new `Stack` object with the same elements as the original stack.
|
|
193
193
|
* @returns The `clone()` method is returning a new `Stack` object with a copy of the `_elements` array.
|
|
194
194
|
*/
|
|
195
|
-
clone(): Stack<E> {
|
|
196
|
-
return new Stack(this.
|
|
195
|
+
clone(): Stack<E, R> {
|
|
196
|
+
return new Stack<E, R>(this, { toElementFn: this.toElementFn });
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
/**
|
|
@@ -217,8 +217,8 @@ export class Stack<E = any> extends IterableElementBase<E> {
|
|
|
217
217
|
* @returns The `filter` method is returning a new `Stack` object that contains the elements that
|
|
218
218
|
* satisfy the given predicate function.
|
|
219
219
|
*/
|
|
220
|
-
filter(predicate: ElementCallback<E, boolean
|
|
221
|
-
const newStack = new Stack<E>();
|
|
220
|
+
filter(predicate: ElementCallback<E, R, boolean, Stack<E, R>>, thisArg?: any): Stack<E, R> {
|
|
221
|
+
const newStack = new Stack<E, R>([], { toElementFn: this.toElementFn });
|
|
222
222
|
let index = 0;
|
|
223
223
|
for (const el of this) {
|
|
224
224
|
if (predicate.call(thisArg, el, index, this)) {
|
|
@@ -235,20 +235,25 @@ export class Stack<E = any> extends IterableElementBase<E> {
|
|
|
235
235
|
*/
|
|
236
236
|
|
|
237
237
|
/**
|
|
238
|
-
* Time Complexity: O(n)
|
|
239
|
-
* Space Complexity: O(n)
|
|
240
|
-
*
|
|
241
238
|
* The `map` function takes a callback function and applies it to each element in the stack,
|
|
242
239
|
* returning a new stack with the results.
|
|
243
|
-
* @param callback - The
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* @
|
|
240
|
+
* @param callback - The callback parameter is a function that will be called for each element in the
|
|
241
|
+
* stack. It takes three arguments: the current element, the index of the element, and the stack
|
|
242
|
+
* itself. It should return a new value that will be added to the new stack.
|
|
243
|
+
* @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to
|
|
244
|
+
* transform the raw element (`RM`) into a new element (`EM`) before pushing it into the new stack.
|
|
245
|
+
* @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
|
|
246
|
+
* specify the value of `this` within the callback function. It is used to set the context or scope
|
|
247
|
+
* in which the callback function will be executed. If `thisArg` is provided, it will be used as the
|
|
248
|
+
* value of
|
|
249
|
+
* @returns a new Stack object with elements of type EM and raw elements of type RM.
|
|
249
250
|
*/
|
|
250
|
-
map<
|
|
251
|
-
|
|
251
|
+
map<EM, RM>(
|
|
252
|
+
callback: ElementCallback<E, R, EM, Stack<E, R>>,
|
|
253
|
+
toElementFn?: (rawElement: RM) => EM,
|
|
254
|
+
thisArg?: any
|
|
255
|
+
): Stack<EM, RM> {
|
|
256
|
+
const newStack = new Stack<EM, RM>([], { toElementFn });
|
|
252
257
|
let index = 0;
|
|
253
258
|
for (const el of this) {
|
|
254
259
|
newStack.push(callback.call(thisArg, el, index, this));
|
|
@@ -269,7 +274,7 @@ export class Stack<E = any> extends IterableElementBase<E> {
|
|
|
269
274
|
* Custom iterator for the Stack class.
|
|
270
275
|
* @returns An iterator object.
|
|
271
276
|
*/
|
|
272
|
-
protected*
|
|
277
|
+
protected *_getIterator(): IterableIterator<E> {
|
|
273
278
|
for (let i = 0; i < this.elements.length; i++) {
|
|
274
279
|
yield this.elements[i];
|
|
275
280
|
}
|