queue-typed 1.53.6 → 1.53.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/common/index.d.ts +12 -0
  2. package/dist/common/index.js +28 -0
  3. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +1 -1
  4. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +9 -12
  5. package/dist/data-structures/binary-tree/avl-tree.js +2 -2
  6. package/dist/data-structures/binary-tree/binary-tree.d.ts +55 -20
  7. package/dist/data-structures/binary-tree/binary-tree.js +102 -68
  8. package/dist/data-structures/binary-tree/bst.d.ts +131 -37
  9. package/dist/data-structures/binary-tree/bst.js +222 -69
  10. package/dist/data-structures/binary-tree/index.d.ts +1 -1
  11. package/dist/data-structures/binary-tree/index.js +1 -1
  12. package/dist/data-structures/binary-tree/{rb-tree.d.ts → red-black-tree.d.ts} +53 -0
  13. package/dist/data-structures/binary-tree/{rb-tree.js → red-black-tree.js} +56 -3
  14. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +2 -2
  15. package/dist/data-structures/binary-tree/tree-multi-map.js +7 -7
  16. package/dist/data-structures/hash/hash-map.d.ts +30 -0
  17. package/dist/data-structures/hash/hash-map.js +30 -0
  18. package/dist/data-structures/heap/heap.d.ts +26 -9
  19. package/dist/data-structures/heap/heap.js +37 -17
  20. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +54 -9
  21. package/dist/data-structures/linked-list/doubly-linked-list.js +80 -19
  22. package/dist/data-structures/linked-list/singly-linked-list.d.ts +35 -2
  23. package/dist/data-structures/linked-list/singly-linked-list.js +55 -11
  24. package/dist/data-structures/queue/deque.d.ts +37 -8
  25. package/dist/data-structures/queue/deque.js +73 -29
  26. package/dist/data-structures/queue/queue.d.ts +41 -1
  27. package/dist/data-structures/queue/queue.js +51 -9
  28. package/dist/data-structures/stack/stack.d.ts +27 -10
  29. package/dist/data-structures/stack/stack.js +39 -20
  30. package/dist/data-structures/trie/trie.d.ts +111 -6
  31. package/dist/data-structures/trie/trie.js +123 -14
  32. package/dist/index.d.ts +2 -1
  33. package/dist/index.js +2 -1
  34. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -1
  35. package/dist/types/data-structures/binary-tree/bst.d.ts +3 -2
  36. package/dist/types/data-structures/binary-tree/rb-tree.d.ts +1 -1
  37. package/dist/types/utils/utils.d.ts +10 -6
  38. package/dist/utils/utils.js +4 -2
  39. package/package.json +2 -2
  40. package/src/common/index.ts +25 -0
  41. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +9 -11
  42. package/src/data-structures/binary-tree/avl-tree.ts +3 -2
  43. package/src/data-structures/binary-tree/binary-tree.ts +110 -66
  44. package/src/data-structures/binary-tree/bst.ts +232 -72
  45. package/src/data-structures/binary-tree/index.ts +1 -1
  46. package/src/data-structures/binary-tree/{rb-tree.ts → red-black-tree.ts} +56 -3
  47. package/src/data-structures/binary-tree/tree-multi-map.ts +6 -6
  48. package/src/data-structures/hash/hash-map.ts +30 -0
  49. package/src/data-structures/heap/heap.ts +72 -49
  50. package/src/data-structures/linked-list/doubly-linked-list.ts +173 -105
  51. package/src/data-structures/linked-list/singly-linked-list.ts +61 -11
  52. package/src/data-structures/queue/deque.ts +72 -28
  53. package/src/data-structures/queue/queue.ts +50 -7
  54. package/src/data-structures/stack/stack.ts +39 -20
  55. package/src/data-structures/trie/trie.ts +123 -13
  56. package/src/index.ts +2 -1
  57. package/src/types/data-structures/binary-tree/binary-tree.ts +1 -1
  58. package/src/types/data-structures/binary-tree/bst.ts +3 -2
  59. package/src/types/data-structures/binary-tree/rb-tree.ts +1 -1
  60. package/src/types/utils/utils.ts +16 -10
  61. package/src/utils/utils.ts +4 -2
