stack-typed 1.54.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-structures/base/iterable-element-base.d.ts +14 -40
- package/dist/data-structures/base/iterable-element-base.js +14 -11
- package/dist/data-structures/base/linear-base.d.ts +277 -0
- package/dist/data-structures/base/linear-base.js +552 -0
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +12 -8
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +50 -37
- package/dist/data-structures/binary-tree/avl-tree.d.ts +64 -0
- package/dist/data-structures/binary-tree/avl-tree.js +64 -0
- package/dist/data-structures/binary-tree/binary-tree.js +5 -5
- package/dist/data-structures/binary-tree/bst.js +11 -11
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +175 -14
- package/dist/data-structures/binary-tree/tree-multi-map.js +210 -40
- package/dist/data-structures/graph/abstract-graph.js +2 -2
- package/dist/data-structures/heap/heap.d.ts +3 -11
- package/dist/data-structures/heap/heap.js +0 -10
- package/dist/data-structures/heap/max-heap.d.ts +2 -2
- package/dist/data-structures/heap/min-heap.d.ts +2 -2
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
- package/dist/data-structures/linked-list/doubly-linked-list.js +131 -146
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +79 -75
- package/dist/data-structures/linked-list/singly-linked-list.js +217 -169
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
- package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -2
- package/dist/data-structures/queue/deque.d.ts +130 -91
- package/dist/data-structures/queue/deque.js +269 -169
- package/dist/data-structures/queue/queue.d.ts +84 -40
- package/dist/data-structures/queue/queue.js +134 -50
- package/dist/data-structures/stack/stack.d.ts +3 -11
- package/dist/data-structures/stack/stack.js +0 -10
- package/dist/data-structures/trie/trie.d.ts +4 -3
- package/dist/data-structures/trie/trie.js +3 -0
- package/dist/types/data-structures/base/base.d.ts +9 -4
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
- package/dist/types/data-structures/queue/deque.d.ts +2 -3
- package/dist/types/data-structures/queue/queue.d.ts +2 -2
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +29 -20
- package/src/data-structures/base/linear-base.ts +649 -0
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +51 -36
- package/src/data-structures/binary-tree/avl-tree.ts +64 -0
- package/src/data-structures/binary-tree/binary-tree.ts +5 -5
- package/src/data-structures/binary-tree/bst.ts +9 -9
- package/src/data-structures/binary-tree/tree-multi-map.ts +214 -40
- package/src/data-structures/graph/abstract-graph.ts +2 -2
- package/src/data-structures/heap/heap.ts +3 -14
- package/src/data-structures/heap/max-heap.ts +2 -2
- package/src/data-structures/heap/min-heap.ts +2 -2
- package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
- package/src/data-structures/linked-list/singly-linked-list.ts +241 -185
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
- package/src/data-structures/priority-queue/priority-queue.ts +2 -2
- package/src/data-structures/queue/deque.ts +286 -183
- package/src/data-structures/queue/queue.ts +149 -63
- package/src/data-structures/stack/stack.ts +3 -18
- package/src/data-structures/trie/trie.ts +7 -3
- package/src/types/data-structures/base/base.ts +17 -8
- package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
- package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
- package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
- package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
- package/src/types/data-structures/queue/deque.ts +2 -3
- package/src/types/data-structures/queue/queue.ts +2 -2
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
import type { DequeOptions, ElementCallback, IterableWithSizeOrLength } from '../../types';
|
|
9
|
-
import { IterableElementBase } from '../base';
|
|
10
9
|
import { calcMinUnitsRequired, rangeCheck } from '../../utils';
|
|
10
|
+
import { LinearBase } from '../base/linear-base';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* 1. Operations at Both Ends: Supports adding and removing elements at both the front and back of the queue. This allows it to be used as a stack (last in, first out) and a queue (first in, first out).
|
|
@@ -15,8 +15,96 @@ import { calcMinUnitsRequired, rangeCheck } from '../../utils';
|
|
|
15
15
|
* 3. Continuous Memory Allocation: Since it is based on an array, all elements are stored contiguously in memory, which can bring cache friendliness and efficient memory access.
|
|
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
|
+
* @example
|
|
19
|
+
* // prize roulette
|
|
20
|
+
* class PrizeRoulette {
|
|
21
|
+
* private deque: Deque<string>;
|
|
22
|
+
*
|
|
23
|
+
* constructor(prizes: string[]) {
|
|
24
|
+
* // Initialize the deque with prizes
|
|
25
|
+
* this.deque = new Deque<string>(prizes);
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* // Rotate clockwise to the right (forward)
|
|
29
|
+
* rotateClockwise(steps: number): void {
|
|
30
|
+
* const n = this.deque.length;
|
|
31
|
+
* if (n === 0) return;
|
|
32
|
+
*
|
|
33
|
+
* for (let i = 0; i < steps; i++) {
|
|
34
|
+
* const last = this.deque.pop(); // Remove the last element
|
|
35
|
+
* this.deque.unshift(last!); // Add it to the front
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* // Rotate counterclockwise to the left (backward)
|
|
40
|
+
* rotateCounterClockwise(steps: number): void {
|
|
41
|
+
* const n = this.deque.length;
|
|
42
|
+
* if (n === 0) return;
|
|
43
|
+
*
|
|
44
|
+
* for (let i = 0; i < steps; i++) {
|
|
45
|
+
* const first = this.deque.shift(); // Remove the first element
|
|
46
|
+
* this.deque.push(first!); // Add it to the back
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* // Display the current prize at the head
|
|
51
|
+
* display() {
|
|
52
|
+
* return this.deque.first;
|
|
53
|
+
* }
|
|
54
|
+
* }
|
|
55
|
+
*
|
|
56
|
+
* // Example usage
|
|
57
|
+
* const prizes = ['Car', 'Bike', 'Laptop', 'Phone', 'Watch', 'Headphones']; // Initialize the prize list
|
|
58
|
+
* const roulette = new PrizeRoulette(prizes);
|
|
59
|
+
*
|
|
60
|
+
* // Display the initial state
|
|
61
|
+
* console.log(roulette.display()); // 'Car' // Car
|
|
62
|
+
*
|
|
63
|
+
* // Rotate clockwise by 3 steps
|
|
64
|
+
* roulette.rotateClockwise(3);
|
|
65
|
+
* console.log(roulette.display()); // 'Phone' // Phone
|
|
66
|
+
*
|
|
67
|
+
* // Rotate counterclockwise by 2 steps
|
|
68
|
+
* roulette.rotateCounterClockwise(2);
|
|
69
|
+
* console.log(roulette.display()); // 'Headphones'
|
|
70
|
+
* @example
|
|
71
|
+
* // sliding window
|
|
72
|
+
* // Maximum function of sliding window
|
|
73
|
+
* function maxSlidingWindow(nums: number[], k: number): number[] {
|
|
74
|
+
* const n = nums.length;
|
|
75
|
+
* if (n * k === 0) return [];
|
|
76
|
+
*
|
|
77
|
+
* const deq = new Deque<number>();
|
|
78
|
+
* const result: number[] = [];
|
|
79
|
+
*
|
|
80
|
+
* for (let i = 0; i < n; i++) {
|
|
81
|
+
* // Delete indexes in the queue that are not within the window range
|
|
82
|
+
* if (deq.length > 0 && deq.first! === i - k) {
|
|
83
|
+
* deq.shift();
|
|
84
|
+
* }
|
|
85
|
+
*
|
|
86
|
+
* // Remove all indices less than the current value from the tail of the queue
|
|
87
|
+
* while (deq.length > 0 && nums[deq.last!] < nums[i]) {
|
|
88
|
+
* deq.pop();
|
|
89
|
+
* }
|
|
90
|
+
*
|
|
91
|
+
* // Add the current index to the end of the queue
|
|
92
|
+
* deq.push(i);
|
|
93
|
+
*
|
|
94
|
+
* // Add the maximum value of the window to the results
|
|
95
|
+
* if (i >= k - 1) {
|
|
96
|
+
* result.push(nums[deq.first!]);
|
|
97
|
+
* }
|
|
98
|
+
* }
|
|
99
|
+
*
|
|
100
|
+
* return result;
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* const nums = [1, 3, -1, -3, 5, 3, 6, 7];
|
|
104
|
+
* const k = 3;
|
|
105
|
+
* console.log(maxSlidingWindow(nums, k)); // [3, 3, 5, 5, 6, 7]
|
|
18
106
|
*/
|
|
19
|
-
export class Deque<E = any, R = any> extends
|
|
107
|
+
export class Deque<E = any, R = any> extends LinearBase<E, R> {
|
|
20
108
|
/**
|
|
21
109
|
* The constructor initializes a Deque object with optional iterable of elements and options.
|
|
22
110
|
* @param elements - An iterable object (such as an array or a Set) that contains the initial
|
|
@@ -32,9 +120,8 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
32
120
|
super(options);
|
|
33
121
|
|
|
34
122
|
if (options) {
|
|
35
|
-
const { bucketSize
|
|
123
|
+
const { bucketSize } = options;
|
|
36
124
|
if (typeof bucketSize === 'number') this._bucketSize = bucketSize;
|
|
37
|
-
if (typeof maxLen === 'number' && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
38
125
|
}
|
|
39
126
|
|
|
40
127
|
let _size: number;
|
|
@@ -58,96 +145,50 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
58
145
|
|
|
59
146
|
protected _bucketSize: number = 1 << 12;
|
|
60
147
|
|
|
61
|
-
/**
|
|
62
|
-
* The bucketSize function returns the size of the bucket.
|
|
63
|
-
*
|
|
64
|
-
* @return The size of the bucket
|
|
65
|
-
*/
|
|
66
148
|
get bucketSize() {
|
|
67
149
|
return this._bucketSize;
|
|
68
150
|
}
|
|
69
151
|
|
|
70
|
-
protected _maxLen: number = -1;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* The maxLen function returns the max length of the deque.
|
|
74
|
-
*
|
|
75
|
-
* @return The max length of the deque
|
|
76
|
-
*/
|
|
77
|
-
get maxLen() {
|
|
78
|
-
return this._maxLen;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
152
|
protected _bucketFirst = 0;
|
|
82
153
|
|
|
83
|
-
/**
|
|
84
|
-
* The function returns the value of the protected variable `_bucketFirst`.
|
|
85
|
-
* @returns The value of the `_bucketFirst` property.
|
|
86
|
-
*/
|
|
87
154
|
get bucketFirst(): number {
|
|
88
155
|
return this._bucketFirst;
|
|
89
156
|
}
|
|
90
157
|
|
|
91
158
|
protected _firstInBucket = 0;
|
|
92
159
|
|
|
93
|
-
/**
|
|
94
|
-
* The function returns the value of the protected variable _firstInBucket.
|
|
95
|
-
* @returns The method is returning the value of the variable `_firstInBucket`, which is of type
|
|
96
|
-
* `number`.
|
|
97
|
-
*/
|
|
98
160
|
get firstInBucket(): number {
|
|
99
161
|
return this._firstInBucket;
|
|
100
162
|
}
|
|
101
163
|
|
|
102
164
|
protected _bucketLast = 0;
|
|
103
165
|
|
|
104
|
-
/**
|
|
105
|
-
* The function returns the value of the protected variable `_bucketLast`.
|
|
106
|
-
* @returns The value of the `_bucketLast` property, which is a number.
|
|
107
|
-
*/
|
|
108
166
|
get bucketLast(): number {
|
|
109
167
|
return this._bucketLast;
|
|
110
168
|
}
|
|
111
169
|
|
|
112
170
|
protected _lastInBucket = 0;
|
|
113
171
|
|
|
114
|
-
/**
|
|
115
|
-
* The function returns the value of the protected variable _lastInBucket.
|
|
116
|
-
* @returns The method is returning the value of the variable `_lastInBucket`, which is of type
|
|
117
|
-
* `number`.
|
|
118
|
-
*/
|
|
119
172
|
get lastInBucket(): number {
|
|
120
173
|
return this._lastInBucket;
|
|
121
174
|
}
|
|
122
175
|
|
|
123
176
|
protected _bucketCount = 0;
|
|
124
177
|
|
|
125
|
-
/**
|
|
126
|
-
* The function returns the number of buckets.
|
|
127
|
-
* @returns The number of buckets.
|
|
128
|
-
*/
|
|
129
178
|
get bucketCount(): number {
|
|
130
179
|
return this._bucketCount;
|
|
131
180
|
}
|
|
132
181
|
|
|
133
182
|
protected _buckets: E[][] = [];
|
|
134
183
|
|
|
135
|
-
/**
|
|
136
|
-
* The buckets function returns the buckets property of the object.
|
|
137
|
-
* @return The buckets property
|
|
138
|
-
*/
|
|
139
184
|
get buckets() {
|
|
140
185
|
return this._buckets;
|
|
141
186
|
}
|
|
142
187
|
|
|
143
|
-
protected
|
|
188
|
+
protected _length = 0;
|
|
144
189
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
* @return The number of values in the set
|
|
148
|
-
*/
|
|
149
|
-
get size() {
|
|
150
|
-
return this._size;
|
|
190
|
+
get length() {
|
|
191
|
+
return this._length;
|
|
151
192
|
}
|
|
152
193
|
|
|
153
194
|
/**
|
|
@@ -156,7 +197,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
156
197
|
* @returns The first element of the collection, of type E, is being returned.
|
|
157
198
|
*/
|
|
158
199
|
get first(): E | undefined {
|
|
159
|
-
if (this.
|
|
200
|
+
if (this._length === 0) return;
|
|
160
201
|
return this._buckets[this._bucketFirst][this._firstInBucket];
|
|
161
202
|
}
|
|
162
203
|
|
|
@@ -165,7 +206,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
165
206
|
* @return The last element in the array
|
|
166
207
|
*/
|
|
167
208
|
get last(): E | undefined {
|
|
168
|
-
if (this.
|
|
209
|
+
if (this._length === 0) return;
|
|
169
210
|
return this._buckets[this._bucketLast][this._lastInBucket];
|
|
170
211
|
}
|
|
171
212
|
|
|
@@ -179,7 +220,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
179
220
|
* @returns The size of the data structure after the element has been pushed.
|
|
180
221
|
*/
|
|
181
222
|
push(element: E): boolean {
|
|
182
|
-
if (this.
|
|
223
|
+
if (this._length) {
|
|
183
224
|
if (this._lastInBucket < this._bucketSize - 1) {
|
|
184
225
|
this._lastInBucket += 1;
|
|
185
226
|
} else if (this._bucketLast < this._bucketCount - 1) {
|
|
@@ -191,9 +232,9 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
191
232
|
}
|
|
192
233
|
if (this._bucketLast === this._bucketFirst && this._lastInBucket === this._firstInBucket) this._reallocate();
|
|
193
234
|
}
|
|
194
|
-
this.
|
|
235
|
+
this._length += 1;
|
|
195
236
|
this._buckets[this._bucketLast][this._lastInBucket] = element;
|
|
196
|
-
if (this._maxLen > 0 && this.
|
|
237
|
+
if (this._maxLen > 0 && this._length > this._maxLen) this.shift();
|
|
197
238
|
return true;
|
|
198
239
|
}
|
|
199
240
|
|
|
@@ -206,9 +247,9 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
206
247
|
* @returns The element that was removed from the data structure is being returned.
|
|
207
248
|
*/
|
|
208
249
|
pop(): E | undefined {
|
|
209
|
-
if (this.
|
|
250
|
+
if (this._length === 0) return;
|
|
210
251
|
const element = this._buckets[this._bucketLast][this._lastInBucket];
|
|
211
|
-
if (this.
|
|
252
|
+
if (this._length !== 1) {
|
|
212
253
|
if (this._lastInBucket > 0) {
|
|
213
254
|
this._lastInBucket -= 1;
|
|
214
255
|
} else if (this._bucketLast > 0) {
|
|
@@ -219,7 +260,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
219
260
|
this._lastInBucket = this._bucketSize - 1;
|
|
220
261
|
}
|
|
221
262
|
}
|
|
222
|
-
this.
|
|
263
|
+
this._length -= 1;
|
|
223
264
|
return element;
|
|
224
265
|
}
|
|
225
266
|
|
|
@@ -233,9 +274,9 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
233
274
|
* returned.
|
|
234
275
|
*/
|
|
235
276
|
shift(): E | undefined {
|
|
236
|
-
if (this.
|
|
277
|
+
if (this._length === 0) return;
|
|
237
278
|
const element = this._buckets[this._bucketFirst][this._firstInBucket];
|
|
238
|
-
if (this.
|
|
279
|
+
if (this._length !== 1) {
|
|
239
280
|
if (this._firstInBucket < this._bucketSize - 1) {
|
|
240
281
|
this._firstInBucket += 1;
|
|
241
282
|
} else if (this._bucketFirst < this._bucketCount - 1) {
|
|
@@ -246,7 +287,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
246
287
|
this._firstInBucket = 0;
|
|
247
288
|
}
|
|
248
289
|
}
|
|
249
|
-
this.
|
|
290
|
+
this._length -= 1;
|
|
250
291
|
return element;
|
|
251
292
|
}
|
|
252
293
|
|
|
@@ -261,7 +302,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
261
302
|
* @returns The size of the data structure after the element has been added.
|
|
262
303
|
*/
|
|
263
304
|
unshift(element: E): boolean {
|
|
264
|
-
if (this.
|
|
305
|
+
if (this._length) {
|
|
265
306
|
if (this._firstInBucket > 0) {
|
|
266
307
|
this._firstInBucket -= 1;
|
|
267
308
|
} else if (this._bucketFirst > 0) {
|
|
@@ -273,9 +314,9 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
273
314
|
}
|
|
274
315
|
if (this._bucketFirst === this._bucketLast && this._firstInBucket === this._lastInBucket) this._reallocate();
|
|
275
316
|
}
|
|
276
|
-
this.
|
|
317
|
+
this._length += 1;
|
|
277
318
|
this._buckets[this._bucketFirst][this._firstInBucket] = element;
|
|
278
|
-
if (this._maxLen > 0 && this.
|
|
319
|
+
if (this._maxLen > 0 && this._length > this._maxLen) this.pop();
|
|
279
320
|
return true;
|
|
280
321
|
}
|
|
281
322
|
|
|
@@ -338,7 +379,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
338
379
|
* @returns A boolean value indicating whether the size of the object is 0 or not.
|
|
339
380
|
*/
|
|
340
381
|
isEmpty(): boolean {
|
|
341
|
-
return this.
|
|
382
|
+
return this._length === 0;
|
|
342
383
|
}
|
|
343
384
|
|
|
344
385
|
/**
|
|
@@ -351,33 +392,10 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
351
392
|
clear(): void {
|
|
352
393
|
this._buckets = [new Array(this._bucketSize)];
|
|
353
394
|
this._bucketCount = 1;
|
|
354
|
-
this._bucketFirst = this._bucketLast = this.
|
|
395
|
+
this._bucketFirst = this._bucketLast = this._length = 0;
|
|
355
396
|
this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
|
|
356
397
|
}
|
|
357
398
|
|
|
358
|
-
/**
|
|
359
|
-
* The below function is a generator that yields elements from a collection one by one.
|
|
360
|
-
*/
|
|
361
|
-
*begin(): Generator<E> {
|
|
362
|
-
let index = 0;
|
|
363
|
-
while (index < this._size) {
|
|
364
|
-
yield this.at(index);
|
|
365
|
-
index++;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* The function `reverseBegin()` is a generator that yields elements in reverse order starting from
|
|
371
|
-
* the last element.
|
|
372
|
-
*/
|
|
373
|
-
*reverseBegin(): Generator<E> {
|
|
374
|
-
let index = this._size - 1;
|
|
375
|
-
while (index >= 0) {
|
|
376
|
-
yield this.at(index);
|
|
377
|
-
index--;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
399
|
/**
|
|
382
400
|
* Time Complexity: O(1)
|
|
383
401
|
* Space Complexity: O(1)
|
|
@@ -389,7 +407,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
389
407
|
* @returns The element at the specified position in the data structure is being returned.
|
|
390
408
|
*/
|
|
391
409
|
at(pos: number): E {
|
|
392
|
-
rangeCheck(pos, 0, this.
|
|
410
|
+
rangeCheck(pos, 0, this._length - 1);
|
|
393
411
|
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
|
|
394
412
|
return this._buckets[bucketIndex][indexInBucket]!;
|
|
395
413
|
}
|
|
@@ -405,7 +423,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
405
423
|
* position in the data structure.
|
|
406
424
|
*/
|
|
407
425
|
setAt(pos: number, element: E): boolean {
|
|
408
|
-
rangeCheck(pos, 0, this.
|
|
426
|
+
rangeCheck(pos, 0, this._length - 1);
|
|
409
427
|
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
|
|
410
428
|
this._buckets[bucketIndex][indexInBucket] = element;
|
|
411
429
|
return true;
|
|
@@ -427,15 +445,15 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
427
445
|
* @returns The size of the array after the insertion is being returned.
|
|
428
446
|
*/
|
|
429
447
|
addAt(pos: number, element: E, num = 1): boolean {
|
|
430
|
-
const length = this.
|
|
448
|
+
const length = this._length;
|
|
431
449
|
rangeCheck(pos, 0, length);
|
|
432
450
|
if (pos === 0) {
|
|
433
451
|
while (num--) this.unshift(element);
|
|
434
|
-
} else if (pos === this.
|
|
452
|
+
} else if (pos === this._length) {
|
|
435
453
|
while (num--) this.push(element);
|
|
436
454
|
} else {
|
|
437
455
|
const arr: E[] = [];
|
|
438
|
-
for (let i = pos; i < this.
|
|
456
|
+
for (let i = pos; i < this._length; ++i) {
|
|
439
457
|
arr.push(this.at(i));
|
|
440
458
|
}
|
|
441
459
|
this.cut(pos - 1, true);
|
|
@@ -465,10 +483,14 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
465
483
|
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
|
|
466
484
|
this._bucketLast = bucketIndex;
|
|
467
485
|
this._lastInBucket = indexInBucket;
|
|
468
|
-
this.
|
|
486
|
+
this._length = pos + 1;
|
|
469
487
|
return this;
|
|
470
488
|
} else {
|
|
471
|
-
const newDeque =
|
|
489
|
+
const newDeque = this._createInstance({
|
|
490
|
+
bucketSize: this._bucketSize,
|
|
491
|
+
toElementFn: this._toElementFn,
|
|
492
|
+
maxLen: this._maxLen
|
|
493
|
+
});
|
|
472
494
|
|
|
473
495
|
for (let i = 0; i <= pos; i++) {
|
|
474
496
|
newDeque.push(this.at(i));
|
|
@@ -478,6 +500,61 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
478
500
|
}
|
|
479
501
|
}
|
|
480
502
|
|
|
503
|
+
/**
|
|
504
|
+
* Time Complexity: O(n)
|
|
505
|
+
* Space Complexity: O(1)
|
|
506
|
+
*
|
|
507
|
+
* The `splice` function in TypeScript overrides the default behavior to remove and insert elements
|
|
508
|
+
* in a Deque data structure while ensuring the starting position and delete count are within bounds.
|
|
509
|
+
* @param {number} start - The `start` parameter in the `splice` method represents the index at which
|
|
510
|
+
* to start changing the array. Items will be removed or added starting from this index.
|
|
511
|
+
* @param {number} deleteCount - The `deleteCount` parameter in the `splice` method represents the
|
|
512
|
+
* number of elements to remove from the array starting at the specified `start` index. If
|
|
513
|
+
* `deleteCount` is not provided, it defaults to the number of elements from the `start` index to the
|
|
514
|
+
* end of the array (`
|
|
515
|
+
* @param {E[]} items - The `items` parameter in the `splice` method represents the elements that
|
|
516
|
+
* will be inserted into the deque at the specified `start` index. These elements will be inserted in
|
|
517
|
+
* place of the elements that are removed based on the `start` and `deleteCount` parameters.
|
|
518
|
+
* @returns The `splice` method is returning the array `deletedElements` which contains the elements
|
|
519
|
+
* that were removed from the Deque during the splice operation.
|
|
520
|
+
*/
|
|
521
|
+
override splice(start: number, deleteCount: number = this._length - start, ...items: E[]): this {
|
|
522
|
+
// Check whether the starting position is legal
|
|
523
|
+
rangeCheck(start, 0, this._length);
|
|
524
|
+
|
|
525
|
+
// Adjust the value of deleteCount
|
|
526
|
+
if (deleteCount < 0) deleteCount = 0;
|
|
527
|
+
if (start + deleteCount > this._length) deleteCount = this._length - start;
|
|
528
|
+
|
|
529
|
+
// Save deleted elements
|
|
530
|
+
const deletedElements = this._createInstance();
|
|
531
|
+
|
|
532
|
+
// Add removed elements to the result
|
|
533
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
534
|
+
deletedElements.push(this.at(start + i));
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// Calculate the range that needs to be deleted
|
|
538
|
+
const elementsAfter = [];
|
|
539
|
+
for (let i = start + deleteCount; i < this._length; i++) {
|
|
540
|
+
elementsAfter.push(this.at(i));
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// Adjust the length of the current Deque
|
|
544
|
+
this.cut(start - 1, true);
|
|
545
|
+
|
|
546
|
+
for (const item of items) {
|
|
547
|
+
this.push(item);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// Insert subsequent elements back
|
|
551
|
+
for (const element of elementsAfter) {
|
|
552
|
+
this.push(element);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return deletedElements;
|
|
556
|
+
}
|
|
557
|
+
|
|
481
558
|
/**
|
|
482
559
|
* Time Complexity: O(1)
|
|
483
560
|
* Space Complexity: O(1) or O(n)
|
|
@@ -501,12 +578,16 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
501
578
|
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
|
|
502
579
|
this._bucketFirst = bucketIndex;
|
|
503
580
|
this._firstInBucket = indexInBucket;
|
|
504
|
-
this.
|
|
581
|
+
this._length = this._length - pos;
|
|
505
582
|
return this;
|
|
506
583
|
} else {
|
|
507
|
-
const newDeque =
|
|
584
|
+
const newDeque = this._createInstance({
|
|
585
|
+
bucketSize: this._bucketSize,
|
|
586
|
+
toElementFn: this._toElementFn,
|
|
587
|
+
maxLen: this._maxLen
|
|
588
|
+
});
|
|
508
589
|
if (pos < 0) pos = 0;
|
|
509
|
-
for (let i = pos; i < this.
|
|
590
|
+
for (let i = pos; i < this._length; i++) {
|
|
510
591
|
newDeque.push(this.at(i));
|
|
511
592
|
}
|
|
512
593
|
|
|
@@ -525,22 +606,34 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
525
606
|
* the index of the element to be deleted.
|
|
526
607
|
* @returns The size of the data structure after the deletion operation is performed.
|
|
527
608
|
*/
|
|
528
|
-
deleteAt(pos: number):
|
|
529
|
-
rangeCheck(pos, 0, this.
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
609
|
+
deleteAt(pos: number): E | undefined {
|
|
610
|
+
rangeCheck(pos, 0, this._length - 1);
|
|
611
|
+
|
|
612
|
+
let deleted: E | undefined;
|
|
613
|
+
if (pos === 0) {
|
|
614
|
+
//If it is the first element, use shift() directly
|
|
615
|
+
return this.shift();
|
|
616
|
+
} else if (pos === this._length - 1) {
|
|
617
|
+
// If it is the last element, just use pop()
|
|
618
|
+
deleted = this.last;
|
|
619
|
+
this.pop();
|
|
620
|
+
return deleted;
|
|
621
|
+
} else {
|
|
622
|
+
// Delete the middle element
|
|
623
|
+
const length = this._length - 1;
|
|
624
|
+
const { bucketIndex: targetBucket, indexInBucket: targetPointer } = this._getBucketAndPosition(pos);
|
|
625
|
+
deleted = this._buckets[targetBucket][targetPointer];
|
|
626
|
+
|
|
627
|
+
for (let i = pos; i < length; i++) {
|
|
628
|
+
const { bucketIndex: curBucket, indexInBucket: curPointer } = this._getBucketAndPosition(i);
|
|
629
|
+
const { bucketIndex: nextBucket, indexInBucket: nextPointer } = this._getBucketAndPosition(i + 1);
|
|
537
630
|
this._buckets[curBucket][curPointer] = this._buckets[nextBucket][nextPointer];
|
|
538
|
-
curBucket = nextBucket;
|
|
539
|
-
curPointer = nextPointer;
|
|
540
631
|
}
|
|
632
|
+
|
|
633
|
+
// Remove last duplicate element
|
|
541
634
|
this.pop();
|
|
635
|
+
return deleted;
|
|
542
636
|
}
|
|
543
|
-
return true;
|
|
544
637
|
}
|
|
545
638
|
|
|
546
639
|
/**
|
|
@@ -554,7 +647,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
554
647
|
* @returns The size of the data structure after the element has been deleted.
|
|
555
648
|
*/
|
|
556
649
|
delete(element: E): boolean {
|
|
557
|
-
const size = this.
|
|
650
|
+
const size = this._length;
|
|
558
651
|
if (size === 0) return false;
|
|
559
652
|
let i = 0;
|
|
560
653
|
let index = 0;
|
|
@@ -570,6 +663,43 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
570
663
|
return true;
|
|
571
664
|
}
|
|
572
665
|
|
|
666
|
+
// /**
|
|
667
|
+
// * Time Complexity: O(n)
|
|
668
|
+
// * Space Complexity: O(1)
|
|
669
|
+
// *
|
|
670
|
+
// * This function overrides the indexOf method to search for an element within a custom data
|
|
671
|
+
// * structure.
|
|
672
|
+
// * @param {E} searchElement - The `searchElement` parameter is the element that you are searching for
|
|
673
|
+
// * within the data structure. The `indexOf` method will return the index of the first occurrence of
|
|
674
|
+
// * this element within the data structure.
|
|
675
|
+
// * @param {number} [fromIndex=0] - The `fromIndex` parameter in the `indexOf` method specifies the
|
|
676
|
+
// * index at which to start searching for the `searchElement` within the data structure. If provided,
|
|
677
|
+
// * the search will begin at this index instead of the beginning of the data structure.
|
|
678
|
+
// * @returns The indexOf method is returning the index of the searchElement if it is found in the data
|
|
679
|
+
// * structure, or -1 if the searchElement is not found.
|
|
680
|
+
// */
|
|
681
|
+
// override indexOf(searchElement: E, fromIndex: number = 0): number {
|
|
682
|
+
// let index = fromIndex;
|
|
683
|
+
// let bucketIndex = this._bucketFirst;
|
|
684
|
+
// let indexInBucket = this._firstInBucket + fromIndex;
|
|
685
|
+
//
|
|
686
|
+
// for (let i = 0; i < this._length; i++) {
|
|
687
|
+
// if (this._buckets[bucketIndex][indexInBucket] === searchElement) {
|
|
688
|
+
// return index;
|
|
689
|
+
// }
|
|
690
|
+
// index++;
|
|
691
|
+
// indexInBucket++;
|
|
692
|
+
// if (indexInBucket >= this._bucketSize) {
|
|
693
|
+
// bucketIndex++;
|
|
694
|
+
// indexInBucket = 0;
|
|
695
|
+
// }
|
|
696
|
+
// if (bucketIndex >= this._bucketCount) {
|
|
697
|
+
// bucketIndex = 0;
|
|
698
|
+
// }
|
|
699
|
+
// }
|
|
700
|
+
// return -1;
|
|
701
|
+
// }
|
|
702
|
+
|
|
573
703
|
/**
|
|
574
704
|
* Time Complexity: O(n)
|
|
575
705
|
* Space Complexity: O(1)
|
|
@@ -600,12 +730,12 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
600
730
|
* @returns The size of the modified array is being returned.
|
|
601
731
|
*/
|
|
602
732
|
unique(): this {
|
|
603
|
-
if (this.
|
|
733
|
+
if (this._length <= 1) {
|
|
604
734
|
return this;
|
|
605
735
|
}
|
|
606
736
|
let index = 1;
|
|
607
737
|
let prev = this.at(0);
|
|
608
|
-
for (let i = 1; i < this.
|
|
738
|
+
for (let i = 1; i < this._length; ++i) {
|
|
609
739
|
const cur = this.at(i);
|
|
610
740
|
if (cur !== prev) {
|
|
611
741
|
prev = cur;
|
|
@@ -616,28 +746,6 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
616
746
|
return this;
|
|
617
747
|
}
|
|
618
748
|
|
|
619
|
-
/**
|
|
620
|
-
* Time Complexity: O(n log n)
|
|
621
|
-
* Space Complexity: O(n)
|
|
622
|
-
*
|
|
623
|
-
* The `sort` function sorts the elements in a data structure using a provided comparator function.
|
|
624
|
-
* @param [comparator] - The `comparator` parameter is a function that takes in two elements `x` and
|
|
625
|
-
* `y` of type `E` and returns a number. The comparator function is used to determine the order of
|
|
626
|
-
* the elements in the sorted array.
|
|
627
|
-
* @returns Deque<E>
|
|
628
|
-
*/
|
|
629
|
-
sort(comparator?: (x: E, y: E) => number): this {
|
|
630
|
-
const arr: E[] = [];
|
|
631
|
-
for (let i = 0; i < this._size; ++i) {
|
|
632
|
-
arr.push(this.at(i));
|
|
633
|
-
}
|
|
634
|
-
arr.sort(comparator);
|
|
635
|
-
for (let i = 0; i < this._size; ++i) {
|
|
636
|
-
this.setAt(i, arr[i]);
|
|
637
|
-
}
|
|
638
|
-
return this;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
749
|
/**
|
|
642
750
|
* Time Complexity: O(n)
|
|
643
751
|
* Space Complexity: O(n)
|
|
@@ -645,10 +753,10 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
645
753
|
* The `shrinkToFit` function reorganizes the elements in an array-like data structure to minimize
|
|
646
754
|
* memory usage.
|
|
647
755
|
* @returns Nothing is being returned. The function is using the `return` statement to exit early if
|
|
648
|
-
* `this.
|
|
756
|
+
* `this._length` is 0, but it does not return any value.
|
|
649
757
|
*/
|
|
650
758
|
shrinkToFit(): void {
|
|
651
|
-
if (this.
|
|
759
|
+
if (this._length === 0) return;
|
|
652
760
|
const newBuckets = [];
|
|
653
761
|
if (this._bucketFirst === this._bucketLast) return;
|
|
654
762
|
else if (this._bucketFirst < this._bucketLast) {
|
|
@@ -668,37 +776,6 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
668
776
|
this._buckets = newBuckets;
|
|
669
777
|
}
|
|
670
778
|
|
|
671
|
-
/**
|
|
672
|
-
* Time Complexity: O(n)
|
|
673
|
-
* Space Complexity: O(1)
|
|
674
|
-
*
|
|
675
|
-
* The function "indexOf" returns the index of the first occurrence of a given element in an array,
|
|
676
|
-
* or -1 if the element is not found.
|
|
677
|
-
* @param {E} element - The "element" parameter represents the element that you want to find the
|
|
678
|
-
* index of in the data structure.
|
|
679
|
-
* @returns The indexOf function returns the index of the first occurrence of the specified element
|
|
680
|
-
* in the data structure. If the element is not found, it returns -1.
|
|
681
|
-
*/
|
|
682
|
-
indexOf(element: E): number {
|
|
683
|
-
for (let i = 0; i < this._size; ++i) {
|
|
684
|
-
if (this.at(i) === element) {
|
|
685
|
-
return i;
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
return -1;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
/**
|
|
692
|
-
* Time Complexity: O(n)
|
|
693
|
-
* Space Complexity: O(n)
|
|
694
|
-
*
|
|
695
|
-
* The `toArray` function converts the elements of a data structure into an array.
|
|
696
|
-
* @returns The `toArray()` method is returning an array of elements of type `E`.
|
|
697
|
-
*/
|
|
698
|
-
toArray(): E[] {
|
|
699
|
-
return [...this];
|
|
700
|
-
}
|
|
701
|
-
|
|
702
779
|
/**
|
|
703
780
|
* Time Complexity: O(n)
|
|
704
781
|
* Space Complexity: O(n)
|
|
@@ -708,8 +785,12 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
708
785
|
* @returns The `clone()` method is returning a new instance of the `Deque` class with the same
|
|
709
786
|
* elements as the original deque (`this`) and the same bucket size.
|
|
710
787
|
*/
|
|
711
|
-
clone():
|
|
712
|
-
return new Deque<E, R>(this, {
|
|
788
|
+
clone(): this {
|
|
789
|
+
return new Deque<E, R>(this, {
|
|
790
|
+
bucketSize: this.bucketSize,
|
|
791
|
+
toElementFn: this.toElementFn,
|
|
792
|
+
maxLen: this._maxLen
|
|
793
|
+
}) as this;
|
|
713
794
|
}
|
|
714
795
|
|
|
715
796
|
/**
|
|
@@ -728,8 +809,12 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
728
809
|
* @returns The `filter` method is returning a new `Deque` object that contains the elements that
|
|
729
810
|
* satisfy the given predicate function.
|
|
730
811
|
*/
|
|
731
|
-
filter(predicate: ElementCallback<E, R, boolean
|
|
732
|
-
const newDeque =
|
|
812
|
+
filter(predicate: ElementCallback<E, R, boolean>, thisArg?: any): Deque<E, R> {
|
|
813
|
+
const newDeque = this._createInstance({
|
|
814
|
+
bucketSize: this._bucketSize,
|
|
815
|
+
toElementFn: this.toElementFn,
|
|
816
|
+
maxLen: this._maxLen
|
|
817
|
+
});
|
|
733
818
|
let index = 0;
|
|
734
819
|
for (const el of this) {
|
|
735
820
|
if (predicate.call(thisArg, el, index, this)) {
|
|
@@ -758,12 +843,8 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
758
843
|
* value of
|
|
759
844
|
* @returns a new Deque object with elements of type EM and raw elements of type RM.
|
|
760
845
|
*/
|
|
761
|
-
map<EM, RM>(
|
|
762
|
-
|
|
763
|
-
toElementFn?: (rawElement: RM) => EM,
|
|
764
|
-
thisArg?: any
|
|
765
|
-
): Deque<EM, RM> {
|
|
766
|
-
const newDeque = new Deque<EM, RM>([], { bucketSize: this._bucketSize, toElementFn });
|
|
846
|
+
map<EM, RM>(callback: ElementCallback<E, R, EM>, toElementFn?: (rawElement: RM) => EM, thisArg?: any): Deque<EM, RM> {
|
|
847
|
+
const newDeque = new Deque<EM, RM>([], { bucketSize: this._bucketSize, toElementFn, maxLen: this._maxLen });
|
|
767
848
|
let index = 0;
|
|
768
849
|
for (const el of this) {
|
|
769
850
|
newDeque.push(callback.call(thisArg, el, index, this));
|
|
@@ -780,7 +861,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
780
861
|
* object to be iterated over using a for...of loop.
|
|
781
862
|
*/
|
|
782
863
|
protected *_getIterator(): IterableIterator<E> {
|
|
783
|
-
for (let i = 0; i < this.
|
|
864
|
+
for (let i = 0; i < this._length; ++i) {
|
|
784
865
|
yield this.at(i);
|
|
785
866
|
}
|
|
786
867
|
}
|
|
@@ -843,4 +924,26 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|
|
843
924
|
|
|
844
925
|
return { bucketIndex, indexInBucket };
|
|
845
926
|
}
|
|
927
|
+
|
|
928
|
+
/**
|
|
929
|
+
* The function `_createInstance` returns a new instance of the `Deque` class with the specified
|
|
930
|
+
* options.
|
|
931
|
+
* @param [options] - The `options` parameter in the `_createInstance` method is of type
|
|
932
|
+
* `DequeOptions<E, R>`, which is an optional parameter that allows you to pass additional
|
|
933
|
+
* configuration options when creating a new instance of the `Deque` class.
|
|
934
|
+
* @returns An instance of the `Deque` class with an empty array and the provided options, casted as
|
|
935
|
+
* `this`.
|
|
936
|
+
*/
|
|
937
|
+
protected override _createInstance(options?: DequeOptions<E, R>): this {
|
|
938
|
+
return new Deque<E, R>([], options) as this;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* This function returns an iterator that iterates over elements in reverse order.
|
|
943
|
+
*/
|
|
944
|
+
protected *_getReverseIterator(): IterableIterator<E> {
|
|
945
|
+
for (let i = this._length - 1; i > -1; i--) {
|
|
946
|
+
yield this.at(i);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
846
949
|
}
|