linked-list-typed 1.54.2 → 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.
Files changed (85) hide show
  1. package/README.md +7 -7
  2. package/dist/data-structures/base/iterable-element-base.d.ts +14 -40
  3. package/dist/data-structures/base/iterable-element-base.js +14 -11
  4. package/dist/data-structures/base/linear-base.d.ts +277 -0
  5. package/dist/data-structures/base/linear-base.js +552 -0
  6. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +21 -20
  7. package/dist/data-structures/binary-tree/avl-tree-counter.js +8 -7
  8. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +23 -19
  9. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +51 -38
  10. package/dist/data-structures/binary-tree/avl-tree.d.ts +89 -21
  11. package/dist/data-structures/binary-tree/avl-tree.js +76 -8
  12. package/dist/data-structures/binary-tree/binary-tree.d.ts +173 -225
  13. package/dist/data-structures/binary-tree/binary-tree.js +244 -149
  14. package/dist/data-structures/binary-tree/bst.d.ts +62 -56
  15. package/dist/data-structures/binary-tree/bst.js +89 -133
  16. package/dist/data-structures/binary-tree/red-black-tree.d.ts +19 -25
  17. package/dist/data-structures/binary-tree/red-black-tree.js +7 -13
  18. package/dist/data-structures/binary-tree/tree-counter.d.ts +19 -19
  19. package/dist/data-structures/binary-tree/tree-counter.js +12 -12
  20. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +186 -25
  21. package/dist/data-structures/binary-tree/tree-multi-map.js +211 -41
  22. package/dist/data-structures/graph/abstract-graph.js +2 -2
  23. package/dist/data-structures/heap/heap.d.ts +3 -11
  24. package/dist/data-structures/heap/heap.js +0 -10
  25. package/dist/data-structures/heap/max-heap.d.ts +2 -2
  26. package/dist/data-structures/heap/min-heap.d.ts +2 -2
  27. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +65 -94
  28. package/dist/data-structures/linked-list/doubly-linked-list.js +131 -146
  29. package/dist/data-structures/linked-list/singly-linked-list.d.ts +79 -75
  30. package/dist/data-structures/linked-list/singly-linked-list.js +217 -169
  31. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +2 -2
  32. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +2 -2
  33. package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -2
  34. package/dist/data-structures/queue/deque.d.ts +130 -91
  35. package/dist/data-structures/queue/deque.js +269 -169
  36. package/dist/data-structures/queue/queue.d.ts +84 -40
  37. package/dist/data-structures/queue/queue.js +134 -50
  38. package/dist/data-structures/stack/stack.d.ts +3 -11
  39. package/dist/data-structures/stack/stack.js +0 -10
  40. package/dist/data-structures/trie/trie.d.ts +4 -3
  41. package/dist/data-structures/trie/trie.js +3 -0
  42. package/dist/types/data-structures/base/base.d.ts +9 -4
  43. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
  44. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -0
  45. package/dist/types/data-structures/binary-tree/bst.d.ts +1 -1
  46. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -1
  47. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -2
  48. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +2 -2
  49. package/dist/types/data-structures/queue/deque.d.ts +2 -3
  50. package/dist/types/data-structures/queue/queue.d.ts +2 -2
  51. package/dist/utils/utils.d.ts +2 -2
  52. package/package.json +2 -2
  53. package/src/data-structures/base/iterable-element-base.ts +29 -20
  54. package/src/data-structures/base/linear-base.ts +649 -0
  55. package/src/data-structures/binary-tree/avl-tree-counter.ts +30 -23
  56. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +74 -49
  57. package/src/data-structures/binary-tree/avl-tree.ts +99 -29
  58. package/src/data-structures/binary-tree/binary-tree.ts +474 -257
  59. package/src/data-structures/binary-tree/bst.ts +150 -152
  60. package/src/data-structures/binary-tree/red-black-tree.ts +27 -35
  61. package/src/data-structures/binary-tree/tree-counter.ts +33 -27
  62. package/src/data-structures/binary-tree/tree-multi-map.ts +235 -53
  63. package/src/data-structures/graph/abstract-graph.ts +2 -2
  64. package/src/data-structures/heap/heap.ts +3 -14
  65. package/src/data-structures/heap/max-heap.ts +2 -2
  66. package/src/data-structures/heap/min-heap.ts +2 -2
  67. package/src/data-structures/linked-list/doubly-linked-list.ts +144 -160
  68. package/src/data-structures/linked-list/singly-linked-list.ts +241 -185
  69. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -5
  70. package/src/data-structures/priority-queue/min-priority-queue.ts +2 -5
  71. package/src/data-structures/priority-queue/priority-queue.ts +2 -2
  72. package/src/data-structures/queue/deque.ts +286 -183
  73. package/src/data-structures/queue/queue.ts +149 -63
  74. package/src/data-structures/stack/stack.ts +3 -18
  75. package/src/data-structures/trie/trie.ts +7 -3
  76. package/src/types/data-structures/base/base.ts +17 -8
  77. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
  78. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -0
  79. package/src/types/data-structures/binary-tree/bst.ts +1 -1
  80. package/src/types/data-structures/binary-tree/tree-multi-map.ts +1 -1
  81. package/src/types/data-structures/linked-list/doubly-linked-list.ts +2 -2
  82. package/src/types/data-structures/linked-list/singly-linked-list.ts +2 -2
  83. package/src/types/data-structures/queue/deque.ts +2 -3
  84. package/src/types/data-structures/queue/queue.ts +2 -2
  85. package/src/utils/utils.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 IterableElementBase<E, R, Deque<E, R>> {
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, maxLen } = options;
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 _size = 0;
188
+ protected _length = 0;
144
189
 