@@ -82,52 +82,52 @@ export class DoublyLinkedListNode<E = any> {
82
82
  }
83
83
 
84
84
  /**
85
- * 1. Node Structure: Each node contains three parts: a data field, a pointer (or reference) to the previous node, and a pointer to the next node. This structure allows traversal of the linked list in both directions.
85
+ *1. Node Structure: Each node contains three parts: a data field, a pointer (or reference) to the previous node, and a pointer to the next node. This structure allows traversal of the linked list in both directions.
86
86
  * 2. Bidirectional Traversal: Unlike singly linked lists, doubly linked lists can be easily traversed forwards or backwards. This makes insertions and deletions in the list more flexible and efficient.
87
87
  * 3. No Centralized Index: Unlike arrays, elements in a linked list are not stored contiguously, so there is no centralized index. Accessing elements in a linked list typically requires traversing from the head or tail node.
88
88
  * 4. High Efficiency in Insertion and Deletion: Adding or removing elements in a linked list does not require moving other elements, making these operations more efficient than in arrays.
89
- * @example
90
- * // text editor operation history
91
- * const actions = [
89
+ * @example
90
+ * // text editor operation history
91
+ * const actions = [
92
92
  * { type: 'insert', content: 'first line of text' },
93
93
  * { type: 'insert', content: 'second line of text' },
94
94
  * { type: 'delete', content: 'delete the first line' }
95
95
  * ];
96
96
  * const editorHistory = new DoublyLinkedList<{ type: string; content: string }>(actions);
97
- *
97
+ *
98
98
  * console.log(editorHistory.last?.type); // 'delete'
99
99
  * console.log(editorHistory.pop()?.content); // 'delete the first line'
100
100
  * console.log(editorHistory.last?.type); // 'insert'
101
- * @example
102
- * // Browser history
103
- * const browserHistory = new DoublyLinkedList<string>();
104
- *
101
+ * @example
102
+ * // Browser history
103
+ * const browserHistory = new DoublyLinkedList<string>();
104
+ *
105
105
  * browserHistory.push('home page');
106
106
  * browserHistory.push('search page');
107
107
  * browserHistory.push('details page');
108
- *
108
+ *
109
109
  * console.log(browserHistory.last); // 'details page'
110
110
  * console.log(browserHistory.pop()); // 'details page'
111
111
  * console.log(browserHistory.last); // 'search page'
112
- * @example
113
- * // Use DoublyLinkedList to implement music player
114
- * // Define the Song interface
112
+ * @example
113
+ * // Use DoublyLinkedList to implement music player
114
+ * // Define the Song interface
115
115
  * interface Song {
116
116
  * title: string;
117
117
  * artist: string;
118
118
  * duration: number; // duration in seconds
119
119
  * }
120
- *
120
+ *
121
121
  * class Player {
122
122
  * private playlist: DoublyLinkedList<Song>;
123
123
  * private currentSong: ReturnType<typeof this.playlist.getNodeAt> | undefined;
124
- *
124
+ *
125
125
  * constructor(songs: Song[]) {
126
126
  * this.playlist = new DoublyLinkedList<Song>();
127
127
  * songs.forEach(song => this.playlist.push(song));
128
128
  * this.currentSong = this.playlist.head;
129
129
  * }
130
- *
130
+ *
131
131
  * // Play the next song in the playlist
132
132
  * playNext(): Song | undefined {
133
133
  * if (!this.currentSong?.next) {
@@ -137,7 +137,7 @@ export class DoublyLinkedListNode<E = any> {
137
137
  * }
138
138
  * return this.currentSong?.value;
139
139
  * }
140
- *
140
+ *
141
141
  * // Play the previous song in the playlist
142
142
  * playPrevious(): Song | undefined {
143
143
  * if (!this.currentSong?.prev) {
@@ -147,29 +147,29 @@ export class DoublyLinkedListNode<E = any> {
147
147
  * }
148
148
  * return this.currentSong?.value;
149
149
  * }
150
- *
150
+ *
151
151
  * // Get the current song
152
152
  * getCurrentSong(): Song | undefined {
153
153
  * return this.currentSong?.value;
154
154
  * }
155
- *
155
+ *
156
156
  * // Loop through the playlist twice
157
157
  * loopThroughPlaylist(): Song[] {
158
158
  * const playedSongs: Song[] = [];
159
159
  * const initialNode = this.currentSong;
160
- *
160
+ *
161
161
  * // Loop through the playlist twice
162
162
  * for (let i = 0; i < this.playlist.size * 2; i++) {
163
163
  * playedSongs.push(this.currentSong!.value);
164
164
  * this.currentSong = this.currentSong!.next || this.playlist.head; // Loop back to the start if needed
165
165
  * }
166
- *
166
+ *
167
167
  * // Reset the current song to the initial song
168
168
  * this.currentSong = initialNode;
169
169
  * return playedSongs;
170
170
  * }
171
171
  * }
172
- *
172
+ *
173
173
  * const songs = [
174
174
  * { title: 'Bohemian Rhapsody', artist: 'Queen', duration: 354 },
175
175
  * { title: 'Hotel California', artist: 'Eagles', duration: 391 },
@@ -181,48 +181,48 @@ export class DoublyLinkedListNode<E = any> {
181
181
  * player = new Player(songs);
182
182
  * const firstSong = player.getCurrentSong();
183
183
  * const nextSong = player.playNext();
184
- *
184
+ *
185
185
  * // Expect the next song to be "Hotel California by Eagles"
186
186
  * console.log(nextSong); // { title: 'Hotel California', artist: 'Eagles', duration: 391 }
187
187
  * console.log(firstSong); // { title: 'Bohemian Rhapsody', artist: 'Queen', duration: 354 }
188
- *
188
+ *
189
189
  * // should play the previous song
190
190
  * player = new Player(songs);
191
191
  * player.playNext(); // Move to the second song
192
192
  * const currentSong = player.getCurrentSong();
193
193
  * const previousSong = player.playPrevious();
194
- *
194
+ *
195
195
  * // Expect the previous song to be "Bohemian Rhapsody by Queen"
196
196
  * console.log(previousSong); // { title: 'Bohemian Rhapsody', artist: 'Queen', duration: 354 }
197
197
  * console.log(currentSong); // { title: 'Hotel California', artist: 'Eagles', duration: 391 }
198
- *
198
+ *
199
199
  * // should loop to the first song when playing next from the last song
200
200
  * player = new Player(songs);
201
201
  * player.playNext(); // Move to the second song
202
202
  * player.playNext(); // Move to the third song
203
203
  * player.playNext(); // Move to the fourth song
204
- *
204
+ *
205
205
  * const nextSongToFirst = player.playNext(); // Should loop to the first song
206
- *
206
+ *
207
207
  * // Expect the next song to be "Bohemian Rhapsody by Queen"
208
208
  * console.log(nextSongToFirst); // { title: 'Bohemian Rhapsody', artist: 'Queen', duration: 354 }
209
- *
209
+ *
210
210
  * // should loop to the last song when playing previous from the first song
211
211
  * player = new Player(songs);
212
212
  * player.playNext(); // Move to the first song
213
213
  * player.playNext(); // Move to the second song
214
214
  * player.playNext(); // Move to the third song
215
215
  * player.playNext(); // Move to the fourth song
216
- *
216
+ *
217
217
  * const previousToLast = player.playPrevious(); // Should loop to the last song
218
- *
218
+ *
219
219
  * // Expect the previous song to be "Billie Jean by Michael Jackson"
220
220
  * console.log(previousToLast); // { title: 'Billie Jean', artist: 'Michael Jackson', duration: 294 }
221
- *
221
+ *
222
222
  * // should loop through the entire playlist
223
223
  * player = new Player(songs);
224
224
  * const playedSongs = player.loopThroughPlaylist();
225
- *
225
+ *
226
226
  * // The expected order of songs for two loops
227
227
  * console.log(playedSongs); // [
228
228
  * // { title: 'Bohemian Rhapsody', artist: 'Queen', duration: 354 },
@@ -234,18 +234,18 @@ export class DoublyLinkedListNode<E = any> {
234
234
  * // { title: 'Shape of You', artist: 'Ed Sheeran', duration: 233 },
235
235
  * // { title: 'Billie Jean', artist: 'Michael Jackson', duration: 294 }
236
236
  * // ]
237
- * @example
238
- * // Use DoublyLinkedList to implement LRU cache
239
- * interface CacheEntry<K, V> {
237
+ * @example
238
+ * // Use DoublyLinkedList to implement LRU cache
239
+ * interface CacheEntry<K, V> {
240
240
  * key: K;
241
241
  * value: V;
242
242
  * }
243
- *
243
+ *
244
244
  * class LRUCache<K = string, V = any> {
245
245
  * private readonly capacity: number;
246
246
  * private list: DoublyLinkedList<CacheEntry<K, V>>;
247
247
  * private map: Map<K, DoublyLinkedListNode<CacheEntry<K, V>>>;
248
- *
248
+ *
249
249
  * constructor(capacity: number) {
250
250
  * if (capacity <= 0) {
251
251
  * throw new Error('lru cache capacity must be greater than 0');
@@ -254,31 +254,31 @@ export class DoublyLinkedListNode<E = any> {
254
254
  * this.list = new DoublyLinkedList<CacheEntry<K, V>>();
255
255
  * this.map = new Map<K, DoublyLinkedListNode<CacheEntry<K, V>>>();
256
256
  * }
257
- *
257
+ *
258
258
  * // Get cached value
259
259
  * get(key: K): V | undefined {
260
260
  * const node = this.map.get(key);
261
- *
261
+ *
262
262
  * if (!node) return undefined;
263
- *
263
+ *
264
264
  * // Move the visited node to the head of the linked list (most recently used)
265
265
  * this.moveToFront(node);
266
- *
266
+ *
267
267
  * return node.value.value;
268
268
  * }
269
- *
269
+ *
270
270
  * // Set cache value
271
271
  * set(key: K, value: V): void {
272
272
  * // Check if it already exists
273
273
  * const node = this.map.get(key);
274
- *
274
+ *
275
275
  * if (node) {
276
276
  * // Update value and move to head
277
277
  * node.value.value = value;
278
278
  * this.moveToFront(node);
279
279
  * return;
280
280
  * }
281
- *
281
+ *
282
282
  * // Check capacity
283
283
  * if (this.list.size >= this.capacity) {
284
284
  * // Delete the least recently used element (the tail of the linked list)
@@ -288,119 +288,119 @@ export class DoublyLinkedListNode<E = any> {
288
288
  * this.list.pop();
289
289
  * }
290
290
  * }
291
- *
291
+ *
292
292
  * // Create new node and add to head
293
293
  * const newEntry: CacheEntry<K, V> = { key, value };
294
294
  * this.list.unshift(newEntry);
295
- *
295
+ *
296
296
  * // Save node reference in map
297
297
  * const newNode = this.list.head;
298
298
  * if (newNode) {
299
299
  * this.map.set(key, newNode);
300
300
  * }
301
301
  * }
302
- *
302
+ *
303
303
  * // Move the node to the head of the linked list
304
304
  * private moveToFront(node: DoublyLinkedListNode<CacheEntry<K, V>>): void {
305
305
  * this.list.delete(node);
306
306
  * this.list.unshift(node.value);
307
307
  * }
308
- *
308
+ *
309
309
  * // Delete specific key
310
310
  * delete(key: K): boolean {
311
311
  * const node = this.map.get(key);
312
312
  * if (!node) return false;
313
- *
313
+ *
314
314
  * // Remove from linked list
315
315
  * this.list.delete(node);
316
316
  * // Remove from map
317
317
  * this.map.delete(key);
318
- *
318
+ *
319
319
  * return true;
320
320
  * }
321
- *
321
+ *
322
322
  * // Clear cache
323
323
  * clear(): void {
324
324
  * this.list.clear();
325
325
  * this.map.clear();
326
326
  * }
327
- *
327
+ *
328
328
  * // Get the current cache size
329
329
  * get size(): number {
330
330
  * return this.list.size;
331
331
  * }
332
- *
332
+ *
333
333
  * // Check if it is empty
334
334
  * get isEmpty(): boolean {
335
335
  * return this.list.isEmpty();
336
336
  * }
337
337
  * }
338
- *
338
+ *
339
339
  * // should set and get values correctly
340
340
  * const cache = new LRUCache<string, number>(3);
341
341
  * cache.set('a', 1);
342
342
  * cache.set('b', 2);
343
343
  * cache.set('c', 3);
344
- *
344
+ *
345
345
  * console.log(cache.get('a')); // 1
346
346
  * console.log(cache.get('b')); // 2
347
347
  * console.log(cache.get('c')); // 3
348
- *
348
+ *
349
349
  * // The least recently used element should be evicted when capacity is exceeded
350
350
  * cache.clear();
351
351
  * cache.set('a', 1);
352
352
  * cache.set('b', 2);
353
353
  * cache.set('c', 3);
354
354
  * cache.set('d', 4); // This will eliminate 'a'
355
- *
355
+ *
356
356
  * console.log(cache.get('a')); // undefined
357
357
  * console.log(cache.get('b')); // 2
358
358
  * console.log(cache.get('c')); // 3
359
359
  * console.log(cache.get('d')); // 4
360
- *
360
+ *
361
361
  * // The priority of an element should be updated when it is accessed
362
362
  * cache.clear();
363
363
  * cache.set('a', 1);
364
364
  * cache.set('b', 2);
365
365
  * cache.set('c', 3);
366
- *
366
+ *
367
367
  * cache.get('a'); // access 'a'
368
368
  * cache.set('d', 4); // This will eliminate 'b'
369
- *
369
+ *
370
370
  * console.log(cache.get('a')); // 1
371
371
  * console.log(cache.get('b')); // undefined
372
372
  * console.log(cache.get('c')); // 3
373
373
  * console.log(cache.get('d')); // 4
374
- *
374
+ *
375
375
  * // Should support updating existing keys
376
376
  * cache.clear();
377
377
  * cache.set('a', 1);
378
378
  * cache.set('a', 10);
379
- *
379
+ *
380
380
  * console.log(cache.get('a')); // 10
381
- *
381
+ *
382
382
  * // Should support deleting specified keys
383
383
  * cache.clear();
384
384
  * cache.set('a', 1);
385
385
  * cache.set('b', 2);
386
- *
386
+ *
387
387
  * console.log(cache.delete('a')); // true
388
388
  * console.log(cache.get('a')); // undefined
389
389
  * console.log(cache.size); // 1
390
- *
390
+ *
391
391
  * // Should support clearing cache
392
392
  * cache.clear();
393
393
  * cache.set('a', 1);
394
394
  * cache.set('b', 2);
395
395
  * cache.clear();
396
- *
396
+ *
397
397
  * console.log(cache.size); // 0
398
398
  * console.log(cache.isEmpty); // true
399
- * @example
400
- * // finding lyrics by timestamp in Coldplay's "Fix You"
401
- * // Create a DoublyLinkedList to store song lyrics with timestamps
399
+ * @example
400
+ * // finding lyrics by timestamp in Coldplay's "Fix You"
401
+ * // Create a DoublyLinkedList to store song lyrics with timestamps
402
402
  * const lyricsList = new DoublyLinkedList<{ time: number; text: string }>();
403
- *
403
+ *
404
404
  * // Detailed lyrics with precise timestamps (in milliseconds)
405
405
  * const lyrics = [
406
406
  * { time: 0, text: "When you try your best, but you don't succeed" },
@@ -415,117 +415,124 @@ export class DoublyLinkedListNode<E = any> {
415
415
  * { time: 36000, text: 'And ignite your bones' },
416
416
  * { time: 40000, text: 'And I will try to fix you' }
417
417
  * ];
418
- *
418
+ *
419
419
  * // Populate the DoublyLinkedList with lyrics
420
420
  * lyrics.forEach(lyric => lyricsList.push(lyric));
421
- *
421
+ *
422
422
  * // Test different scenarios of lyric synchronization
423
- *
423
+ *
424
424
  * // 1. Find lyric at exact timestamp
425
425
  * const exactTimeLyric = lyricsList.getBackward(lyric => lyric.value.time <= 36000);
426
426
  * console.log(exactTimeLyric?.text); // 'And ignite your bones'
427
- *
427
+ *
428
428
  * // 2. Find lyric between timestamps
429
429
  * const betweenTimeLyric = lyricsList.getBackward(lyric => lyric.value.time <= 22000);
430
430
  * console.log(betweenTimeLyric?.text); // "When you lose something you can't replace"
431
- *
431
+ *
432
432
  * // 3. Find first lyric when timestamp is less than first entry
433
433
  * const earlyTimeLyric = lyricsList.getBackward(lyric => lyric.value.time <= -1000);
434
434
  * console.log(earlyTimeLyric); // undefined
435
- *
435
+ *
436
436
  * // 4. Find last lyric when timestamp is after last entry
437
437
  * const lateTimeLyric = lyricsList.getBackward(lyric => lyric.value.time <= 50000);
438
438
  * console.log(lateTimeLyric?.text); // 'And I will try to fix you'
439
- * @example
440
- * // cpu process schedules
441
- * class Process {
439
+ * @example
440
+ * // cpu process schedules
441
+ * class Process {
442
442
  * constructor(
443
443
  * public id: number,
444
444
  * public priority: number
445
445
  * ) {}
446
- *
446
+ *
447
447
  * execute(): string {
448
448
  * return `Process ${this.id} executed.`;
449
449
  * }
450
450
  * }
451
- *
451
+ *
452
452
  * class Scheduler {
453
453
  * private queue: DoublyLinkedList<Process>;
454
- *
454
+ *
455
455
  * constructor() {
456
456
  * this.queue = new DoublyLinkedList<Process>();
457
457
  * }
458
- *
458
+ *
459
459
  * addProcess(process: Process): void {
460
460
  * // Insert processes into a queue based on priority, keeping priority in descending order
461
461
  * let current = this.queue.head;
462
462
  * while (current && current.value.priority >= process.priority) {
463
463
  * current = current.next;
464
464
  * }
465
- *
465
+ *
466
466
  * if (!current) {
467
467
  * this.queue.push(process);
468
468
  * } else {
469
469
  * this.queue.addBefore(current, process);
470
470
  * }
471
471
  * }
472
- *
472
+ *
473
473
  * executeNext(): string | undefined {
474
474
  * // Execute tasks at the head of the queue in order
475
475
  * const process = this.queue.shift();
476
476
  * return process ? process.execute() : undefined;
477
477
  * }
478
- *
478
+ *
479
479
  * listProcesses(): string[] {
480
480
  * return this.queue.toArray().map(process => `Process ${process.id} (Priority: ${process.priority})`);
481
481
  * }
482
- *
482
+ *
483
483
  * clear(): void {
484
484
  * this.queue.clear();
485
485
  * }
486
486
  * }
487
- *
487
+ *
488
488
  * // should add processes based on priority
489
489
  * let scheduler = new Scheduler();
490
490
  * scheduler.addProcess(new Process(1, 10));
491
491
  * scheduler.addProcess(new Process(2, 20));
492
492
  * scheduler.addProcess(new Process(3, 15));
493
- *
493
+ *
494
494
  * console.log(scheduler.listProcesses()); // [
495
495
  * // 'Process 2 (Priority: 20)',
496
496
  * // 'Process 3 (Priority: 15)',
497
497
  * // 'Process 1 (Priority: 10)'
498
498
  * // ]
499
- *
499
+ *
500
500
  * // should execute the highest priority process
501
501
  * scheduler = new Scheduler();
502
502
  * scheduler.addProcess(new Process(1, 10));
503
503
  * scheduler.addProcess(new Process(2, 20));
504
- *
504
+ *
505
505
  * console.log(scheduler.executeNext()); // 'Process 2 executed.'
506
506
  * console.log(scheduler.listProcesses()); // ['Process 1 (Priority: 10)']
507
- *
507
+ *
508
508
  * // should clear all processes
509
509
  * scheduler = new Scheduler();
510
510
  * scheduler.addProcess(new Process(1, 10));
511
511
  * scheduler.addProcess(new Process(2, 20));
512
- *
512
+ *
513
513
  * scheduler.clear();
514
514
  * console.log(scheduler.listProcesses()); // []
515
515
  */
