deque-typed 2.4.4 → 2.5.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/README.md +6 -73
- package/dist/cjs/index.cjs +428 -81
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +428 -81
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +428 -82
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +428 -82
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/common/error.d.ts +23 -0
- package/dist/types/common/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +313 -66
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
- package/dist/umd/deque-typed.js +428 -81
- package/dist/umd/deque-typed.js.map +1 -1
- package/dist/umd/deque-typed.min.js +1 -1
- package/dist/umd/deque-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/common/error.ts +60 -0
- package/src/common/index.ts +2 -0
- package/src/data-structures/base/iterable-element-base.ts +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
- package/src/data-structures/binary-tree/binary-tree.ts +542 -121
- package/src/data-structures/binary-tree/bst.ts +346 -37
- package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1292 -13
- package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
- package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
- package/src/data-structures/binary-tree/tree-set.ts +1143 -15
- package/src/data-structures/graph/abstract-graph.ts +106 -1
- package/src/data-structures/graph/directed-graph.ts +223 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +299 -59
- package/src/data-structures/hash/hash-map.ts +243 -79
- package/src/data-structures/heap/heap.ts +291 -102
- package/src/data-structures/heap/max-heap.ts +48 -3
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +425 -22
- package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +343 -68
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +215 -44
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
- package/src/types/data-structures/queue/deque.ts +7 -0
- package/src/utils/utils.ts +4 -2
package/dist/umd/deque-typed.js
CHANGED
|
@@ -25,12 +25,15 @@ var dequeTyped = (() => {
|
|
|
25
25
|
__export(src_exports, {
|
|
26
26
|
DFSOperation: () => DFSOperation,
|
|
27
27
|
Deque: () => Deque,
|
|
28
|
+
ERR: () => ERR,
|
|
28
29
|
Range: () => Range
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
// src/utils/utils.ts
|
|
32
|
-
var rangeCheck = (index, min, max, message
|
|
33
|
-
if (index < min || index > max)
|
|
33
|
+
var rangeCheck = (index, min, max, message) => {
|
|
34
|
+
if (index < min || index > max) {
|
|
35
|
+
throw new RangeError(message != null ? message : `Index ${index} is out of range [${min}, ${max}].`);
|
|
36
|
+
}
|
|
34
37
|
};
|
|
35
38
|
var calcMinUnitsRequired = (totalQuantity, unitSize) => Math.floor((totalQuantity + unitSize - 1) / unitSize);
|
|
36
39
|
|
|
@@ -446,17 +449,16 @@ var dequeTyped = (() => {
|
|
|
446
449
|
|
|
447
450
|
// src/data-structures/queue/deque.ts
|
|
448
451
|
var Deque = class extends LinearBase {
|
|
449
|
-
/**
|
|
450
|
-
* Create a Deque and optionally bulk-insert elements.
|
|
451
|
-
* @remarks Time O(N), Space O(N)
|
|
452
|
-
* @param [elements] - Iterable (or iterable-like) of elements/records to insert.
|
|
453
|
-
* @param [options] - Options such as bucketSize, toElementFn, and maxLen.
|
|
454
|
-
* @returns New Deque instance.
|
|
455
|
-
*/
|
|
456
452
|
constructor(elements = [], options) {
|
|
457
453
|
super(options);
|
|
458
454
|
__publicField(this, "_equals", (a, b) => Object.is(a, b));
|
|
459
455
|
__publicField(this, "_bucketSize", 1 << 12);
|
|
456
|
+
__publicField(this, "_autoCompactRatio", 0.5);
|
|
457
|
+
/**
|
|
458
|
+
* Counter for shift/pop operations since last compaction check.
|
|
459
|
+
* Only checks ratio every `_bucketSize` operations to minimize overhead.
|
|
460
|
+
*/
|
|
461
|
+
__publicField(this, "_compactCounter", 0);
|
|
460
462
|
__publicField(this, "_bucketFirst", 0);
|
|
461
463
|
__publicField(this, "_firstInBucket", 0);
|
|
462
464
|
__publicField(this, "_bucketLast", 0);
|
|
@@ -465,8 +467,9 @@ var dequeTyped = (() => {
|
|
|
465
467
|
__publicField(this, "_buckets", []);
|
|
466
468
|
__publicField(this, "_length", 0);
|
|
467
469
|
if (options) {
|
|
468
|
-
const { bucketSize } = options;
|
|
470
|
+
const { bucketSize, autoCompactRatio } = options;
|
|
469
471
|
if (typeof bucketSize === "number") this._bucketSize = bucketSize;
|
|
472
|
+
if (typeof autoCompactRatio === "number") this._autoCompactRatio = autoCompactRatio;
|
|
470
473
|
}
|
|
471
474
|
let _size;
|
|
472
475
|
if ("length" in elements) {
|
|
@@ -491,6 +494,24 @@ var dequeTyped = (() => {
|
|
|
491
494
|
get bucketSize() {
|
|
492
495
|
return this._bucketSize;
|
|
493
496
|
}
|
|
497
|
+
/**
|
|
498
|
+
* Get the auto-compaction ratio.
|
|
499
|
+
* When `elements / (bucketCount * bucketSize)` drops below this ratio after
|
|
500
|
+
* enough shift/pop operations, the deque auto-compacts.
|
|
501
|
+
* @remarks Time O(1), Space O(1)
|
|
502
|
+
* @returns Current ratio threshold. 0 means auto-compact is disabled.
|
|
503
|
+
*/
|
|
504
|
+
get autoCompactRatio() {
|
|
505
|
+
return this._autoCompactRatio;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Set the auto-compaction ratio.
|
|
509
|
+
* @remarks Time O(1), Space O(1)
|
|
510
|
+
* @param value - Ratio in [0,1]. 0 disables auto-compact.
|
|
511
|
+
*/
|
|
512
|
+
set autoCompactRatio(value) {
|
|
513
|
+
this._autoCompactRatio = value;
|
|
514
|
+
}
|
|
494
515
|
/**
|
|
495
516
|
* Get the index of the first bucket in use.
|
|
496
517
|
* @remarks Time O(1), Space O(1)
|
|
@@ -548,19 +569,60 @@ var dequeTyped = (() => {
|
|
|
548
569
|
return this._length;
|
|
549
570
|
}
|
|
550
571
|
/**
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
572
|
+
* Get the first element without removing it.
|
|
573
|
+
* @remarks Time O(1), Space O(1)
|
|
574
|
+
* @returns First element or undefined.
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
* @example
|
|
587
|
+
* // Deque peek at both ends
|
|
588
|
+
* const deque = new Deque<number>([10, 20, 30, 40, 50]);
|
|
589
|
+
*
|
|
590
|
+
* // Get first element without removing
|
|
591
|
+
* const first = deque.at(0);
|
|
592
|
+
* console.log(first); // 10;
|
|
593
|
+
*
|
|
594
|
+
* // Get last element without removing
|
|
595
|
+
* const last = deque.at(deque.length - 1);
|
|
596
|
+
* console.log(last); // 50;
|
|
597
|
+
*
|
|
598
|
+
* // Length unchanged
|
|
599
|
+
* console.log(deque.length); // 5;
|
|
600
|
+
*/
|
|
555
601
|
get first() {
|
|
556
602
|
if (this._length === 0) return;
|
|
557
603
|
return this._buckets[this._bucketFirst][this._firstInBucket];
|
|
558
604
|
}
|
|
559
605
|
/**
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
606
|
+
* Get the last element without removing it.
|
|
607
|
+
* @remarks Time O(1), Space O(1)
|
|
608
|
+
* @returns Last element or undefined.
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
* @example
|
|
621
|
+
* // Peek at the back element
|
|
622
|
+
* const dq = new Deque<string>(['a', 'b', 'c']);
|
|
623
|
+
* console.log(dq.last); // 'c';
|
|
624
|
+
* console.log(dq.first); // 'a';
|
|
625
|
+
*/
|
|
564
626
|
get last() {
|
|
565
627
|
if (this._length === 0) return;
|
|
566
628
|
return this._buckets[this._bucketLast][this._lastInBucket];
|
|
@@ -579,11 +641,40 @@ var dequeTyped = (() => {
|
|
|
579
641
|
return new this(data, options);
|
|
580
642
|
}
|
|
581
643
|
/**
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
644
|
+
* Append one element at the back.
|
|
645
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
646
|
+
* @param element - Element to append.
|
|
647
|
+
* @returns True when appended.
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
* @example
|
|
660
|
+
* // basic Deque creation and push/pop operations
|
|
661
|
+
* // Create a simple Deque with initial values
|
|
662
|
+
* const deque = new Deque([1, 2, 3, 4, 5]);
|
|
663
|
+
*
|
|
664
|
+
* // Verify the deque maintains insertion order
|
|
665
|
+
* console.log([...deque]); // [1, 2, 3, 4, 5];
|
|
666
|
+
*
|
|
667
|
+
* // Check length
|
|
668
|
+
* console.log(deque.length); // 5;
|
|
669
|
+
*
|
|
670
|
+
* // Push to the end
|
|
671
|
+
* deque.push(6);
|
|
672
|
+
* console.log(deque.length); // 6;
|
|
673
|
+
*
|
|
674
|
+
* // Pop from the end
|
|
675
|
+
* const last = deque.pop();
|
|
676
|
+
* console.log(last); // 6;
|
|
677
|
+
*/
|
|
587
678
|
push(element) {
|
|
588
679
|
if (this._length) {
|
|
589
680
|
if (this._lastInBucket < this._bucketSize - 1) {
|
|
@@ -603,10 +694,26 @@ var dequeTyped = (() => {
|
|
|
603
694
|
return true;
|
|
604
695
|
}
|
|
605
696
|
/**
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
697
|
+
* Remove and return the last element.
|
|
698
|
+
* @remarks Time O(1), Space O(1)
|
|
699
|
+
* @returns Removed element or undefined.
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
* @example
|
|
712
|
+
* // Remove from the back
|
|
713
|
+
* const dq = new Deque<number>([1, 2, 3]);
|
|
714
|
+
* console.log(dq.pop()); // 3;
|
|
715
|
+
* console.log(dq.length); // 2;
|
|
716
|
+
*/
|
|
610
717
|
pop() {
|
|
611
718
|
if (this._length === 0) return;
|
|
612
719
|
const element = this._buckets[this._bucketLast][this._lastInBucket];
|
|
@@ -622,13 +729,30 @@ var dequeTyped = (() => {
|
|
|
622
729
|
}
|
|
623
730
|
}
|
|
624
731
|
this._length -= 1;
|
|
732
|
+
this._autoCompact();
|
|
625
733
|
return element;
|
|
626
734
|
}
|
|
627
735
|
/**
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
736
|
+
* Remove and return the first element.
|
|
737
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
738
|
+
* @returns Removed element or undefined.
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
* @example
|
|
751
|
+
* // Remove from the front
|
|
752
|
+
* const dq = new Deque<number>([1, 2, 3]);
|
|
753
|
+
* console.log(dq.shift()); // 1;
|
|
754
|
+
* console.log(dq.length); // 2;
|
|
755
|
+
*/
|
|
632
756
|
shift() {
|
|
633
757
|
if (this._length === 0) return;
|
|
634
758
|
const element = this._buckets[this._bucketFirst][this._firstInBucket];
|
|
@@ -644,14 +768,41 @@ var dequeTyped = (() => {
|
|
|
644
768
|
}
|
|
645
769
|
}
|
|
646
770
|
this._length -= 1;
|
|
771
|
+
this._autoCompact();
|
|
647
772
|
return element;
|
|
648
773
|
}
|
|
649
774
|
/**
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
775
|
+
* Prepend one element at the front.
|
|
776
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
777
|
+
* @param element - Element to prepend.
|
|
778
|
+
* @returns True when prepended.
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
* @example
|
|
791
|
+
* // Deque shift and unshift operations
|
|
792
|
+
* const deque = new Deque<number>([20, 30, 40]);
|
|
793
|
+
*
|
|
794
|
+
* // Unshift adds to the front
|
|
795
|
+
* deque.unshift(10);
|
|
796
|
+
* console.log([...deque]); // [10, 20, 30, 40];
|
|
797
|
+
*
|
|
798
|
+
* // Shift removes from the front (O(1) complexity!)
|
|
799
|
+
* const first = deque.shift();
|
|
800
|
+
* console.log(first); // 10;
|
|
801
|
+
*
|
|
802
|
+
* // Verify remaining elements
|
|
803
|
+
* console.log([...deque]); // [20, 30, 40];
|
|
804
|
+
* console.log(deque.length); // 3;
|
|
805
|
+
*/
|
|
655
806
|
unshift(element) {
|
|
656
807
|
if (this._length) {
|
|
657
808
|
if (this._firstInBucket > 0) {
|
|
@@ -705,18 +856,45 @@ var dequeTyped = (() => {
|
|
|
705
856
|
return ans;
|
|
706
857
|
}
|
|
707
858
|
/**
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
859
|
+
* Check whether the deque is empty.
|
|
860
|
+
* @remarks Time O(1), Space O(1)
|
|
861
|
+
* @returns True if length is 0.
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
* @example
|
|
872
|
+
* // Check if empty
|
|
873
|
+
* const dq = new Deque();
|
|
874
|
+
* console.log(dq.isEmpty()); // true;
|
|
875
|
+
*/
|
|
712
876
|
isEmpty() {
|
|
713
877
|
return this._length === 0;
|
|
714
878
|
}
|
|
715
879
|
/**
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
880
|
+
* Remove all elements and reset structure.
|
|
881
|
+
* @remarks Time O(1), Space O(1)
|
|
882
|
+
* @returns void
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
* @example
|
|
893
|
+
* // Remove all elements
|
|
894
|
+
* const dq = new Deque<number>([1, 2, 3]);
|
|
895
|
+
* dq.clear();
|
|
896
|
+
* console.log(dq.length); // 0;
|
|
897
|
+
*/
|
|
720
898
|
clear() {
|
|
721
899
|
this._buckets = [new Array(this._bucketSize)];
|
|
722
900
|
this._bucketCount = 1;
|
|
@@ -724,11 +902,24 @@ var dequeTyped = (() => {
|
|
|
724
902
|
this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;
|
|
725
903
|
}
|
|
726
904
|
/**
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
905
|
+
* Get the element at a given position.
|
|
906
|
+
* @remarks Time O(1), Space O(1)
|
|
907
|
+
* @param pos - Zero-based position from the front.
|
|
908
|
+
* @returns Element or undefined.
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
* @example
|
|
918
|
+
* // Access by index
|
|
919
|
+
* const dq = new Deque<string>(['a', 'b', 'c']);
|
|
920
|
+
* console.log(dq.at(0)); // 'a';
|
|
921
|
+
* console.log(dq.at(2)); // 'c';
|
|
922
|
+
*/
|
|
732
923
|
at(pos) {
|
|
733
924
|
if (pos < 0 || pos >= this._length) return void 0;
|
|
734
925
|
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
|
|
@@ -887,11 +1078,24 @@ var dequeTyped = (() => {
|
|
|
887
1078
|
}
|
|
888
1079
|
}
|
|
889
1080
|
/**
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
1081
|
+
* Delete the first occurrence of a value.
|
|
1082
|
+
* @remarks Time O(N), Space O(1)
|
|
1083
|
+
* @param element - Element to remove (using the configured equality).
|
|
1084
|
+
* @returns True if an element was removed.
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
* @example
|
|
1094
|
+
* // Remove element
|
|
1095
|
+
* const dq = new Deque<number>([1, 2, 3]);
|
|
1096
|
+
* dq.delete(2);
|
|
1097
|
+
* console.log(dq.length); // 2;
|
|
1098
|
+
*/
|
|
895
1099
|
delete(element) {
|
|
896
1100
|
const size = this._length;
|
|
897
1101
|
if (size === 0) return false;
|
|
@@ -935,10 +1139,39 @@ var dequeTyped = (() => {
|
|
|
935
1139
|
return this;
|
|
936
1140
|
}
|
|
937
1141
|
/**
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
1142
|
+
* Reverse the deque by reversing buckets and pointers.
|
|
1143
|
+
* @remarks Time O(N), Space O(N)
|
|
1144
|
+
* @returns This deque.
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
* @example
|
|
1157
|
+
* // Deque for...of iteration and reverse
|
|
1158
|
+
* const deque = new Deque<string>(['A', 'B', 'C', 'D']);
|
|
1159
|
+
*
|
|
1160
|
+
* // Iterate forward
|
|
1161
|
+
* const forward: string[] = [];
|
|
1162
|
+
* for (const item of deque) {
|
|
1163
|
+
* forward.push(item);
|
|
1164
|
+
* }
|
|
1165
|
+
* console.log(forward); // ['A', 'B', 'C', 'D'];
|
|
1166
|
+
*
|
|
1167
|
+
* // Reverse the deque
|
|
1168
|
+
* deque.reverse();
|
|
1169
|
+
* const backward: string[] = [];
|
|
1170
|
+
* for (const item of deque) {
|
|
1171
|
+
* backward.push(item);
|
|
1172
|
+
* }
|
|
1173
|
+
* console.log(backward); // ['D', 'C', 'B', 'A'];
|
|
1174
|
+
*/
|
|
942
1175
|
reverse() {
|
|
943
1176
|
this._buckets.reverse().forEach(function(bucket) {
|
|
944
1177
|
bucket.reverse();
|
|
@@ -976,11 +1209,55 @@ var dequeTyped = (() => {
|
|
|
976
1209
|
* @remarks Time O(N), Space O(1)
|
|
977
1210
|
* @returns void
|
|
978
1211
|
*/
|
|
1212
|
+
/**
|
|
1213
|
+
* (Protected) Trigger auto-compaction if space utilization drops below threshold.
|
|
1214
|
+
* Only checks every `_bucketSize` operations to minimize hot-path overhead.
|
|
1215
|
+
* Uses element-based ratio: `elements / (bucketCount * bucketSize)`.
|
|
1216
|
+
*/
|
|
1217
|
+
_autoCompact() {
|
|
1218
|
+
if (this._autoCompactRatio <= 0 || this._bucketCount <= 1) return;
|
|
1219
|
+
this._compactCounter++;
|
|
1220
|
+
if (this._compactCounter < this._bucketSize) return;
|
|
1221
|
+
this._compactCounter = 0;
|
|
1222
|
+
const utilization = this._length / (this._bucketCount * this._bucketSize);
|
|
1223
|
+
if (utilization < this._autoCompactRatio) {
|
|
1224
|
+
this.shrinkToFit();
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Compact the deque by removing unused buckets.
|
|
1229
|
+
* @remarks Time O(N), Space O(1)
|
|
1230
|
+
* @returns True if compaction was performed (bucket count reduced).
|
|
1231
|
+
*/
|
|
1232
|
+
/**
|
|
1233
|
+
* Compact the deque by removing unused buckets.
|
|
1234
|
+
* @remarks Time O(N), Space O(1)
|
|
1235
|
+
* @returns True if compaction was performed (bucket count reduced).
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
|
|
1243
|
+
|
|
1244
|
+
* @example
|
|
1245
|
+
* // Reclaim memory
|
|
1246
|
+
* const dq = new Deque<number>([1, 2, 3, 4, 5]);
|
|
1247
|
+
* dq.shift();
|
|
1248
|
+
* dq.shift();
|
|
1249
|
+
* dq.compact();
|
|
1250
|
+
* console.log(dq.length); // 3;
|
|
1251
|
+
*/
|
|
1252
|
+
compact() {
|
|
1253
|
+
const before = this._bucketCount;
|
|
1254
|
+
this.shrinkToFit();
|
|
1255
|
+
return this._bucketCount < before;
|
|
1256
|
+
}
|
|
979
1257
|
shrinkToFit() {
|
|
980
1258
|
if (this._length === 0) return;
|
|
981
1259
|
const newBuckets = [];
|
|
982
|
-
if (this._bucketFirst
|
|
983
|
-
else if (this._bucketFirst < this._bucketLast) {
|
|
1260
|
+
if (this._bucketFirst <= this._bucketLast) {
|
|
984
1261
|
for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {
|
|
985
1262
|
newBuckets.push(this._buckets[i]);
|
|
986
1263
|
}
|
|
@@ -995,12 +1272,30 @@ var dequeTyped = (() => {
|
|
|
995
1272
|
this._bucketFirst = 0;
|
|
996
1273
|
this._bucketLast = newBuckets.length - 1;
|
|
997
1274
|
this._buckets = newBuckets;
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1275
|
+
this._bucketCount = newBuckets.length;
|
|
1276
|
+
this._compactCounter = 0;
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* Deep clone this deque, preserving options.
|
|
1280
|
+
* @remarks Time O(N), Space O(N)
|
|
1281
|
+
* @returns A new deque with the same content and options.
|
|
1282
|
+
|
|
1283
|
+
|
|
1284
|
+
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
|
|
1288
|
+
|
|
1289
|
+
|
|
1290
|
+
|
|
1291
|
+
* @example
|
|
1292
|
+
* // Create independent copy
|
|
1293
|
+
* const dq = new Deque<number>([1, 2, 3]);
|
|
1294
|
+
* const copy = dq.clone();
|
|
1295
|
+
* copy.pop();
|
|
1296
|
+
* console.log(dq.length); // 3;
|
|
1297
|
+
* console.log(copy.length); // 2;
|
|
1298
|
+
*/
|
|
1004
1299
|
clone() {
|
|
1005
1300
|
return this._createLike(this, {
|
|
1006
1301
|
bucketSize: this.bucketSize,
|
|
@@ -1009,12 +1304,26 @@ var dequeTyped = (() => {
|
|
|
1009
1304
|
});
|
|
1010
1305
|
}
|
|
1011
1306
|
/**
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1307
|
+
* Filter elements into a new deque of the same class.
|
|
1308
|
+
* @remarks Time O(N), Space O(N)
|
|
1309
|
+
* @param predicate - Predicate (value, index, deque) → boolean to keep element.
|
|
1310
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
1311
|
+
* @returns A new deque with kept elements.
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
* @example
|
|
1322
|
+
* // Filter elements
|
|
1323
|
+
* const dq = new Deque<number>([1, 2, 3, 4]);
|
|
1324
|
+
* const result = dq.filter(x => x > 2);
|
|
1325
|
+
* console.log(result.length); // 2;
|
|
1326
|
+
*/
|
|
1018
1327
|
filter(predicate, thisArg) {
|
|
1019
1328
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1020
1329
|
out._setBucketSize(this._bucketSize);
|
|
@@ -1043,15 +1352,28 @@ var dequeTyped = (() => {
|
|
|
1043
1352
|
return out;
|
|
1044
1353
|
}
|
|
1045
1354
|
/**
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1355
|
+
* Map elements into a new deque (possibly different element type).
|
|
1356
|
+
* @remarks Time O(N), Space O(N)
|
|
1357
|
+
* @template EM
|
|
1358
|
+
* @template RM
|
|
1359
|
+
* @param callback - Mapping function (value, index, deque) → newElement.
|
|
1360
|
+
* @param [options] - Options for the output deque (e.g., bucketSize, toElementFn, maxLen).
|
|
1361
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1362
|
+
* @returns A new Deque with mapped elements.
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
|
|
1370
|
+
|
|
1371
|
+
* @example
|
|
1372
|
+
* // Transform elements
|
|
1373
|
+
* const dq = new Deque<number>([1, 2, 3]);
|
|
1374
|
+
* const result = dq.map(x => x * 10);
|
|
1375
|
+
* console.log(result.toArray()); // [10, 20, 30];
|
|
1376
|
+
*/
|
|
1055
1377
|
map(callback, options, thisArg) {
|
|
1056
1378
|
const out = this._createLike([], {
|
|
1057
1379
|
...options != null ? options : {},
|
|
@@ -1175,6 +1497,31 @@ var dequeTyped = (() => {
|
|
|
1175
1497
|
}
|
|
1176
1498
|
};
|
|
1177
1499
|
|
|
1500
|
+
// src/common/error.ts
|
|
1501
|
+
var ERR = {
|
|
1502
|
+
// Range / index
|
|
1503
|
+
indexOutOfRange: (index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`,
|
|
1504
|
+
invalidIndex: (ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`,
|
|
1505
|
+
// Type / argument
|
|
1506
|
+
invalidArgument: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
1507
|
+
comparatorRequired: (ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`,
|
|
1508
|
+
invalidKey: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
1509
|
+
notAFunction: (name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`,
|
|
1510
|
+
invalidEntry: (ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`,
|
|
1511
|
+
invalidNaN: (ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`,
|
|
1512
|
+
invalidDate: (ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`,
|
|
1513
|
+
reduceEmpty: (ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`,
|
|
1514
|
+
callbackReturnType: (expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`,
|
|
1515
|
+
// State / operation
|
|
1516
|
+
invalidOperation: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
1517
|
+
// Matrix
|
|
1518
|
+
matrixDimensionMismatch: (op) => `Matrix: Dimensions must be compatible for ${op}.`,
|
|
1519
|
+
matrixSingular: () => "Matrix: Singular matrix, inverse does not exist.",
|
|
1520
|
+
matrixNotSquare: () => "Matrix: Must be square for inversion.",
|
|
1521
|
+
matrixNotRectangular: () => "Matrix: Must be rectangular for transposition.",
|
|
1522
|
+
matrixRowMismatch: (expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`
|
|
1523
|
+
};
|
|
1524
|
+
|
|
1178
1525
|
// src/common/index.ts
|
|
1179
1526
|
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
1180
1527
|
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|