145
- /**
146
- * The size function returns the number of items in the stack.
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._size === 0) return;
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._size === 0) return;
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._size) {
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._size += 1;
235
+ this._length += 1;
195
236
  this._buckets[this._bucketLast][this._lastInBucket] = element;
196
- if (this._maxLen > 0 && this._size > this._maxLen) this.shift();
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._size === 0) return;
250
+ if (this._length === 0) return;
210
251
  const element = this._buckets[this._bucketLast][this._lastInBucket];
211
- if (this._size !== 1) {
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._size -= 1;
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._size === 0) return;
277
+ if (this._length === 0) return;
237
278
  const element = this._buckets[this._bucketFirst][this._firstInBucket];
238
- if (this._size !== 1) {
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._size -= 1;
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._size) {
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._size += 1;
317
+ this._length += 1;
277
318
  this._buckets[this._bucketFirst][this._firstInBucket] = element;
278
- if (this._maxLen > 0 && this._size > this._maxLen) this.pop();
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._size === 0;
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._size = 0;
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._size - 1);
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._size - 1);
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._size;
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._size) {
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._size; ++i) {
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._size = pos + 1;
486
+ this._length = pos + 1;
469
487
  return this;
470
488
  } else {
471
- const newDeque = new Deque<E>([], { bucketSize: this._bucketSize });
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._size = this._size - pos;
581
+ this._length = this._length - pos;
505
582
  return this;
506
583
  } else {
507
- const newDeque = new Deque<E>([], { bucketSize: this._bucketSize });
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._size; i++) {
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): boolean {
529
- rangeCheck(pos, 0, this._size - 1);
530
- if (pos === 0) this.shift();
531
- else if (pos === this._size - 1) this.pop();
532
- else {
533
- const length = this._size - 1;
534
- let { bucketIndex: curBucket, indexInBucket: curPointer } = this._getBucketAndPosition(pos);
535
- for (let i = pos; i < length; ++i) {
536
- const { bucketIndex: nextBucket, indexInBucket: nextPointer } = this._getBucketAndPosition(pos + 1);
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._size;
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._size <= 1) {
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._size; ++i) {
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._size` is 0, but it does not return any value.
756
+ * `this._length` is 0, but it does not return any value.
649
757
  */
650
758
  shrinkToFit(): void {
651
- if (this._size === 0) return;
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(): Deque<E, R> {
712
- return new Deque<E, R>(this, { bucketSize: this.bucketSize, toElementFn: this.toElementFn });
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, Deque<E, R>>, thisArg?: any): Deque<E, R> {
732
- const newDeque = new Deque<E, R>([], { bucketSize: this._bucketSize, toElementFn: this.toElementFn });
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
- callback: ElementCallback<E, R, EM, Deque<E, R>>,
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._size; ++i) {
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
  }