516
516
  export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R, DoublyLinkedList<E, R>> {
517
- constructor(elements: Iterable<E> | Iterable<R> = [], options?: DoublyLinkedListOptions<E, R>) {
517
+ /**
518
+ * This TypeScript constructor initializes a DoublyLinkedList with optional elements and options.
519
+ * @param {Iterable<E> | Iterable<R>} elements - The `elements` parameter in the constructor is an
520
+ * iterable collection of elements of type `E` or `R`. It is used to initialize the DoublyLinkedList
521
+ * with the elements provided in the iterable. If no elements are provided, the default value is an
522
+ * empty iterable.
523
+ * @param [options] - The `options` parameter in the constructor is of type
524
+ * `DoublyLinkedListOptions<E, R>`. It is an optional parameter that allows you to pass additional
525
+ * configuration options to customize the behavior of the DoublyLinkedList.
526
+ */
527
+ constructor(
528
+ elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>> = [],
529
+ options?: DoublyLinkedListOptions<E, R>
530
+ ) {
518
531
  super(options);
519
532
  this._head = undefined;
520
533
  this._tail = undefined;
521
534
  this._size = 0;
522
- if (elements) {
523
- for (const el of elements) {
524
- if (this.toElementFn) {
525
- this.push(this.toElementFn(el as R));
526
- } else this.push(el as E);
527
- }
528
- }
535
+ this.pushMany(elements);
529
536
  }
530
537
 
531
538
  protected _head: DoublyLinkedListNode<E> | undefined;
@@ -690,6 +697,57 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
690
697
  return true;
691
698
  }
692
699
 
700
+ /**
701
+ * Time Complexity: O(k)
702
+ * Space Complexity: O(k)
703
+ *
704
+ * The function `pushMany` iterates over elements and pushes them into a data structure, applying a
705
+ * transformation function if provided.
706
+ * @param {Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>} elements - The `elements`
707
+ * parameter in the `pushMany` function can accept an iterable containing elements of type `E`, `R`,
708
+ * or `DoublyLinkedListNode<E>`. The function iterates over each element in the iterable and pushes
709
+ * it onto the linked list. If a transformation function `to
710
+ * @returns The `pushMany` function is returning an array of boolean values (`ans`) which indicate
711
+ * the success or failure of pushing each element into the data structure.
712
+ */
713
+ pushMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>) {
714
+ const ans: boolean[] = [];
715
+ for (const el of elements) {
716
+ if (this.toElementFn) {
717
+ ans.push(this.push(this.toElementFn(el as R)));
718
+ continue;
719
+ }
720
+ ans.push(this.push(el as E | DoublyLinkedListNode<E>));
721
+ }
722
+ return ans;
723
+ }
724
+
725
+ /**
726
+ * Time Complexity: O(k)
727
+ * Space Complexity: O(k)
728
+ *
729
+ * The function `unshiftMany` iterates through a collection of elements and adds them to the
730
+ * beginning of a Doubly Linked List, returning an array of boolean values indicating the success of
731
+ * each insertion.
732
+ * @param {Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>} elements - The `elements`
733
+ * parameter in the `unshiftMany` function can accept an iterable containing elements of type `E`,
734
+ * `R`, or `DoublyLinkedListNode<E>`. The function iterates over each element in the iterable and
735
+ * performs an `unshift` operation on the doubly linked list
736
+ * @returns The `unshiftMany` function returns an array of boolean values indicating the success of
737
+ * each unshift operation performed on the elements passed as input.
738
+ */
739
+ unshiftMany(elements: Iterable<E> | Iterable<R> | Iterable<DoublyLinkedListNode<E>>) {
740
+ const ans: boolean[] = [];
741
+ for (const el of elements) {
742
+ if (this.toElementFn) {
743
+ ans.push(this.unshift(this.toElementFn(el as R)));
744
+ continue;
745
+ }
746
+ ans.push(this.unshift(el as E | DoublyLinkedListNode<E>));
747
+ }
748
+ return ans;
749
+ }
750
+
693
751
  /**
694
752
  * Time Complexity: O(n)
695
753
  * Space Complexity: O(1)
@@ -819,7 +877,9 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
819
877
  existingElementOrNode: E | DoublyLinkedListNode<E>,
820
878
  newElementOrNode: E | DoublyLinkedListNode<E>
821
879
  ): boolean {
822
- const existingNode: DoublyLinkedListNode<E> | undefined = this.getNode(existingElementOrNode);
880
+ const existingNode: DoublyLinkedListNode<E> | undefined = this.isNode(existingElementOrNode)
881
+ ? existingElementOrNode
882
+ : this.getNode(existingElementOrNode);
823
883
 
824
884
  if (existingNode) {
825
885
  const newNode = this._ensureNode(newElementOrNode);
@@ -856,7 +916,9 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
856
916
  * was not found in the linked list.
857
917
  */
