directed-graph-typed 2.4.5 → 2.5.1
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 +0 -51
- package/dist/cjs/index.cjs +1819 -356
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +1818 -355
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1819 -356
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +1818 -355
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
- package/dist/types/data-structures/base/linear-base.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +380 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +487 -147
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +956 -80
- package/dist/types/data-structures/binary-tree/bst.d.ts +816 -29
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +610 -31
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +326 -135
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +3781 -6
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3607 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2874 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +3528 -6
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
- package/dist/types/data-structures/graph/directed-graph.d.ts +429 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +393 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +473 -89
- package/dist/types/data-structures/heap/heap.d.ts +581 -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 +646 -47
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +596 -68
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +793 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +499 -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 +593 -71
- package/dist/types/data-structures/queue/queue.d.ts +463 -42
- package/dist/types/data-structures/stack/stack.d.ts +384 -32
- package/dist/types/data-structures/trie/trie.d.ts +470 -48
- package/dist/types/interfaces/graph.d.ts +1 -1
- package/dist/types/types/common.d.ts +2 -2
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
- package/dist/types/types/utils/validate-type.d.ts +4 -4
- package/dist/umd/directed-graph-typed.js +1816 -353
- package/dist/umd/directed-graph-typed.js.map +1 -1
- package/dist/umd/directed-graph-typed.min.js +3 -3
- package/dist/umd/directed-graph-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- package/src/data-structures/base/iterable-entry-base.ts +8 -8
- package/src/data-structures/base/linear-base.ts +3 -3
- package/src/data-structures/binary-tree/avl-tree.ts +386 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +596 -247
- package/src/data-structures/binary-tree/binary-tree.ts +956 -81
- package/src/data-structures/binary-tree/bst.ts +840 -35
- package/src/data-structures/binary-tree/red-black-tree.ts +689 -97
- package/src/data-structures/binary-tree/segment-tree.ts +498 -249
- package/src/data-structures/binary-tree/tree-map.ts +3784 -7
- package/src/data-structures/binary-tree/tree-multi-map.ts +3614 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +2874 -65
- package/src/data-structures/binary-tree/tree-set.ts +3531 -10
- package/src/data-structures/graph/abstract-graph.ts +4 -4
- package/src/data-structures/graph/directed-graph.ts +429 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +393 -59
- package/src/data-structures/hash/hash-map.ts +476 -92
- package/src/data-structures/heap/heap.ts +581 -99
- package/src/data-structures/heap/max-heap.ts +46 -0
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +646 -47
- package/src/data-structures/linked-list/singly-linked-list.ts +596 -68
- package/src/data-structures/linked-list/skip-linked-list.ts +1067 -90
- package/src/data-structures/matrix/matrix.ts +584 -12
- package/src/data-structures/priority-queue/max-priority-queue.ts +57 -0
- 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 +592 -70
- package/src/data-structures/queue/queue.ts +463 -42
- package/src/data-structures/stack/stack.ts +384 -32
- package/src/data-structures/trie/trie.ts +470 -48
- package/src/interfaces/graph.ts +1 -1
- package/src/types/common.ts +2 -2
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/heap/heap.ts +1 -0
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
- package/src/types/utils/validate-type.ts +4 -4
package/dist/esm/index.mjs
CHANGED
|
@@ -271,7 +271,7 @@ var IterableElementBase = class {
|
|
|
271
271
|
if (options) {
|
|
272
272
|
const { toElementFn } = options;
|
|
273
273
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
274
|
-
else if (toElementFn) throw new TypeError(
|
|
274
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
277
|
/**
|
|
@@ -434,7 +434,7 @@ var IterableElementBase = class {
|
|
|
434
434
|
acc = initialValue;
|
|
435
435
|
} else {
|
|
436
436
|
const first = iter.next();
|
|
437
|
-
if (first.done) throw new TypeError(
|
|
437
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
438
438
|
acc = first.value;
|
|
439
439
|
index = 1;
|
|
440
440
|
}
|
|
@@ -476,6 +476,199 @@ var IterableElementBase = class {
|
|
|
476
476
|
}
|
|
477
477
|
};
|
|
478
478
|
|
|
479
|
+
// src/data-structures/base/linear-base.ts
|
|
480
|
+
var LinearBase = class _LinearBase extends IterableElementBase {
|
|
481
|
+
static {
|
|
482
|
+
__name(this, "LinearBase");
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Construct a linear container with runtime options.
|
|
486
|
+
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
487
|
+
* @remarks Time O(1), Space O(1)
|
|
488
|
+
*/
|
|
489
|
+
constructor(options) {
|
|
490
|
+
super(options);
|
|
491
|
+
if (options) {
|
|
492
|
+
const { maxLen } = options;
|
|
493
|
+
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
_maxLen = -1;
|
|
497
|
+
/**
|
|
498
|
+
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
499
|
+
* @returns Maximum allowed length.
|
|
500
|
+
* @remarks Time O(1), Space O(1)
|
|
501
|
+
*/
|
|
502
|
+
get maxLen() {
|
|
503
|
+
return this._maxLen;
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* First index of a value from the left.
|
|
507
|
+
* @param searchElement - Value to match.
|
|
508
|
+
* @param fromIndex - Start position (supports negative index).
|
|
509
|
+
* @returns Index or `-1` if not found.
|
|
510
|
+
* @remarks Time O(n), Space O(1)
|
|
511
|
+
*/
|
|
512
|
+
indexOf(searchElement, fromIndex = 0) {
|
|
513
|
+
if (this.length === 0) return -1;
|
|
514
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
515
|
+
if (fromIndex < 0) fromIndex = 0;
|
|
516
|
+
for (let i = fromIndex; i < this.length; i++) {
|
|
517
|
+
const element = this.at(i);
|
|
518
|
+
if (element === searchElement) return i;
|
|
519
|
+
}
|
|
520
|
+
return -1;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Last index of a value from the right.
|
|
524
|
+
* @param searchElement - Value to match.
|
|
525
|
+
* @param fromIndex - Start position (supports negative index).
|
|
526
|
+
* @returns Index or `-1` if not found.
|
|
527
|
+
* @remarks Time O(n), Space O(1)
|
|
528
|
+
*/
|
|
529
|
+
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
530
|
+
if (this.length === 0) return -1;
|
|
531
|
+
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
532
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
533
|
+
for (let i = fromIndex; i >= 0; i--) {
|
|
534
|
+
const element = this.at(i);
|
|
535
|
+
if (element === searchElement) return i;
|
|
536
|
+
}
|
|
537
|
+
return -1;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Find the first index matching a predicate.
|
|
541
|
+
* @param predicate - `(element, index, self) => boolean`.
|
|
542
|
+
* @param thisArg - Optional `this` for callback.
|
|
543
|
+
* @returns Index or `-1`.
|
|
544
|
+
* @remarks Time O(n), Space O(1)
|
|
545
|
+
*/
|
|
546
|
+
findIndex(predicate, thisArg) {
|
|
547
|
+
for (let i = 0; i < this.length; i++) {
|
|
548
|
+
const item = this.at(i);
|
|
549
|
+
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
550
|
+
}
|
|
551
|
+
return -1;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Concatenate elements and/or containers.
|
|
555
|
+
* @param items - Elements or other containers.
|
|
556
|
+
* @returns New container with combined elements (`this` type).
|
|
557
|
+
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
558
|
+
*/
|
|
559
|
+
concat(...items) {
|
|
560
|
+
const newList = this.clone();
|
|
561
|
+
for (const item of items) {
|
|
562
|
+
if (item instanceof _LinearBase) {
|
|
563
|
+
newList.pushMany(item);
|
|
564
|
+
} else {
|
|
565
|
+
newList.push(item);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return newList;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* In-place stable order via array sort semantics.
|
|
572
|
+
* @param compareFn - Comparator `(a, b) => number`.
|
|
573
|
+
* @returns This container.
|
|
574
|
+
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
575
|
+
*/
|
|
576
|
+
sort(compareFn) {
|
|
577
|
+
const arr = this.toArray();
|
|
578
|
+
arr.sort(compareFn);
|
|
579
|
+
this.clear();
|
|
580
|
+
for (const item of arr) this.push(item);
|
|
581
|
+
return this;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Remove and/or insert elements at a position (array-compatible).
|
|
585
|
+
* @param start - Start index (supports negative index).
|
|
586
|
+
* @param deleteCount - How many to remove.
|
|
587
|
+
* @param items - Elements to insert.
|
|
588
|
+
* @returns Removed elements as a new list (`this` type).
|
|
589
|
+
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
590
|
+
*/
|
|
591
|
+
splice(start, deleteCount = 0, ...items) {
|
|
592
|
+
const removedList = this._createInstance();
|
|
593
|
+
start = start < 0 ? this.length + start : start;
|
|
594
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
595
|
+
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
596
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
597
|
+
const removed = this.deleteAt(start);
|
|
598
|
+
if (removed !== void 0) {
|
|
599
|
+
removedList.push(removed);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
for (let i = 0; i < items.length; i++) {
|
|
603
|
+
this.addAt(start + i, items[i]);
|
|
604
|
+
}
|
|
605
|
+
return removedList;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Join all elements into a string.
|
|
609
|
+
* @param separator - Separator string.
|
|
610
|
+
* @returns Concatenated string.
|
|
611
|
+
* @remarks Time O(n), Space O(n)
|
|
612
|
+
*/
|
|
613
|
+
join(separator = ",") {
|
|
614
|
+
return this.toArray().join(separator);
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Snapshot elements into a reversed array.
|
|
618
|
+
* @returns New reversed array.
|
|
619
|
+
* @remarks Time O(n), Space O(n)
|
|
620
|
+
*/
|
|
621
|
+
toReversedArray() {
|
|
622
|
+
const array = [];
|
|
623
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
624
|
+
array.push(this.at(i));
|
|
625
|
+
}
|
|
626
|
+
return array;
|
|
627
|
+
}
|
|
628
|
+
reduceRight(callbackfn, initialValue) {
|
|
629
|
+
let accumulator = initialValue ?? 0;
|
|
630
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
631
|
+
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
632
|
+
}
|
|
633
|
+
return accumulator;
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Create a shallow copy of a subrange.
|
|
637
|
+
* @param start - Inclusive start (supports negative index).
|
|
638
|
+
* @param end - Exclusive end (supports negative index).
|
|
639
|
+
* @returns New list with the range (`this` type).
|
|
640
|
+
* @remarks Time O(n), Space O(n)
|
|
641
|
+
*/
|
|
642
|
+
slice(start = 0, end = this.length) {
|
|
643
|
+
start = start < 0 ? this.length + start : start;
|
|
644
|
+
end = end < 0 ? this.length + end : end;
|
|
645
|
+
const newList = this._createInstance();
|
|
646
|
+
for (let i = start; i < end; i++) {
|
|
647
|
+
newList.push(this.at(i));
|
|
648
|
+
}
|
|
649
|
+
return newList;
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Fill a range with a value.
|
|
653
|
+
* @param value - Value to set.
|
|
654
|
+
* @param start - Inclusive start.
|
|
655
|
+
* @param end - Exclusive end.
|
|
656
|
+
* @returns This list.
|
|
657
|
+
* @remarks Time O(n), Space O(1)
|
|
658
|
+
*/
|
|
659
|
+
fill(value, start = 0, end = this.length) {
|
|
660
|
+
start = start < 0 ? this.length + start : start;
|
|
661
|
+
end = end < 0 ? this.length + end : end;
|
|
662
|
+
if (start < 0) start = 0;
|
|
663
|
+
if (end > this.length) end = this.length;
|
|
664
|
+
if (start >= end) return this;
|
|
665
|
+
for (let i = start; i < end; i++) {
|
|
666
|
+
this.setAt(i, value);
|
|
667
|
+
}
|
|
668
|
+
return this;
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
|
|
479
672
|
// src/data-structures/heap/heap.ts
|
|
480
673
|
var Heap = class _Heap extends IterableElementBase {
|
|
481
674
|
static {
|
|
@@ -507,10 +700,51 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
507
700
|
return this._elements;
|
|
508
701
|
}
|
|
509
702
|
/**
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
703
|
+
* Get the number of elements.
|
|
704
|
+
* @remarks Time O(1), Space O(1)
|
|
705
|
+
* @returns Heap size.
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
* @example
|
|
739
|
+
* // Track heap capacity
|
|
740
|
+
* const heap = new Heap<number>();
|
|
741
|
+
* console.log(heap.size); // 0;
|
|
742
|
+
* heap.add(10);
|
|
743
|
+
* heap.add(20);
|
|
744
|
+
* console.log(heap.size); // 2;
|
|
745
|
+
* heap.poll();
|
|
746
|
+
* console.log(heap.size); // 1;
|
|
747
|
+
*/
|
|
514
748
|
get size() {
|
|
515
749
|
return this.elements.length;
|
|
516
750
|
}
|
|
@@ -548,21 +782,103 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
548
782
|
return new _Heap(elements, options);
|
|
549
783
|
}
|
|
550
784
|
/**
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
785
|
+
* Insert an element.
|
|
786
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
787
|
+
* @param element - Element to insert.
|
|
788
|
+
* @returns True.
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
* @example
|
|
822
|
+
* // basic Heap creation and add operation
|
|
823
|
+
* // Create a min heap (default)
|
|
824
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
825
|
+
*
|
|
826
|
+
* // Verify size
|
|
827
|
+
* console.log(minHeap.size); // 6;
|
|
828
|
+
*
|
|
829
|
+
* // Add new element
|
|
830
|
+
* minHeap.add(4);
|
|
831
|
+
* console.log(minHeap.size); // 7;
|
|
832
|
+
*
|
|
833
|
+
* // Min heap property: smallest element at root
|
|
834
|
+
* const min = minHeap.peek();
|
|
835
|
+
* console.log(min); // 1;
|
|
836
|
+
*/
|
|
556
837
|
add(element) {
|
|
557
838
|
this._elements.push(element);
|
|
558
839
|
return this._bubbleUp(this.elements.length - 1);
|
|
559
840
|
}
|
|
560
841
|
/**
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
842
|
+
* Insert many elements from an iterable.
|
|
843
|
+
* @remarks Time O(N log N), Space O(1)
|
|
844
|
+
* @param elements - Iterable of elements or raw values.
|
|
845
|
+
* @returns Array of per-element success flags.
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
* @example
|
|
876
|
+
* // Add multiple elements
|
|
877
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
878
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
879
|
+
* console.log(heap.peek()); // 1;
|
|
880
|
+
* console.log(heap.size); // 4;
|
|
881
|
+
*/
|
|
566
882
|
addMany(elements) {
|
|
567
883
|
const flags = [];
|
|
568
884
|
for (const el of elements) {
|
|
@@ -577,10 +893,67 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
577
893
|
return flags;
|
|
578
894
|
}
|
|
579
895
|
/**
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
896
|
+
* Remove and return the top element.
|
|
897
|
+
* @remarks Time O(log N), Space O(1)
|
|
898
|
+
* @returns Top element or undefined.
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
* @example
|
|
932
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
933
|
+
* interface Task {
|
|
934
|
+
* id: number;
|
|
935
|
+
* priority: number;
|
|
936
|
+
* name: string;
|
|
937
|
+
* }
|
|
938
|
+
*
|
|
939
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
940
|
+
* const tasks: Task[] = [
|
|
941
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
942
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
943
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
944
|
+
* ];
|
|
945
|
+
*
|
|
946
|
+
* const maxHeap = new Heap(tasks, {
|
|
947
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
948
|
+
* });
|
|
949
|
+
*
|
|
950
|
+
* console.log(maxHeap.size); // 3;
|
|
951
|
+
*
|
|
952
|
+
* // Peek returns highest priority task
|
|
953
|
+
* const topTask = maxHeap.peek();
|
|
954
|
+
* console.log(topTask?.priority); // 8;
|
|
955
|
+
* console.log(topTask?.name); // 'Alert';
|
|
956
|
+
*/
|
|
584
957
|
poll() {
|
|
585
958
|
if (this.elements.length === 0) return;
|
|
586
959
|
const value = this.elements[0];
|
|
@@ -592,26 +965,188 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
592
965
|
return value;
|
|
593
966
|
}
|
|
594
967
|
/**
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
968
|
+
* Get the current top element without removing it.
|
|
969
|
+
* @remarks Time O(1), Space O(1)
|
|
970
|
+
* @returns Top element or undefined.
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
* @example
|
|
1004
|
+
* // Heap for event processing with priority
|
|
1005
|
+
* interface Event {
|
|
1006
|
+
* id: number;
|
|
1007
|
+
* type: 'critical' | 'warning' | 'info';
|
|
1008
|
+
* timestamp: number;
|
|
1009
|
+
* message: string;
|
|
1010
|
+
* }
|
|
1011
|
+
*
|
|
1012
|
+
* // Custom priority: critical > warning > info
|
|
1013
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
1014
|
+
*
|
|
1015
|
+
* const eventHeap = new Heap<Event>([], {
|
|
1016
|
+
* comparator: (a: Event, b: Event) => {
|
|
1017
|
+
* const priorityA = priorityMap[a.type];
|
|
1018
|
+
* const priorityB = priorityMap[b.type];
|
|
1019
|
+
* return priorityB - priorityA; // Higher priority first
|
|
1020
|
+
* }
|
|
1021
|
+
* });
|
|
1022
|
+
*
|
|
1023
|
+
* // Add events in random order
|
|
1024
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
1025
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
1026
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
1027
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
1028
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
1029
|
+
*
|
|
1030
|
+
* console.log(eventHeap.size); // 5;
|
|
1031
|
+
*
|
|
1032
|
+
* // Process events by priority (critical first)
|
|
1033
|
+
* const processedOrder: Event[] = [];
|
|
1034
|
+
* while (eventHeap.size > 0) {
|
|
1035
|
+
* const event = eventHeap.poll();
|
|
1036
|
+
* if (event) {
|
|
1037
|
+
* processedOrder.push(event);
|
|
1038
|
+
* }
|
|
1039
|
+
* }
|
|
1040
|
+
*
|
|
1041
|
+
* // Verify critical events came first
|
|
1042
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
1043
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
1044
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
1045
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
1046
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
1047
|
+
*
|
|
1048
|
+
* // Verify O(log n) operations
|
|
1049
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
1050
|
+
*
|
|
1051
|
+
* // Add - O(log n)
|
|
1052
|
+
* newHeap.add(2);
|
|
1053
|
+
* console.log(newHeap.size); // 5;
|
|
1054
|
+
*
|
|
1055
|
+
* // Poll - O(log n)
|
|
1056
|
+
* const removed = newHeap.poll();
|
|
1057
|
+
* console.log(removed); // 1;
|
|
1058
|
+
*
|
|
1059
|
+
* // Peek - O(1)
|
|
1060
|
+
* const top = newHeap.peek();
|
|
1061
|
+
* console.log(top); // 2;
|
|
1062
|
+
*/
|
|
599
1063
|
peek() {
|
|
600
1064
|
return this.elements[0];
|
|
601
1065
|
}
|
|
602
1066
|
/**
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
1067
|
+
* Check whether the heap is empty.
|
|
1068
|
+
* @remarks Time O(1), Space O(1)
|
|
1069
|
+
* @returns True if size is 0.
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
* @example
|
|
1101
|
+
* // Check if heap is empty
|
|
1102
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
1103
|
+
* console.log(heap.isEmpty()); // true;
|
|
1104
|
+
* heap.add(1);
|
|
1105
|
+
* console.log(heap.isEmpty()); // false;
|
|
1106
|
+
*/
|
|
607
1107
|
isEmpty() {
|
|
608
1108
|
return this.size === 0;
|
|
609
1109
|
}
|
|
610
1110
|
/**
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
1111
|
+
* Remove all elements.
|
|
1112
|
+
* @remarks Time O(1), Space O(1)
|
|
1113
|
+
* @returns void
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
* @example
|
|
1145
|
+
* // Remove all elements
|
|
1146
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1147
|
+
* heap.clear();
|
|
1148
|
+
* console.log(heap.isEmpty()); // true;
|
|
1149
|
+
*/
|
|
615
1150
|
clear() {
|
|
616
1151
|
this._elements = [];
|
|
617
1152
|
}
|
|
@@ -626,21 +1161,83 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
626
1161
|
return this.fix();
|
|
627
1162
|
}
|
|
628
1163
|
/**
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
1164
|
+
* Check if an equal element exists in the heap.
|
|
1165
|
+
* @remarks Time O(N), Space O(1)
|
|
1166
|
+
* @param element - Element to search for.
|
|
1167
|
+
* @returns True if found.
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
* @example
|
|
1192
|
+
* // Check element existence
|
|
1193
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1194
|
+
* console.log(heap.has(1)); // true;
|
|
1195
|
+
* console.log(heap.has(99)); // false;
|
|
1196
|
+
*/
|
|
634
1197
|
has(element) {
|
|
635
1198
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
636
1199
|
return false;
|
|
637
1200
|
}
|
|
638
1201
|
/**
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
1202
|
+
* Delete one occurrence of an element.
|
|
1203
|
+
* @remarks Time O(N), Space O(1)
|
|
1204
|
+
* @param element - Element to delete.
|
|
1205
|
+
* @returns True if an element was removed.
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
* @example
|
|
1236
|
+
* // Remove specific element
|
|
1237
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
1238
|
+
* heap.delete(4);
|
|
1239
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
1240
|
+
*/
|
|
644
1241
|
delete(element) {
|
|
645
1242
|
let index = -1;
|
|
646
1243
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -698,11 +1295,39 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
698
1295
|
return this;
|
|
699
1296
|
}
|
|
700
1297
|
/**
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
1298
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
1299
|
+
* @remarks Time O(N), Space O(H)
|
|
1300
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
1301
|
+
* @returns Array of visited elements.
|
|
1302
|
+
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
* @example
|
|
1326
|
+
* // Depth-first traversal
|
|
1327
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1328
|
+
* const result = heap.dfs('IN');
|
|
1329
|
+
* console.log(result.length); // 3;
|
|
1330
|
+
*/
|
|
706
1331
|
dfs(order = "PRE") {
|
|
707
1332
|
const result = [];
|
|
708
1333
|
const _dfs = /* @__PURE__ */ __name((index) => {
|
|
@@ -739,10 +1364,47 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
739
1364
|
return results;
|
|
740
1365
|
}
|
|
741
1366
|
/**
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
1367
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
1368
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1369
|
+
* @returns Sorted array of elements.
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
|
|
1374
|
+
|
|
1375
|
+
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
|
|
1382
|
+
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
|
|
1388
|
+
|
|
1389
|
+
|
|
1390
|
+
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
|
|
1401
|
+
|
|
1402
|
+
* @example
|
|
1403
|
+
* // Sort elements using heap
|
|
1404
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
1405
|
+
* const sorted = heap.sort();
|
|
1406
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
1407
|
+
*/
|
|
746
1408
|
sort() {
|
|
747
1409
|
const visited = [];
|
|
748
1410
|
const cloned = this._createInstance();
|
|
@@ -754,22 +1416,94 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
754
1416
|
return visited;
|
|
755
1417
|
}
|
|
756
1418
|
/**
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
1419
|
+
* Deep clone this heap.
|
|
1420
|
+
* @remarks Time O(N), Space O(N)
|
|
1421
|
+
* @returns A new heap with the same elements.
|
|
1422
|
+
|
|
1423
|
+
|
|
1424
|
+
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
* @example
|
|
1453
|
+
* // Create independent copy
|
|
1454
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
1455
|
+
* const copy = heap.clone();
|
|
1456
|
+
* copy.poll();
|
|
1457
|
+
* console.log(heap.size); // 3;
|
|
1458
|
+
* console.log(copy.size); // 2;
|
|
1459
|
+
*/
|
|
761
1460
|
clone() {
|
|
762
1461
|
const next = this._createInstance();
|
|
763
1462
|
for (const x of this.elements) next.add(x);
|
|
764
1463
|
return next;
|
|
765
1464
|
}
|
|
766
1465
|
/**
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
1466
|
+
* Filter elements into a new heap of the same class.
|
|
1467
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1468
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
1469
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1470
|
+
* @returns A new heap with the kept elements.
|
|
1471
|
+
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
|
|
1478
|
+
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
|
|
1482
|
+
|
|
1483
|
+
|
|
1484
|
+
|
|
1485
|
+
|
|
1486
|
+
|
|
1487
|
+
|
|
1488
|
+
|
|
1489
|
+
|
|
1490
|
+
|
|
1491
|
+
|
|
1492
|
+
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
|
|
1501
|
+
* @example
|
|
1502
|
+
* // Filter elements
|
|
1503
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
1504
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
1505
|
+
* console.log(evens.size); // 2;
|
|
1506
|
+
*/
|
|
773
1507
|
filter(callback, thisArg) {
|
|
774
1508
|
const out = this._createInstance();
|
|
775
1509
|
let i = 0;
|
|
@@ -783,15 +1517,49 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
783
1517
|
return out;
|
|
784
1518
|
}
|
|
785
1519
|
/**
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
1520
|
+
* Map elements into a new heap of possibly different element type.
|
|
1521
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1522
|
+
* @template EM
|
|
1523
|
+
* @template RM
|
|
1524
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
1525
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
1526
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1527
|
+
* @returns A new heap with mapped elements.
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
|
|
1531
|
+
|
|
1532
|
+
|
|
1533
|
+
|
|
1534
|
+
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
* @example
|
|
1558
|
+
* // Transform elements
|
|
1559
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1560
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
1561
|
+
* console.log(doubled.peek()); // 2;
|
|
1562
|
+
*/
|
|
795
1563
|
map(callback, options, thisArg) {
|
|
796
1564
|
const { comparator, toElementFn, ...rest } = options ?? {};
|
|
797
1565
|
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
@@ -904,199 +1672,6 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
904
1672
|
}
|
|
905
1673
|
};
|
|
906
1674
|
|
|
907
|
-
// src/data-structures/base/linear-base.ts
|
|
908
|
-
var LinearBase = class _LinearBase extends IterableElementBase {
|
|
909
|
-
static {
|
|
910
|
-
__name(this, "LinearBase");
|
|
911
|
-
}
|
|
912
|
-
/**
|
|
913
|
-
* Construct a linear container with runtime options.
|
|
914
|
-
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
915
|
-
* @remarks Time O(1), Space O(1)
|
|
916
|
-
*/
|
|
917
|
-
constructor(options) {
|
|
918
|
-
super(options);
|
|
919
|
-
if (options) {
|
|
920
|
-
const { maxLen } = options;
|
|
921
|
-
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
_maxLen = -1;
|
|
925
|
-
/**
|
|
926
|
-
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
927
|
-
* @returns Maximum allowed length.
|
|
928
|
-
* @remarks Time O(1), Space O(1)
|
|
929
|
-
*/
|
|
930
|
-
get maxLen() {
|
|
931
|
-
return this._maxLen;
|
|
932
|
-
}
|
|
933
|
-
/**
|
|
934
|
-
* First index of a value from the left.
|
|
935
|
-
* @param searchElement - Value to match.
|
|
936
|
-
* @param fromIndex - Start position (supports negative index).
|
|
937
|
-
* @returns Index or `-1` if not found.
|
|
938
|
-
* @remarks Time O(n), Space O(1)
|
|
939
|
-
*/
|
|
940
|
-
indexOf(searchElement, fromIndex = 0) {
|
|
941
|
-
if (this.length === 0) return -1;
|
|
942
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
943
|
-
if (fromIndex < 0) fromIndex = 0;
|
|
944
|
-
for (let i = fromIndex; i < this.length; i++) {
|
|
945
|
-
const element = this.at(i);
|
|
946
|
-
if (element === searchElement) return i;
|
|
947
|
-
}
|
|
948
|
-
return -1;
|
|
949
|
-
}
|
|
950
|
-
/**
|
|
951
|
-
* Last index of a value from the right.
|
|
952
|
-
* @param searchElement - Value to match.
|
|
953
|
-
* @param fromIndex - Start position (supports negative index).
|
|
954
|
-
* @returns Index or `-1` if not found.
|
|
955
|
-
* @remarks Time O(n), Space O(1)
|
|
956
|
-
*/
|
|
957
|
-
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
958
|
-
if (this.length === 0) return -1;
|
|
959
|
-
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
960
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
961
|
-
for (let i = fromIndex; i >= 0; i--) {
|
|
962
|
-
const element = this.at(i);
|
|
963
|
-
if (element === searchElement) return i;
|
|
964
|
-
}
|
|
965
|
-
return -1;
|
|
966
|
-
}
|
|
967
|
-
/**
|
|
968
|
-
* Find the first index matching a predicate.
|
|
969
|
-
* @param predicate - `(element, index, self) => boolean`.
|
|
970
|
-
* @param thisArg - Optional `this` for callback.
|
|
971
|
-
* @returns Index or `-1`.
|
|
972
|
-
* @remarks Time O(n), Space O(1)
|
|
973
|
-
*/
|
|
974
|
-
findIndex(predicate, thisArg) {
|
|
975
|
-
for (let i = 0; i < this.length; i++) {
|
|
976
|
-
const item = this.at(i);
|
|
977
|
-
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
978
|
-
}
|
|
979
|
-
return -1;
|
|
980
|
-
}
|
|
981
|
-
/**
|
|
982
|
-
* Concatenate elements and/or containers.
|
|
983
|
-
* @param items - Elements or other containers.
|
|
984
|
-
* @returns New container with combined elements (`this` type).
|
|
985
|
-
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
986
|
-
*/
|
|
987
|
-
concat(...items) {
|
|
988
|
-
const newList = this.clone();
|
|
989
|
-
for (const item of items) {
|
|
990
|
-
if (item instanceof _LinearBase) {
|
|
991
|
-
newList.pushMany(item);
|
|
992
|
-
} else {
|
|
993
|
-
newList.push(item);
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
return newList;
|
|
997
|
-
}
|
|
998
|
-
/**
|
|
999
|
-
* In-place stable order via array sort semantics.
|
|
1000
|
-
* @param compareFn - Comparator `(a, b) => number`.
|
|
1001
|
-
* @returns This container.
|
|
1002
|
-
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
1003
|
-
*/
|
|
1004
|
-
sort(compareFn) {
|
|
1005
|
-
const arr = this.toArray();
|
|
1006
|
-
arr.sort(compareFn);
|
|
1007
|
-
this.clear();
|
|
1008
|
-
for (const item of arr) this.push(item);
|
|
1009
|
-
return this;
|
|
1010
|
-
}
|
|
1011
|
-
/**
|
|
1012
|
-
* Remove and/or insert elements at a position (array-compatible).
|
|
1013
|
-
* @param start - Start index (supports negative index).
|
|
1014
|
-
* @param deleteCount - How many to remove.
|
|
1015
|
-
* @param items - Elements to insert.
|
|
1016
|
-
* @returns Removed elements as a new list (`this` type).
|
|
1017
|
-
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
1018
|
-
*/
|
|
1019
|
-
splice(start, deleteCount = 0, ...items) {
|
|
1020
|
-
const removedList = this._createInstance();
|
|
1021
|
-
start = start < 0 ? this.length + start : start;
|
|
1022
|
-
start = Math.max(0, Math.min(start, this.length));
|
|
1023
|
-
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
1024
|
-
for (let i = 0; i < deleteCount; i++) {
|
|
1025
|
-
const removed = this.deleteAt(start);
|
|
1026
|
-
if (removed !== void 0) {
|
|
1027
|
-
removedList.push(removed);
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
for (let i = 0; i < items.length; i++) {
|
|
1031
|
-
this.addAt(start + i, items[i]);
|
|
1032
|
-
}
|
|
1033
|
-
return removedList;
|
|
1034
|
-
}
|
|
1035
|
-
/**
|
|
1036
|
-
* Join all elements into a string.
|
|
1037
|
-
* @param separator - Separator string.
|
|
1038
|
-
* @returns Concatenated string.
|
|
1039
|
-
* @remarks Time O(n), Space O(n)
|
|
1040
|
-
*/
|
|
1041
|
-
join(separator = ",") {
|
|
1042
|
-
return this.toArray().join(separator);
|
|
1043
|
-
}
|
|
1044
|
-
/**
|
|
1045
|
-
* Snapshot elements into a reversed array.
|
|
1046
|
-
* @returns New reversed array.
|
|
1047
|
-
* @remarks Time O(n), Space O(n)
|
|
1048
|
-
*/
|
|
1049
|
-
toReversedArray() {
|
|
1050
|
-
const array = [];
|
|
1051
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1052
|
-
array.push(this.at(i));
|
|
1053
|
-
}
|
|
1054
|
-
return array;
|
|
1055
|
-
}
|
|
1056
|
-
reduceRight(callbackfn, initialValue) {
|
|
1057
|
-
let accumulator = initialValue ?? 0;
|
|
1058
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1059
|
-
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
1060
|
-
}
|
|
1061
|
-
return accumulator;
|
|
1062
|
-
}
|
|
1063
|
-
/**
|
|
1064
|
-
* Create a shallow copy of a subrange.
|
|
1065
|
-
* @param start - Inclusive start (supports negative index).
|
|
1066
|
-
* @param end - Exclusive end (supports negative index).
|
|
1067
|
-
* @returns New list with the range (`this` type).
|
|
1068
|
-
* @remarks Time O(n), Space O(n)
|
|
1069
|
-
*/
|
|
1070
|
-
slice(start = 0, end = this.length) {
|
|
1071
|
-
start = start < 0 ? this.length + start : start;
|
|
1072
|
-
end = end < 0 ? this.length + end : end;
|
|
1073
|
-
const newList = this._createInstance();
|
|
1074
|
-
for (let i = start; i < end; i++) {
|
|
1075
|
-
newList.push(this.at(i));
|
|
1076
|
-
}
|
|
1077
|
-
return newList;
|
|
1078
|
-
}
|
|
1079
|
-
/**
|
|
1080
|
-
* Fill a range with a value.
|
|
1081
|
-
* @param value - Value to set.
|
|
1082
|
-
* @param start - Inclusive start.
|
|
1083
|
-
* @param end - Exclusive end.
|
|
1084
|
-
* @returns This list.
|
|
1085
|
-
* @remarks Time O(n), Space O(1)
|
|
1086
|
-
*/
|
|
1087
|
-
fill(value, start = 0, end = this.length) {
|
|
1088
|
-
start = start < 0 ? this.length + start : start;
|
|
1089
|
-
end = end < 0 ? this.length + end : end;
|
|
1090
|
-
if (start < 0) start = 0;
|
|
1091
|
-
if (end > this.length) end = this.length;
|
|
1092
|
-
if (start >= end) return this;
|
|
1093
|
-
for (let i = start; i < end; i++) {
|
|
1094
|
-
this.setAt(i, value);
|
|
1095
|
-
}
|
|
1096
|
-
return this;
|
|
1097
|
-
}
|
|
1098
|
-
};
|
|
1099
|
-
|
|
1100
1675
|
// src/data-structures/queue/queue.ts
|
|
1101
1676
|
var Queue = class _Queue extends LinearBase {
|
|
1102
1677
|
static {
|
|
@@ -1154,18 +1729,94 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1154
1729
|
this._autoCompactRatio = value;
|
|
1155
1730
|
}
|
|
1156
1731
|
/**
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1732
|
+
* Get the number of elements currently in the queue.
|
|
1733
|
+
* @remarks Time O(1), Space O(1)
|
|
1734
|
+
* @returns Current length.
|
|
1735
|
+
|
|
1736
|
+
|
|
1737
|
+
|
|
1738
|
+
|
|
1739
|
+
|
|
1740
|
+
|
|
1741
|
+
|
|
1742
|
+
|
|
1743
|
+
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
|
|
1747
|
+
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
|
|
1758
|
+
|
|
1759
|
+
|
|
1760
|
+
|
|
1761
|
+
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
|
|
1765
|
+
|
|
1766
|
+
|
|
1767
|
+
* @example
|
|
1768
|
+
* // Track queue length
|
|
1769
|
+
* const q = new Queue<number>();
|
|
1770
|
+
* console.log(q.length); // 0;
|
|
1771
|
+
* q.push(1);
|
|
1772
|
+
* q.push(2);
|
|
1773
|
+
* console.log(q.length); // 2;
|
|
1774
|
+
*/
|
|
1161
1775
|
get length() {
|
|
1162
1776
|
return this.elements.length - this._offset;
|
|
1163
1777
|
}
|
|
1164
1778
|
/**
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1779
|
+
* Get the first element (front) without removing it.
|
|
1780
|
+
* @remarks Time O(1), Space O(1)
|
|
1781
|
+
* @returns Front element or undefined.
|
|
1782
|
+
|
|
1783
|
+
|
|
1784
|
+
|
|
1785
|
+
|
|
1786
|
+
|
|
1787
|
+
|
|
1788
|
+
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
|
|
1797
|
+
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
|
|
1801
|
+
|
|
1802
|
+
|
|
1803
|
+
|
|
1804
|
+
|
|
1805
|
+
|
|
1806
|
+
|
|
1807
|
+
|
|
1808
|
+
|
|
1809
|
+
|
|
1810
|
+
|
|
1811
|
+
|
|
1812
|
+
|
|
1813
|
+
|
|
1814
|
+
* @example
|
|
1815
|
+
* // View the front element
|
|
1816
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
1817
|
+
* console.log(q.first); // 'first';
|
|
1818
|
+
* console.log(q.length); // 3;
|
|
1819
|
+
*/
|
|
1169
1820
|
get first() {
|
|
1170
1821
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
1171
1822
|
}
|
|
@@ -1188,19 +1839,111 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1188
1839
|
return new _Queue(elements);
|
|
1189
1840
|
}
|
|
1190
1841
|
/**
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1842
|
+
* Check whether the queue is empty.
|
|
1843
|
+
* @remarks Time O(1), Space O(1)
|
|
1844
|
+
* @returns True if length is 0.
|
|
1845
|
+
|
|
1846
|
+
|
|
1847
|
+
|
|
1848
|
+
|
|
1849
|
+
|
|
1850
|
+
|
|
1851
|
+
|
|
1852
|
+
|
|
1853
|
+
|
|
1854
|
+
|
|
1855
|
+
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
|
|
1861
|
+
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
|
|
1867
|
+
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
|
|
1871
|
+
|
|
1872
|
+
|
|
1873
|
+
|
|
1874
|
+
|
|
1875
|
+
|
|
1876
|
+
|
|
1877
|
+
* @example
|
|
1878
|
+
* // Queue for...of iteration and isEmpty check
|
|
1879
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
1880
|
+
*
|
|
1881
|
+
* const elements: string[] = [];
|
|
1882
|
+
* for (const item of queue) {
|
|
1883
|
+
* elements.push(item);
|
|
1884
|
+
* }
|
|
1885
|
+
*
|
|
1886
|
+
* // Verify all elements are iterated in order
|
|
1887
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
1888
|
+
*
|
|
1889
|
+
* // Process all elements
|
|
1890
|
+
* while (queue.length > 0) {
|
|
1891
|
+
* queue.shift();
|
|
1892
|
+
* }
|
|
1893
|
+
*
|
|
1894
|
+
* console.log(queue.length); // 0;
|
|
1895
|
+
*/
|
|
1195
1896
|
isEmpty() {
|
|
1196
1897
|
return this.length === 0;
|
|
1197
1898
|
}
|
|
1198
1899
|
/**
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1900
|
+
* Enqueue one element at the back.
|
|
1901
|
+
* @remarks Time O(1), Space O(1)
|
|
1902
|
+
* @param element - Element to enqueue.
|
|
1903
|
+
* @returns True on success.
|
|
1904
|
+
|
|
1905
|
+
|
|
1906
|
+
|
|
1907
|
+
|
|
1908
|
+
|
|
1909
|
+
|
|
1910
|
+
|
|
1911
|
+
|
|
1912
|
+
|
|
1913
|
+
|
|
1914
|
+
|
|
1915
|
+
|
|
1916
|
+
|
|
1917
|
+
|
|
1918
|
+
|
|
1919
|
+
|
|
1920
|
+
|
|
1921
|
+
|
|
1922
|
+
|
|
1923
|
+
|
|
1924
|
+
|
|
1925
|
+
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
|
|
1933
|
+
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
* @example
|
|
1937
|
+
* // basic Queue creation and push operation
|
|
1938
|
+
* // Create a simple Queue with initial values
|
|
1939
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
1940
|
+
*
|
|
1941
|
+
* // Verify the queue maintains insertion order
|
|
1942
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
1943
|
+
*
|
|
1944
|
+
* // Check length
|
|
1945
|
+
* console.log(queue.length); // 5;
|
|
1946
|
+
*/
|
|
1204
1947
|
push(element) {
|
|
1205
1948
|
this.elements.push(element);
|
|
1206
1949
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -1221,10 +1964,56 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1221
1964
|
return ans;
|
|
1222
1965
|
}
|
|
1223
1966
|
/**
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1967
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1968
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1969
|
+
* @returns Removed element or undefined.
|
|
1970
|
+
|
|
1971
|
+
|
|
1972
|
+
|
|
1973
|
+
|
|
1974
|
+
|
|
1975
|
+
|
|
1976
|
+
|
|
1977
|
+
|
|
1978
|
+
|
|
1979
|
+
|
|
1980
|
+
|
|
1981
|
+
|
|
1982
|
+
|
|
1983
|
+
|
|
1984
|
+
|
|
1985
|
+
|
|
1986
|
+
|
|
1987
|
+
|
|
1988
|
+
|
|
1989
|
+
|
|
1990
|
+
|
|
1991
|
+
|
|
1992
|
+
|
|
1993
|
+
|
|
1994
|
+
|
|
1995
|
+
|
|
1996
|
+
|
|
1997
|
+
|
|
1998
|
+
|
|
1999
|
+
|
|
2000
|
+
|
|
2001
|
+
|
|
2002
|
+
* @example
|
|
2003
|
+
* // Queue shift and peek operations
|
|
2004
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
2005
|
+
*
|
|
2006
|
+
* // Peek at the front element without removing it
|
|
2007
|
+
* console.log(queue.first); // 10;
|
|
2008
|
+
*
|
|
2009
|
+
* // Remove and get the first element (FIFO)
|
|
2010
|
+
* const first = queue.shift();
|
|
2011
|
+
* console.log(first); // 10;
|
|
2012
|
+
*
|
|
2013
|
+
* // Verify remaining elements and length decreased
|
|
2014
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
2015
|
+
* console.log(queue.length); // 3;
|
|
2016
|
+
*/
|
|
1228
2017
|
shift() {
|
|
1229
2018
|
if (this.length === 0) return void 0;
|
|
1230
2019
|
const first = this.first;
|
|
@@ -1233,11 +2022,45 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1233
2022
|
return first;
|
|
1234
2023
|
}
|
|
1235
2024
|
/**
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
2025
|
+
* Delete the first occurrence of a specific element.
|
|
2026
|
+
* @remarks Time O(N), Space O(1)
|
|
2027
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
2028
|
+
* @returns True if an element was removed.
|
|
2029
|
+
|
|
2030
|
+
|
|
2031
|
+
|
|
2032
|
+
|
|
2033
|
+
|
|
2034
|
+
|
|
2035
|
+
|
|
2036
|
+
|
|
2037
|
+
|
|
2038
|
+
|
|
2039
|
+
|
|
2040
|
+
|
|
2041
|
+
|
|
2042
|
+
|
|
2043
|
+
|
|
2044
|
+
|
|
2045
|
+
|
|
2046
|
+
|
|
2047
|
+
|
|
2048
|
+
|
|
2049
|
+
|
|
2050
|
+
|
|
2051
|
+
|
|
2052
|
+
|
|
2053
|
+
|
|
2054
|
+
|
|
2055
|
+
|
|
2056
|
+
|
|
2057
|
+
|
|
2058
|
+
* @example
|
|
2059
|
+
* // Remove specific element
|
|
2060
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
2061
|
+
* q.delete(2);
|
|
2062
|
+
* console.log(q.length); // 3;
|
|
2063
|
+
*/
|
|
1241
2064
|
delete(element) {
|
|
1242
2065
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
1243
2066
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -1248,11 +2071,45 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1248
2071
|
return false;
|
|
1249
2072
|
}
|
|
1250
2073
|
/**
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
2074
|
+
* Get the element at a given logical index.
|
|
2075
|
+
* @remarks Time O(1), Space O(1)
|
|
2076
|
+
* @param index - Zero-based index from the front.
|
|
2077
|
+
* @returns Element or undefined.
|
|
2078
|
+
|
|
2079
|
+
|
|
2080
|
+
|
|
2081
|
+
|
|
2082
|
+
|
|
2083
|
+
|
|
2084
|
+
|
|
2085
|
+
|
|
2086
|
+
|
|
2087
|
+
|
|
2088
|
+
|
|
2089
|
+
|
|
2090
|
+
|
|
2091
|
+
|
|
2092
|
+
|
|
2093
|
+
|
|
2094
|
+
|
|
2095
|
+
|
|
2096
|
+
|
|
2097
|
+
|
|
2098
|
+
|
|
2099
|
+
|
|
2100
|
+
|
|
2101
|
+
|
|
2102
|
+
|
|
2103
|
+
|
|
2104
|
+
|
|
2105
|
+
|
|
2106
|
+
|
|
2107
|
+
* @example
|
|
2108
|
+
* // Access element by index
|
|
2109
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
2110
|
+
* console.log(q.at(0)); // 'a';
|
|
2111
|
+
* console.log(q.at(2)); // 'c';
|
|
2112
|
+
*/
|
|
1256
2113
|
at(index) {
|
|
1257
2114
|
if (index < 0 || index >= this.length) return void 0;
|
|
1258
2115
|
return this._elements[this._offset + index];
|
|
@@ -1304,19 +2161,90 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1304
2161
|
return this;
|
|
1305
2162
|
}
|
|
1306
2163
|
/**
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
2164
|
+
* Remove all elements and reset offset.
|
|
2165
|
+
* @remarks Time O(1), Space O(1)
|
|
2166
|
+
* @returns void
|
|
2167
|
+
|
|
2168
|
+
|
|
2169
|
+
|
|
2170
|
+
|
|
2171
|
+
|
|
2172
|
+
|
|
2173
|
+
|
|
2174
|
+
|
|
2175
|
+
|
|
2176
|
+
|
|
2177
|
+
|
|
2178
|
+
|
|
2179
|
+
|
|
2180
|
+
|
|
2181
|
+
|
|
2182
|
+
|
|
2183
|
+
|
|
2184
|
+
|
|
2185
|
+
|
|
2186
|
+
|
|
2187
|
+
|
|
2188
|
+
|
|
2189
|
+
|
|
2190
|
+
|
|
2191
|
+
|
|
2192
|
+
|
|
2193
|
+
|
|
2194
|
+
|
|
2195
|
+
|
|
2196
|
+
|
|
2197
|
+
* @example
|
|
2198
|
+
* // Remove all elements
|
|
2199
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2200
|
+
* q.clear();
|
|
2201
|
+
* console.log(q.length); // 0;
|
|
2202
|
+
*/
|
|
1311
2203
|
clear() {
|
|
1312
2204
|
this._elements = [];
|
|
1313
2205
|
this._offset = 0;
|
|
1314
2206
|
}
|
|
1315
2207
|
/**
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
2208
|
+
* Compact storage by discarding consumed head elements.
|
|
2209
|
+
* @remarks Time O(N), Space O(N)
|
|
2210
|
+
* @returns True when compaction performed.
|
|
2211
|
+
|
|
2212
|
+
|
|
2213
|
+
|
|
2214
|
+
|
|
2215
|
+
|
|
2216
|
+
|
|
2217
|
+
|
|
2218
|
+
|
|
2219
|
+
|
|
2220
|
+
|
|
2221
|
+
|
|
2222
|
+
|
|
2223
|
+
|
|
2224
|
+
|
|
2225
|
+
|
|
2226
|
+
|
|
2227
|
+
|
|
2228
|
+
|
|
2229
|
+
|
|
2230
|
+
|
|
2231
|
+
|
|
2232
|
+
|
|
2233
|
+
|
|
2234
|
+
|
|
2235
|
+
|
|
2236
|
+
|
|
2237
|
+
|
|
2238
|
+
|
|
2239
|
+
|
|
2240
|
+
* @example
|
|
2241
|
+
* // Reclaim unused memory
|
|
2242
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2243
|
+
* q.shift();
|
|
2244
|
+
* q.shift();
|
|
2245
|
+
* q.compact();
|
|
2246
|
+
* console.log(q.length); // 3;
|
|
2247
|
+
*/
|
|
1320
2248
|
compact() {
|
|
1321
2249
|
this._elements = this.elements.slice(this._offset);
|
|
1322
2250
|
this._offset = 0;
|
|
@@ -1342,10 +2270,47 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1342
2270
|
return removed;
|
|
1343
2271
|
}
|
|
1344
2272
|
/**
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
2273
|
+
* Deep clone this queue and its parameters.
|
|
2274
|
+
* @remarks Time O(N), Space O(N)
|
|
2275
|
+
* @returns A new queue with the same content and options.
|
|
2276
|
+
|
|
2277
|
+
|
|
2278
|
+
|
|
2279
|
+
|
|
2280
|
+
|
|
2281
|
+
|
|
2282
|
+
|
|
2283
|
+
|
|
2284
|
+
|
|
2285
|
+
|
|
2286
|
+
|
|
2287
|
+
|
|
2288
|
+
|
|
2289
|
+
|
|
2290
|
+
|
|
2291
|
+
|
|
2292
|
+
|
|
2293
|
+
|
|
2294
|
+
|
|
2295
|
+
|
|
2296
|
+
|
|
2297
|
+
|
|
2298
|
+
|
|
2299
|
+
|
|
2300
|
+
|
|
2301
|
+
|
|
2302
|
+
|
|
2303
|
+
|
|
2304
|
+
|
|
2305
|
+
|
|
2306
|
+
* @example
|
|
2307
|
+
* // Create independent copy
|
|
2308
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2309
|
+
* const copy = q.clone();
|
|
2310
|
+
* copy.shift();
|
|
2311
|
+
* console.log(q.length); // 3;
|
|
2312
|
+
* console.log(copy.length); // 2;
|
|
2313
|
+
*/
|
|
1349
2314
|
clone() {
|
|
1350
2315
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1351
2316
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1353,12 +2318,47 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1353
2318
|
return out;
|
|
1354
2319
|
}
|
|
1355
2320
|
/**
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
2321
|
+
* Filter elements into a new queue of the same class.
|
|
2322
|
+
* @remarks Time O(N), Space O(N)
|
|
2323
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
2324
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
2325
|
+
* @returns A new queue with kept elements.
|
|
2326
|
+
|
|
2327
|
+
|
|
2328
|
+
|
|
2329
|
+
|
|
2330
|
+
|
|
2331
|
+
|
|
2332
|
+
|
|
2333
|
+
|
|
2334
|
+
|
|
2335
|
+
|
|
2336
|
+
|
|
2337
|
+
|
|
2338
|
+
|
|
2339
|
+
|
|
2340
|
+
|
|
2341
|
+
|
|
2342
|
+
|
|
2343
|
+
|
|
2344
|
+
|
|
2345
|
+
|
|
2346
|
+
|
|
2347
|
+
|
|
2348
|
+
|
|
2349
|
+
|
|
2350
|
+
|
|
2351
|
+
|
|
2352
|
+
|
|
2353
|
+
|
|
2354
|
+
|
|
2355
|
+
|
|
2356
|
+
* @example
|
|
2357
|
+
* // Filter elements
|
|
2358
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2359
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
2360
|
+
* console.log(evens.length); // 2;
|
|
2361
|
+
*/
|
|
1362
2362
|
filter(predicate, thisArg) {
|
|
1363
2363
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1364
2364
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1370,15 +2370,49 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1370
2370
|
return out;
|
|
1371
2371
|
}
|
|
1372
2372
|
/**
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
2373
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
2374
|
+
* @remarks Time O(N), Space O(N)
|
|
2375
|
+
* @template EM
|
|
2376
|
+
* @template RM
|
|
2377
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
2378
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
2379
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
2380
|
+
* @returns A new Queue with mapped elements.
|
|
2381
|
+
|
|
2382
|
+
|
|
2383
|
+
|
|
2384
|
+
|
|
2385
|
+
|
|
2386
|
+
|
|
2387
|
+
|
|
2388
|
+
|
|
2389
|
+
|
|
2390
|
+
|
|
2391
|
+
|
|
2392
|
+
|
|
2393
|
+
|
|
2394
|
+
|
|
2395
|
+
|
|
2396
|
+
|
|
2397
|
+
|
|
2398
|
+
|
|
2399
|
+
|
|
2400
|
+
|
|
2401
|
+
|
|
2402
|
+
|
|
2403
|
+
|
|
2404
|
+
|
|
2405
|
+
|
|
2406
|
+
|
|
2407
|
+
|
|
2408
|
+
|
|
2409
|
+
|
|
2410
|
+
* @example
|
|
2411
|
+
* // Transform elements
|
|
2412
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2413
|
+
* const doubled = q.map(x => x * 2);
|
|
2414
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
2415
|
+
*/
|
|
1382
2416
|
map(callback, options, thisArg) {
|
|
1383
2417
|
const out = new this.constructor([], {
|
|
1384
2418
|
toElementFn: options?.toElementFn,
|
|
@@ -2475,12 +3509,49 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2475
3509
|
return new DirectedEdge(src, dest, weight ?? this.options.defaultEdgeWeight ?? 1, value);
|
|
2476
3510
|
}
|
|
2477
3511
|
/**
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
3512
|
+
* Get the unique edge from `src` to `dest`, if present.
|
|
3513
|
+
* @param srcOrKey - Source vertex or key.
|
|
3514
|
+
* @param destOrKey - Destination vertex or key.
|
|
3515
|
+
* @returns Edge instance or `undefined`.
|
|
3516
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3517
|
+
|
|
3518
|
+
|
|
3519
|
+
|
|
3520
|
+
|
|
3521
|
+
|
|
3522
|
+
|
|
3523
|
+
|
|
3524
|
+
|
|
3525
|
+
|
|
3526
|
+
|
|
3527
|
+
|
|
3528
|
+
|
|
3529
|
+
|
|
3530
|
+
|
|
3531
|
+
|
|
3532
|
+
|
|
3533
|
+
|
|
3534
|
+
|
|
3535
|
+
|
|
3536
|
+
|
|
3537
|
+
|
|
3538
|
+
|
|
3539
|
+
|
|
3540
|
+
|
|
3541
|
+
|
|
3542
|
+
|
|
3543
|
+
|
|
3544
|
+
|
|
3545
|
+
|
|
3546
|
+
* @example
|
|
3547
|
+
* // Get edge between vertices
|
|
3548
|
+
* const g = new DirectedGraph();
|
|
3549
|
+
* g.addVertex('A');
|
|
3550
|
+
* g.addVertex('B');
|
|
3551
|
+
* g.addEdge('A', 'B', 5);
|
|
3552
|
+
* const edge = g.getEdge('A', 'B');
|
|
3553
|
+
* console.log(edge?.weight); // 5;
|
|
3554
|
+
*/
|
|
2484
3555
|
getEdge(srcOrKey, destOrKey) {
|
|
2485
3556
|
let edgeMap = [];
|
|
2486
3557
|
if (srcOrKey !== void 0 && destOrKey !== void 0) {
|
|
@@ -2520,12 +3591,69 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2520
3591
|
return removed;
|
|
2521
3592
|
}
|
|
2522
3593
|
/**
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
3594
|
+
* Delete an edge by instance or by `(srcKey, destKey)`.
|
|
3595
|
+
* @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
|
|
3596
|
+
* @param destVertexKey - Optional destination vertex/key when deleting by pair.
|
|
3597
|
+
* @returns Removed edge or `undefined`.
|
|
3598
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3599
|
+
|
|
3600
|
+
|
|
3601
|
+
|
|
3602
|
+
|
|
3603
|
+
|
|
3604
|
+
|
|
3605
|
+
|
|
3606
|
+
|
|
3607
|
+
|
|
3608
|
+
|
|
3609
|
+
|
|
3610
|
+
|
|
3611
|
+
|
|
3612
|
+
|
|
3613
|
+
|
|
3614
|
+
|
|
3615
|
+
|
|
3616
|
+
|
|
3617
|
+
|
|
3618
|
+
|
|
3619
|
+
|
|
3620
|
+
|
|
3621
|
+
|
|
3622
|
+
|
|
3623
|
+
|
|
3624
|
+
|
|
3625
|
+
|
|
3626
|
+
|
|
3627
|
+
|
|
3628
|
+
|
|
3629
|
+
|
|
3630
|
+
|
|
3631
|
+
* @example
|
|
3632
|
+
* // DirectedGraph deleteEdge and vertex operations
|
|
3633
|
+
* const graph = new DirectedGraph<string>();
|
|
3634
|
+
*
|
|
3635
|
+
* // Build a small graph
|
|
3636
|
+
* graph.addVertex('X');
|
|
3637
|
+
* graph.addVertex('Y');
|
|
3638
|
+
* graph.addVertex('Z');
|
|
3639
|
+
* graph.addEdge('X', 'Y', 1);
|
|
3640
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
3641
|
+
*
|
|
3642
|
+
* // Delete an edge
|
|
3643
|
+
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
3644
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
3645
|
+
*
|
|
3646
|
+
* // Edge in other direction should not exist
|
|
3647
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
3648
|
+
*
|
|
3649
|
+
* // Other edges should remain
|
|
3650
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
3651
|
+
*
|
|
3652
|
+
* // Delete a vertex
|
|
3653
|
+
* graph.deleteVertex('Y');
|
|
3654
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
3655
|
+
* console.log(graph.size); // 2;
|
|
3656
|
+
*/
|
|
2529
3657
|
deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
|
|
2530
3658
|
let removed = void 0;
|
|
2531
3659
|
let src, dest;
|
|
@@ -2552,6 +3680,47 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2552
3680
|
}
|
|
2553
3681
|
return removed;
|
|
2554
3682
|
}
|
|
3683
|
+
/**
|
|
3684
|
+
* Remove a vertex
|
|
3685
|
+
|
|
3686
|
+
|
|
3687
|
+
|
|
3688
|
+
|
|
3689
|
+
|
|
3690
|
+
|
|
3691
|
+
|
|
3692
|
+
|
|
3693
|
+
|
|
3694
|
+
|
|
3695
|
+
|
|
3696
|
+
|
|
3697
|
+
|
|
3698
|
+
|
|
3699
|
+
|
|
3700
|
+
|
|
3701
|
+
|
|
3702
|
+
|
|
3703
|
+
|
|
3704
|
+
|
|
3705
|
+
|
|
3706
|
+
|
|
3707
|
+
|
|
3708
|
+
|
|
3709
|
+
|
|
3710
|
+
|
|
3711
|
+
|
|
3712
|
+
|
|
3713
|
+
|
|
3714
|
+
* @example
|
|
3715
|
+
* // Remove a vertex
|
|
3716
|
+
* const g = new DirectedGraph();
|
|
3717
|
+
* g.addVertex('A');
|
|
3718
|
+
* g.addVertex('B');
|
|
3719
|
+
* g.addEdge('A', 'B');
|
|
3720
|
+
* g.deleteVertex('A');
|
|
3721
|
+
* console.log(g.hasVertex('A')); // false;
|
|
3722
|
+
* console.log(g.hasEdge('A', 'B')); // false;
|
|
3723
|
+
*/
|
|
2555
3724
|
deleteVertex(vertexOrKey) {
|
|
2556
3725
|
let vertexKey;
|
|
2557
3726
|
let vertex;
|
|
@@ -2583,11 +3752,49 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2583
3752
|
return removed;
|
|
2584
3753
|
}
|
|
2585
3754
|
/**
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
3755
|
+
* Incoming edges of a vertex.
|
|
3756
|
+
* @param vertexOrKey - Vertex or key.
|
|
3757
|
+
* @returns Array of incoming edges.
|
|
3758
|
+
* @remarks Time O(deg_in), Space O(deg_in)
|
|
3759
|
+
|
|
3760
|
+
|
|
3761
|
+
|
|
3762
|
+
|
|
3763
|
+
|
|
3764
|
+
|
|
3765
|
+
|
|
3766
|
+
|
|
3767
|
+
|
|
3768
|
+
|
|
3769
|
+
|
|
3770
|
+
|
|
3771
|
+
|
|
3772
|
+
|
|
3773
|
+
|
|
3774
|
+
|
|
3775
|
+
|
|
3776
|
+
|
|
3777
|
+
|
|
3778
|
+
|
|
3779
|
+
|
|
3780
|
+
|
|
3781
|
+
|
|
3782
|
+
|
|
3783
|
+
|
|
3784
|
+
|
|
3785
|
+
|
|
3786
|
+
|
|
3787
|
+
|
|
3788
|
+
* @example
|
|
3789
|
+
* // Get incoming edges
|
|
3790
|
+
* const g = new DirectedGraph();
|
|
3791
|
+
* g.addVertex('A');
|
|
3792
|
+
* g.addVertex('B');
|
|
3793
|
+
* g.addVertex('C');
|
|
3794
|
+
* g.addEdge('A', 'C');
|
|
3795
|
+
* g.addEdge('B', 'C');
|
|
3796
|
+
* console.log(g.incomingEdgesOf('C').length); // 2;
|
|
3797
|
+
*/
|
|
2591
3798
|
incomingEdgesOf(vertexOrKey) {
|
|
2592
3799
|
const target = this._getVertex(vertexOrKey);
|
|
2593
3800
|
if (target) {
|
|
@@ -2596,11 +3803,49 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2596
3803
|
return [];
|
|
2597
3804
|
}
|
|
2598
3805
|
/**
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
3806
|
+
* Outgoing edges of a vertex.
|
|
3807
|
+
* @param vertexOrKey - Vertex or key.
|
|
3808
|
+
* @returns Array of outgoing edges.
|
|
3809
|
+
* @remarks Time O(deg_out), Space O(deg_out)
|
|
3810
|
+
|
|
3811
|
+
|
|
3812
|
+
|
|
3813
|
+
|
|
3814
|
+
|
|
3815
|
+
|
|
3816
|
+
|
|
3817
|
+
|
|
3818
|
+
|
|
3819
|
+
|
|
3820
|
+
|
|
3821
|
+
|
|
3822
|
+
|
|
3823
|
+
|
|
3824
|
+
|
|
3825
|
+
|
|
3826
|
+
|
|
3827
|
+
|
|
3828
|
+
|
|
3829
|
+
|
|
3830
|
+
|
|
3831
|
+
|
|
3832
|
+
|
|
3833
|
+
|
|
3834
|
+
|
|
3835
|
+
|
|
3836
|
+
|
|
3837
|
+
|
|
3838
|
+
|
|
3839
|
+
* @example
|
|
3840
|
+
* // Get outgoing edges
|
|
3841
|
+
* const g = new DirectedGraph();
|
|
3842
|
+
* g.addVertex('A');
|
|
3843
|
+
* g.addVertex('B');
|
|
3844
|
+
* g.addVertex('C');
|
|
3845
|
+
* g.addEdge('A', 'B');
|
|
3846
|
+
* g.addEdge('A', 'C');
|
|
3847
|
+
* console.log(g.outgoingEdgesOf('A').length); // 2;
|
|
3848
|
+
*/
|
|
2604
3849
|
outgoingEdgesOf(vertexOrKey) {
|
|
2605
3850
|
const target = this._getVertex(vertexOrKey);
|
|
2606
3851
|
if (target) {
|
|
@@ -2659,11 +3904,65 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2659
3904
|
return destinations;
|
|
2660
3905
|
}
|
|
2661
3906
|
/**
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
3907
|
+
* Topological sort if DAG; returns `undefined` if a cycle exists.
|
|
3908
|
+
* @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
|
|
3909
|
+
* @returns Array of keys/vertices, or `undefined` when cycle is found.
|
|
3910
|
+
* @remarks Time O(V + E), Space O(V)
|
|
3911
|
+
|
|
3912
|
+
|
|
3913
|
+
|
|
3914
|
+
|
|
3915
|
+
|
|
3916
|
+
|
|
3917
|
+
|
|
3918
|
+
|
|
3919
|
+
|
|
3920
|
+
|
|
3921
|
+
|
|
3922
|
+
|
|
3923
|
+
|
|
3924
|
+
|
|
3925
|
+
|
|
3926
|
+
|
|
3927
|
+
|
|
3928
|
+
|
|
3929
|
+
|
|
3930
|
+
|
|
3931
|
+
|
|
3932
|
+
|
|
3933
|
+
|
|
3934
|
+
|
|
3935
|
+
|
|
3936
|
+
|
|
3937
|
+
|
|
3938
|
+
|
|
3939
|
+
|
|
3940
|
+
|
|
3941
|
+
|
|
3942
|
+
|
|
3943
|
+
* @example
|
|
3944
|
+
* // DirectedGraph topologicalSort for task scheduling
|
|
3945
|
+
* const graph = new DirectedGraph<string>();
|
|
3946
|
+
*
|
|
3947
|
+
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
3948
|
+
* graph.addVertex('Design');
|
|
3949
|
+
* graph.addVertex('Implement');
|
|
3950
|
+
* graph.addVertex('Test');
|
|
3951
|
+
* graph.addVertex('Deploy');
|
|
3952
|
+
*
|
|
3953
|
+
* // Add dependency edges
|
|
3954
|
+
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
3955
|
+
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
3956
|
+
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
3957
|
+
*
|
|
3958
|
+
* // Topological sort gives valid execution order
|
|
3959
|
+
* const executionOrder = graph.topologicalSort();
|
|
3960
|
+
* console.log(executionOrder); // defined;
|
|
3961
|
+
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
3962
|
+
*
|
|
3963
|
+
* // All vertices should be included
|
|
3964
|
+
* console.log(executionOrder?.length); // 4;
|
|
3965
|
+
*/
|
|
2667
3966
|
topologicalSort(propertyName) {
|
|
2668
3967
|
propertyName = propertyName ?? "key";
|
|
2669
3968
|
const statusMap = /* @__PURE__ */ new Map();
|
|
@@ -2695,6 +3994,45 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2695
3994
|
if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
|
|
2696
3995
|
return sorted.reverse();
|
|
2697
3996
|
}
|
|
3997
|
+
/**
|
|
3998
|
+
* Get all edges
|
|
3999
|
+
|
|
4000
|
+
|
|
4001
|
+
|
|
4002
|
+
|
|
4003
|
+
|
|
4004
|
+
|
|
4005
|
+
|
|
4006
|
+
|
|
4007
|
+
|
|
4008
|
+
|
|
4009
|
+
|
|
4010
|
+
|
|
4011
|
+
|
|
4012
|
+
|
|
4013
|
+
|
|
4014
|
+
|
|
4015
|
+
|
|
4016
|
+
|
|
4017
|
+
|
|
4018
|
+
|
|
4019
|
+
|
|
4020
|
+
|
|
4021
|
+
|
|
4022
|
+
|
|
4023
|
+
|
|
4024
|
+
|
|
4025
|
+
|
|
4026
|
+
|
|
4027
|
+
|
|
4028
|
+
* @example
|
|
4029
|
+
* // Get all edges
|
|
4030
|
+
* const g = new DirectedGraph();
|
|
4031
|
+
* g.addVertex('A');
|
|
4032
|
+
* g.addVertex('B');
|
|
4033
|
+
* g.addEdge('A', 'B', 3);
|
|
4034
|
+
* console.log(g.edgeSet().length); // 1;
|
|
4035
|
+
*/
|
|
2698
4036
|
edgeSet() {
|
|
2699
4037
|
let edgeMap = [];
|
|
2700
4038
|
this._outEdgeMap.forEach((outEdges) => {
|
|
@@ -2702,6 +4040,49 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2702
4040
|
});
|
|
2703
4041
|
return edgeMap;
|
|
2704
4042
|
}
|
|
4043
|
+
/**
|
|
4044
|
+
* Get outgoing neighbors
|
|
4045
|
+
|
|
4046
|
+
|
|
4047
|
+
|
|
4048
|
+
|
|
4049
|
+
|
|
4050
|
+
|
|
4051
|
+
|
|
4052
|
+
|
|
4053
|
+
|
|
4054
|
+
|
|
4055
|
+
|
|
4056
|
+
|
|
4057
|
+
|
|
4058
|
+
|
|
4059
|
+
|
|
4060
|
+
|
|
4061
|
+
|
|
4062
|
+
|
|
4063
|
+
|
|
4064
|
+
|
|
4065
|
+
|
|
4066
|
+
|
|
4067
|
+
|
|
4068
|
+
|
|
4069
|
+
|
|
4070
|
+
|
|
4071
|
+
|
|
4072
|
+
|
|
4073
|
+
|
|
4074
|
+
|
|
4075
|
+
* @example
|
|
4076
|
+
* // Get outgoing neighbors
|
|
4077
|
+
* const g = new DirectedGraph();
|
|
4078
|
+
* g.addVertex('A');
|
|
4079
|
+
* g.addVertex('B');
|
|
4080
|
+
* g.addVertex('C');
|
|
4081
|
+
* g.addEdge('A', 'B');
|
|
4082
|
+
* g.addEdge('A', 'C');
|
|
4083
|
+
* const neighbors = g.getNeighbors('A');
|
|
4084
|
+
* console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
|
|
4085
|
+
*/
|
|
2705
4086
|
getNeighbors(vertexOrKey) {
|
|
2706
4087
|
const neighbors = [];
|
|
2707
4088
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -2759,10 +4140,52 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2759
4140
|
return super.clone();
|
|
2760
4141
|
}
|
|
2761
4142
|
/**
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
4143
|
+
* Tarjan's algorithm for strongly connected components.
|
|
4144
|
+
* @returns `{ dfnMap, lowMap, SCCs }`.
|
|
4145
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
4146
|
+
|
|
4147
|
+
|
|
4148
|
+
|
|
4149
|
+
|
|
4150
|
+
|
|
4151
|
+
|
|
4152
|
+
|
|
4153
|
+
|
|
4154
|
+
|
|
4155
|
+
|
|
4156
|
+
|
|
4157
|
+
|
|
4158
|
+
|
|
4159
|
+
|
|
4160
|
+
|
|
4161
|
+
|
|
4162
|
+
|
|
4163
|
+
|
|
4164
|
+
|
|
4165
|
+
|
|
4166
|
+
|
|
4167
|
+
|
|
4168
|
+
|
|
4169
|
+
|
|
4170
|
+
|
|
4171
|
+
|
|
4172
|
+
|
|
4173
|
+
|
|
4174
|
+
|
|
4175
|
+
* @example
|
|
4176
|
+
* // Find strongly connected components
|
|
4177
|
+
* const g = new DirectedGraph();
|
|
4178
|
+
* g.addVertex('A');
|
|
4179
|
+
* g.addVertex('B');
|
|
4180
|
+
* g.addVertex('C');
|
|
4181
|
+
* g.addEdge('A', 'B');
|
|
4182
|
+
* g.addEdge('B', 'C');
|
|
4183
|
+
* g.addEdge('C', 'A');
|
|
4184
|
+
* const { SCCs } = g.tarjan();
|
|
4185
|
+
* // A→B→C→A forms one SCC with 3 members
|
|
4186
|
+
* const sccArrays = [...SCCs.values()];
|
|
4187
|
+
* console.log(sccArrays.some(scc => scc.length === 3)); // true;
|
|
4188
|
+
*/
|
|
2766
4189
|
tarjan() {
|
|
2767
4190
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
2768
4191
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -2820,10 +4243,50 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2820
4243
|
return this.tarjan().lowMap;
|
|
2821
4244
|
}
|
|
2822
4245
|
/**
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
4246
|
+
* Strongly connected components computed by `tarjan()`.
|
|
4247
|
+
* @returns Map from SCC id to vertices.
|
|
4248
|
+
* @remarks Time O(#SCC + V), Space O(V)
|
|
4249
|
+
|
|
4250
|
+
|
|
4251
|
+
|
|
4252
|
+
|
|
4253
|
+
|
|
4254
|
+
|
|
4255
|
+
|
|
4256
|
+
|
|
4257
|
+
|
|
4258
|
+
|
|
4259
|
+
|
|
4260
|
+
|
|
4261
|
+
|
|
4262
|
+
|
|
4263
|
+
|
|
4264
|
+
|
|
4265
|
+
|
|
4266
|
+
|
|
4267
|
+
|
|
4268
|
+
|
|
4269
|
+
|
|
4270
|
+
|
|
4271
|
+
|
|
4272
|
+
|
|
4273
|
+
|
|
4274
|
+
|
|
4275
|
+
|
|
4276
|
+
|
|
4277
|
+
|
|
4278
|
+
* @example
|
|
4279
|
+
* // Get strongly connected components
|
|
4280
|
+
* const g = new DirectedGraph();
|
|
4281
|
+
* g.addVertex(1);
|
|
4282
|
+
* g.addVertex(2);
|
|
4283
|
+
* g.addVertex(3);
|
|
4284
|
+
* g.addEdge(1, 2);
|
|
4285
|
+
* g.addEdge(2, 3);
|
|
4286
|
+
* g.addEdge(3, 1);
|
|
4287
|
+
* const sccs = g.getSCCs(); // Map<number, VO[]>
|
|
4288
|
+
* console.log(sccs.size); // >= 1;
|
|
4289
|
+
*/
|
|
2827
4290
|
getSCCs() {
|
|
2828
4291
|
return this.tarjan().SCCs;
|
|
2829
4292
|
}
|