858
918
  addAfter(existingElementOrNode: E | DoublyLinkedListNode<E>, newElementOrNode: E | DoublyLinkedListNode<E>): boolean {
859
- const existingNode: DoublyLinkedListNode<E> | undefined = this.getNode(existingElementOrNode);
919
+ const existingNode: DoublyLinkedListNode<E> | undefined = this.isNode(existingElementOrNode)
920
+ ? existingElementOrNode
921
+ : this.getNode(existingElementOrNode);
860
922
 
861
923
  if (existingNode) {
862
924
  const newNode = this._ensureNode(newElementOrNode);
@@ -999,7 +1061,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
999
1061
  * @returns The `get` method returns the value of the first node in the doubly linked list that
1000
1062
  * satisfies the provided predicate function. If no such node is found, it returns `undefined`.
1001
1063
  */
1002
- get(
1064
+ search(
1003
1065
  elementNodeOrPredicate: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)
1004
1066
  ): E | undefined {
1005
1067
  const predicate = this._ensurePredicate(elementNodeOrPredicate);
@@ -1168,6 +1230,12 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
1168
1230
  * Time Complexity: O(n)
1169
1231
  * Space Complexity: O(1)
1170
1232
  *
1233
+ * The function `countOccurrences` iterates through a doubly linked list and counts the occurrences
1234
+ * of a specified element or nodes that satisfy a given predicate.
1235
+ * @param {E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)} elementOrNode
1236
+ * - The `elementOrNode` parameter in the `countOccurrences` method can accept three types of values:
1237
+ * @returns The `countOccurrences` method returns the number of occurrences of the specified element,
1238
+ * node, or predicate function in the doubly linked list.
1171
1239
  */
1172
1240
  countOccurrences(elementOrNode: E | DoublyLinkedListNode<E> | ((node: DoublyLinkedListNode<E>) => boolean)): number {
1173
1241
  const predicate = this._ensurePredicate(elementOrNode);