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/dist/cjs/index.cjs +2250 -394
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +2249 -393
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +2250 -394
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +2249 -393
- 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/graph-typed.js +2247 -391
- package/dist/umd/graph-typed.js.map +1 -1
- package/dist/umd/graph-typed.min.js +3 -3
- package/dist/umd/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/umd/graph-typed.js
CHANGED
|
@@ -308,7 +308,7 @@ var graphTyped = (() => {
|
|
|
308
308
|
if (options) {
|
|
309
309
|
const { toElementFn } = options;
|
|
310
310
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
311
|
-
else if (toElementFn) throw new TypeError(
|
|
311
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
312
312
|
}
|
|
313
313
|
}
|
|
314
314
|
/**
|
|
@@ -464,7 +464,7 @@ var graphTyped = (() => {
|
|
|
464
464
|
acc = initialValue;
|
|
465
465
|
} else {
|
|
466
466
|
const first = iter.next();
|
|
467
|
-
if (first.done) throw new TypeError(
|
|
467
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
468
468
|
acc = first.value;
|
|
469
469
|
index = 1;
|
|
470
470
|
}
|
|
@@ -506,6 +506,196 @@ var graphTyped = (() => {
|
|
|
506
506
|
}
|
|
507
507
|
};
|
|
508
508
|
|
|
509
|
+
// src/data-structures/base/linear-base.ts
|
|
510
|
+
var LinearBase = class _LinearBase extends IterableElementBase {
|
|
511
|
+
/**
|
|
512
|
+
* Construct a linear container with runtime options.
|
|
513
|
+
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
514
|
+
* @remarks Time O(1), Space O(1)
|
|
515
|
+
*/
|
|
516
|
+
constructor(options) {
|
|
517
|
+
super(options);
|
|
518
|
+
__publicField(this, "_maxLen", -1);
|
|
519
|
+
if (options) {
|
|
520
|
+
const { maxLen } = options;
|
|
521
|
+
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
526
|
+
* @returns Maximum allowed length.
|
|
527
|
+
* @remarks Time O(1), Space O(1)
|
|
528
|
+
*/
|
|
529
|
+
get maxLen() {
|
|
530
|
+
return this._maxLen;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* First index of a value from the left.
|
|
534
|
+
* @param searchElement - Value to match.
|
|
535
|
+
* @param fromIndex - Start position (supports negative index).
|
|
536
|
+
* @returns Index or `-1` if not found.
|
|
537
|
+
* @remarks Time O(n), Space O(1)
|
|
538
|
+
*/
|
|
539
|
+
indexOf(searchElement, fromIndex = 0) {
|
|
540
|
+
if (this.length === 0) return -1;
|
|
541
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
542
|
+
if (fromIndex < 0) fromIndex = 0;
|
|
543
|
+
for (let i = fromIndex; i < this.length; i++) {
|
|
544
|
+
const element = this.at(i);
|
|
545
|
+
if (element === searchElement) return i;
|
|
546
|
+
}
|
|
547
|
+
return -1;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Last index of a value from the right.
|
|
551
|
+
* @param searchElement - Value to match.
|
|
552
|
+
* @param fromIndex - Start position (supports negative index).
|
|
553
|
+
* @returns Index or `-1` if not found.
|
|
554
|
+
* @remarks Time O(n), Space O(1)
|
|
555
|
+
*/
|
|
556
|
+
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
557
|
+
if (this.length === 0) return -1;
|
|
558
|
+
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
559
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
560
|
+
for (let i = fromIndex; i >= 0; i--) {
|
|
561
|
+
const element = this.at(i);
|
|
562
|
+
if (element === searchElement) return i;
|
|
563
|
+
}
|
|
564
|
+
return -1;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Find the first index matching a predicate.
|
|
568
|
+
* @param predicate - `(element, index, self) => boolean`.
|
|
569
|
+
* @param thisArg - Optional `this` for callback.
|
|
570
|
+
* @returns Index or `-1`.
|
|
571
|
+
* @remarks Time O(n), Space O(1)
|
|
572
|
+
*/
|
|
573
|
+
findIndex(predicate, thisArg) {
|
|
574
|
+
for (let i = 0; i < this.length; i++) {
|
|
575
|
+
const item = this.at(i);
|
|
576
|
+
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
577
|
+
}
|
|
578
|
+
return -1;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Concatenate elements and/or containers.
|
|
582
|
+
* @param items - Elements or other containers.
|
|
583
|
+
* @returns New container with combined elements (`this` type).
|
|
584
|
+
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
585
|
+
*/
|
|
586
|
+
concat(...items) {
|
|
587
|
+
const newList = this.clone();
|
|
588
|
+
for (const item of items) {
|
|
589
|
+
if (item instanceof _LinearBase) {
|
|
590
|
+
newList.pushMany(item);
|
|
591
|
+
} else {
|
|
592
|
+
newList.push(item);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return newList;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* In-place stable order via array sort semantics.
|
|
599
|
+
* @param compareFn - Comparator `(a, b) => number`.
|
|
600
|
+
* @returns This container.
|
|
601
|
+
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
602
|
+
*/
|
|
603
|
+
sort(compareFn) {
|
|
604
|
+
const arr = this.toArray();
|
|
605
|
+
arr.sort(compareFn);
|
|
606
|
+
this.clear();
|
|
607
|
+
for (const item of arr) this.push(item);
|
|
608
|
+
return this;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Remove and/or insert elements at a position (array-compatible).
|
|
612
|
+
* @param start - Start index (supports negative index).
|
|
613
|
+
* @param deleteCount - How many to remove.
|
|
614
|
+
* @param items - Elements to insert.
|
|
615
|
+
* @returns Removed elements as a new list (`this` type).
|
|
616
|
+
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
617
|
+
*/
|
|
618
|
+
splice(start, deleteCount = 0, ...items) {
|
|
619
|
+
const removedList = this._createInstance();
|
|
620
|
+
start = start < 0 ? this.length + start : start;
|
|
621
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
622
|
+
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
623
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
624
|
+
const removed = this.deleteAt(start);
|
|
625
|
+
if (removed !== void 0) {
|
|
626
|
+
removedList.push(removed);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
for (let i = 0; i < items.length; i++) {
|
|
630
|
+
this.addAt(start + i, items[i]);
|
|
631
|
+
}
|
|
632
|
+
return removedList;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Join all elements into a string.
|
|
636
|
+
* @param separator - Separator string.
|
|
637
|
+
* @returns Concatenated string.
|
|
638
|
+
* @remarks Time O(n), Space O(n)
|
|
639
|
+
*/
|
|
640
|
+
join(separator = ",") {
|
|
641
|
+
return this.toArray().join(separator);
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Snapshot elements into a reversed array.
|
|
645
|
+
* @returns New reversed array.
|
|
646
|
+
* @remarks Time O(n), Space O(n)
|
|
647
|
+
*/
|
|
648
|
+
toReversedArray() {
|
|
649
|
+
const array = [];
|
|
650
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
651
|
+
array.push(this.at(i));
|
|
652
|
+
}
|
|
653
|
+
return array;
|
|
654
|
+
}
|
|
655
|
+
reduceRight(callbackfn, initialValue) {
|
|
656
|
+
let accumulator = initialValue != null ? initialValue : 0;
|
|
657
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
658
|
+
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
659
|
+
}
|
|
660
|
+
return accumulator;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Create a shallow copy of a subrange.
|
|
664
|
+
* @param start - Inclusive start (supports negative index).
|
|
665
|
+
* @param end - Exclusive end (supports negative index).
|
|
666
|
+
* @returns New list with the range (`this` type).
|
|
667
|
+
* @remarks Time O(n), Space O(n)
|
|
668
|
+
*/
|
|
669
|
+
slice(start = 0, end = this.length) {
|
|
670
|
+
start = start < 0 ? this.length + start : start;
|
|
671
|
+
end = end < 0 ? this.length + end : end;
|
|
672
|
+
const newList = this._createInstance();
|
|
673
|
+
for (let i = start; i < end; i++) {
|
|
674
|
+
newList.push(this.at(i));
|
|
675
|
+
}
|
|
676
|
+
return newList;
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Fill a range with a value.
|
|
680
|
+
* @param value - Value to set.
|
|
681
|
+
* @param start - Inclusive start.
|
|
682
|
+
* @param end - Exclusive end.
|
|
683
|
+
* @returns This list.
|
|
684
|
+
* @remarks Time O(n), Space O(1)
|
|
685
|
+
*/
|
|
686
|
+
fill(value, start = 0, end = this.length) {
|
|
687
|
+
start = start < 0 ? this.length + start : start;
|
|
688
|
+
end = end < 0 ? this.length + end : end;
|
|
689
|
+
if (start < 0) start = 0;
|
|
690
|
+
if (end > this.length) end = this.length;
|
|
691
|
+
if (start >= end) return this;
|
|
692
|
+
for (let i = start; i < end; i++) {
|
|
693
|
+
this.setAt(i, value);
|
|
694
|
+
}
|
|
695
|
+
return this;
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
|
|
509
699
|
// src/data-structures/heap/heap.ts
|
|
510
700
|
var Heap = class _Heap extends IterableElementBase {
|
|
511
701
|
/**
|
|
@@ -543,10 +733,51 @@ var graphTyped = (() => {
|
|
|
543
733
|
return this._elements;
|
|
544
734
|
}
|
|
545
735
|
/**
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
736
|
+
* Get the number of elements.
|
|
737
|
+
* @remarks Time O(1), Space O(1)
|
|
738
|
+
* @returns Heap size.
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
* @example
|
|
772
|
+
* // Track heap capacity
|
|
773
|
+
* const heap = new Heap<number>();
|
|
774
|
+
* console.log(heap.size); // 0;
|
|
775
|
+
* heap.add(10);
|
|
776
|
+
* heap.add(20);
|
|
777
|
+
* console.log(heap.size); // 2;
|
|
778
|
+
* heap.poll();
|
|
779
|
+
* console.log(heap.size); // 1;
|
|
780
|
+
*/
|
|
550
781
|
get size() {
|
|
551
782
|
return this.elements.length;
|
|
552
783
|
}
|
|
@@ -585,21 +816,103 @@ var graphTyped = (() => {
|
|
|
585
816
|
return new _Heap(elements, options);
|
|
586
817
|
}
|
|
587
818
|
/**
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
819
|
+
* Insert an element.
|
|
820
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
821
|
+
* @param element - Element to insert.
|
|
822
|
+
* @returns True.
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
* @example
|
|
856
|
+
* // basic Heap creation and add operation
|
|
857
|
+
* // Create a min heap (default)
|
|
858
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
859
|
+
*
|
|
860
|
+
* // Verify size
|
|
861
|
+
* console.log(minHeap.size); // 6;
|
|
862
|
+
*
|
|
863
|
+
* // Add new element
|
|
864
|
+
* minHeap.add(4);
|
|
865
|
+
* console.log(minHeap.size); // 7;
|
|
866
|
+
*
|
|
867
|
+
* // Min heap property: smallest element at root
|
|
868
|
+
* const min = minHeap.peek();
|
|
869
|
+
* console.log(min); // 1;
|
|
870
|
+
*/
|
|
593
871
|
add(element) {
|
|
594
872
|
this._elements.push(element);
|
|
595
873
|
return this._bubbleUp(this.elements.length - 1);
|
|
596
874
|
}
|
|
597
875
|
/**
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
876
|
+
* Insert many elements from an iterable.
|
|
877
|
+
* @remarks Time O(N log N), Space O(1)
|
|
878
|
+
* @param elements - Iterable of elements or raw values.
|
|
879
|
+
* @returns Array of per-element success flags.
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
* @example
|
|
910
|
+
* // Add multiple elements
|
|
911
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
912
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
913
|
+
* console.log(heap.peek()); // 1;
|
|
914
|
+
* console.log(heap.size); // 4;
|
|
915
|
+
*/
|
|
603
916
|
addMany(elements) {
|
|
604
917
|
const flags = [];
|
|
605
918
|
for (const el of elements) {
|
|
@@ -614,10 +927,67 @@ var graphTyped = (() => {
|
|
|
614
927
|
return flags;
|
|
615
928
|
}
|
|
616
929
|
/**
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
930
|
+
* Remove and return the top element.
|
|
931
|
+
* @remarks Time O(log N), Space O(1)
|
|
932
|
+
* @returns Top element or undefined.
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
* @example
|
|
966
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
967
|
+
* interface Task {
|
|
968
|
+
* id: number;
|
|
969
|
+
* priority: number;
|
|
970
|
+
* name: string;
|
|
971
|
+
* }
|
|
972
|
+
*
|
|
973
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
974
|
+
* const tasks: Task[] = [
|
|
975
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
976
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
977
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
978
|
+
* ];
|
|
979
|
+
*
|
|
980
|
+
* const maxHeap = new Heap(tasks, {
|
|
981
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
982
|
+
* });
|
|
983
|
+
*
|
|
984
|
+
* console.log(maxHeap.size); // 3;
|
|
985
|
+
*
|
|
986
|
+
* // Peek returns highest priority task
|
|
987
|
+
* const topTask = maxHeap.peek();
|
|
988
|
+
* console.log(topTask?.priority); // 8;
|
|
989
|
+
* console.log(topTask?.name); // 'Alert';
|
|
990
|
+
*/
|
|
621
991
|
poll() {
|
|
622
992
|
if (this.elements.length === 0) return;
|
|
623
993
|
const value = this.elements[0];
|
|
@@ -629,26 +999,188 @@ var graphTyped = (() => {
|
|
|
629
999
|
return value;
|
|
630
1000
|
}
|
|
631
1001
|
/**
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
1002
|
+
* Get the current top element without removing it.
|
|
1003
|
+
* @remarks Time O(1), Space O(1)
|
|
1004
|
+
* @returns Top element or undefined.
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
* @example
|
|
1038
|
+
* // Heap for event processing with priority
|
|
1039
|
+
* interface Event {
|
|
1040
|
+
* id: number;
|
|
1041
|
+
* type: 'critical' | 'warning' | 'info';
|
|
1042
|
+
* timestamp: number;
|
|
1043
|
+
* message: string;
|
|
1044
|
+
* }
|
|
1045
|
+
*
|
|
1046
|
+
* // Custom priority: critical > warning > info
|
|
1047
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
1048
|
+
*
|
|
1049
|
+
* const eventHeap = new Heap<Event>([], {
|
|
1050
|
+
* comparator: (a: Event, b: Event) => {
|
|
1051
|
+
* const priorityA = priorityMap[a.type];
|
|
1052
|
+
* const priorityB = priorityMap[b.type];
|
|
1053
|
+
* return priorityB - priorityA; // Higher priority first
|
|
1054
|
+
* }
|
|
1055
|
+
* });
|
|
1056
|
+
*
|
|
1057
|
+
* // Add events in random order
|
|
1058
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
1059
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
1060
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
1061
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
1062
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
1063
|
+
*
|
|
1064
|
+
* console.log(eventHeap.size); // 5;
|
|
1065
|
+
*
|
|
1066
|
+
* // Process events by priority (critical first)
|
|
1067
|
+
* const processedOrder: Event[] = [];
|
|
1068
|
+
* while (eventHeap.size > 0) {
|
|
1069
|
+
* const event = eventHeap.poll();
|
|
1070
|
+
* if (event) {
|
|
1071
|
+
* processedOrder.push(event);
|
|
1072
|
+
* }
|
|
1073
|
+
* }
|
|
1074
|
+
*
|
|
1075
|
+
* // Verify critical events came first
|
|
1076
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
1077
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
1078
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
1079
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
1080
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
1081
|
+
*
|
|
1082
|
+
* // Verify O(log n) operations
|
|
1083
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
1084
|
+
*
|
|
1085
|
+
* // Add - O(log n)
|
|
1086
|
+
* newHeap.add(2);
|
|
1087
|
+
* console.log(newHeap.size); // 5;
|
|
1088
|
+
*
|
|
1089
|
+
* // Poll - O(log n)
|
|
1090
|
+
* const removed = newHeap.poll();
|
|
1091
|
+
* console.log(removed); // 1;
|
|
1092
|
+
*
|
|
1093
|
+
* // Peek - O(1)
|
|
1094
|
+
* const top = newHeap.peek();
|
|
1095
|
+
* console.log(top); // 2;
|
|
1096
|
+
*/
|
|
636
1097
|
peek() {
|
|
637
1098
|
return this.elements[0];
|
|
638
1099
|
}
|
|
639
1100
|
/**
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
1101
|
+
* Check whether the heap is empty.
|
|
1102
|
+
* @remarks Time O(1), Space O(1)
|
|
1103
|
+
* @returns True if size is 0.
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
* @example
|
|
1135
|
+
* // Check if heap is empty
|
|
1136
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
1137
|
+
* console.log(heap.isEmpty()); // true;
|
|
1138
|
+
* heap.add(1);
|
|
1139
|
+
* console.log(heap.isEmpty()); // false;
|
|
1140
|
+
*/
|
|
644
1141
|
isEmpty() {
|
|
645
1142
|
return this.size === 0;
|
|
646
1143
|
}
|
|
647
1144
|
/**
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
1145
|
+
* Remove all elements.
|
|
1146
|
+
* @remarks Time O(1), Space O(1)
|
|
1147
|
+
* @returns void
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
* @example
|
|
1179
|
+
* // Remove all elements
|
|
1180
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1181
|
+
* heap.clear();
|
|
1182
|
+
* console.log(heap.isEmpty()); // true;
|
|
1183
|
+
*/
|
|
652
1184
|
clear() {
|
|
653
1185
|
this._elements = [];
|
|
654
1186
|
}
|
|
@@ -663,21 +1195,83 @@ var graphTyped = (() => {
|
|
|
663
1195
|
return this.fix();
|
|
664
1196
|
}
|
|
665
1197
|
/**
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
1198
|
+
* Check if an equal element exists in the heap.
|
|
1199
|
+
* @remarks Time O(N), Space O(1)
|
|
1200
|
+
* @param element - Element to search for.
|
|
1201
|
+
* @returns True if found.
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
* @example
|
|
1226
|
+
* // Check element existence
|
|
1227
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1228
|
+
* console.log(heap.has(1)); // true;
|
|
1229
|
+
* console.log(heap.has(99)); // false;
|
|
1230
|
+
*/
|
|
671
1231
|
has(element) {
|
|
672
1232
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
673
1233
|
return false;
|
|
674
1234
|
}
|
|
675
1235
|
/**
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
1236
|
+
* Delete one occurrence of an element.
|
|
1237
|
+
* @remarks Time O(N), Space O(1)
|
|
1238
|
+
* @param element - Element to delete.
|
|
1239
|
+
* @returns True if an element was removed.
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
|
|
1243
|
+
|
|
1244
|
+
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
* @example
|
|
1270
|
+
* // Remove specific element
|
|
1271
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
1272
|
+
* heap.delete(4);
|
|
1273
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
1274
|
+
*/
|
|
681
1275
|
delete(element) {
|
|
682
1276
|
let index = -1;
|
|
683
1277
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -735,11 +1329,39 @@ var graphTyped = (() => {
|
|
|
735
1329
|
return this;
|
|
736
1330
|
}
|
|
737
1331
|
/**
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
1332
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
1333
|
+
* @remarks Time O(N), Space O(H)
|
|
1334
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
1335
|
+
* @returns Array of visited elements.
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
|
|
1346
|
+
|
|
1347
|
+
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
|
|
1352
|
+
|
|
1353
|
+
|
|
1354
|
+
|
|
1355
|
+
|
|
1356
|
+
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
* @example
|
|
1360
|
+
* // Depth-first traversal
|
|
1361
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1362
|
+
* const result = heap.dfs('IN');
|
|
1363
|
+
* console.log(result.length); // 3;
|
|
1364
|
+
*/
|
|
743
1365
|
dfs(order = "PRE") {
|
|
744
1366
|
const result = [];
|
|
745
1367
|
const _dfs = (index) => {
|
|
@@ -776,10 +1398,47 @@ var graphTyped = (() => {
|
|
|
776
1398
|
return results;
|
|
777
1399
|
}
|
|
778
1400
|
/**
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
1401
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
1402
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1403
|
+
* @returns Sorted array of elements.
|
|
1404
|
+
|
|
1405
|
+
|
|
1406
|
+
|
|
1407
|
+
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
|
|
1422
|
+
|
|
1423
|
+
|
|
1424
|
+
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
* @example
|
|
1437
|
+
* // Sort elements using heap
|
|
1438
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
1439
|
+
* const sorted = heap.sort();
|
|
1440
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
1441
|
+
*/
|
|
783
1442
|
sort() {
|
|
784
1443
|
const visited = [];
|
|
785
1444
|
const cloned = this._createInstance();
|
|
@@ -791,22 +1450,94 @@ var graphTyped = (() => {
|
|
|
791
1450
|
return visited;
|
|
792
1451
|
}
|
|
793
1452
|
/**
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
1453
|
+
* Deep clone this heap.
|
|
1454
|
+
* @remarks Time O(N), Space O(N)
|
|
1455
|
+
* @returns A new heap with the same elements.
|
|
1456
|
+
|
|
1457
|
+
|
|
1458
|
+
|
|
1459
|
+
|
|
1460
|
+
|
|
1461
|
+
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
|
|
1470
|
+
|
|
1471
|
+
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
|
|
1478
|
+
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
|
|
1482
|
+
|
|
1483
|
+
|
|
1484
|
+
|
|
1485
|
+
|
|
1486
|
+
* @example
|
|
1487
|
+
* // Create independent copy
|
|
1488
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
1489
|
+
* const copy = heap.clone();
|
|
1490
|
+
* copy.poll();
|
|
1491
|
+
* console.log(heap.size); // 3;
|
|
1492
|
+
* console.log(copy.size); // 2;
|
|
1493
|
+
*/
|
|
798
1494
|
clone() {
|
|
799
1495
|
const next = this._createInstance();
|
|
800
1496
|
for (const x of this.elements) next.add(x);
|
|
801
1497
|
return next;
|
|
802
1498
|
}
|
|
803
1499
|
/**
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
1500
|
+
* Filter elements into a new heap of the same class.
|
|
1501
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1502
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
1503
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1504
|
+
* @returns A new heap with the kept elements.
|
|
1505
|
+
|
|
1506
|
+
|
|
1507
|
+
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
|
|
1514
|
+
|
|
1515
|
+
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
|
|
1519
|
+
|
|
1520
|
+
|
|
1521
|
+
|
|
1522
|
+
|
|
1523
|
+
|
|
1524
|
+
|
|
1525
|
+
|
|
1526
|
+
|
|
1527
|
+
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
|
|
1531
|
+
|
|
1532
|
+
|
|
1533
|
+
|
|
1534
|
+
|
|
1535
|
+
* @example
|
|
1536
|
+
* // Filter elements
|
|
1537
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
1538
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
1539
|
+
* console.log(evens.size); // 2;
|
|
1540
|
+
*/
|
|
810
1541
|
filter(callback, thisArg) {
|
|
811
1542
|
const out = this._createInstance();
|
|
812
1543
|
let i = 0;
|
|
@@ -820,15 +1551,49 @@ var graphTyped = (() => {
|
|
|
820
1551
|
return out;
|
|
821
1552
|
}
|
|
822
1553
|
/**
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
1554
|
+
* Map elements into a new heap of possibly different element type.
|
|
1555
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1556
|
+
* @template EM
|
|
1557
|
+
* @template RM
|
|
1558
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
1559
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
1560
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1561
|
+
* @returns A new heap with mapped elements.
|
|
1562
|
+
|
|
1563
|
+
|
|
1564
|
+
|
|
1565
|
+
|
|
1566
|
+
|
|
1567
|
+
|
|
1568
|
+
|
|
1569
|
+
|
|
1570
|
+
|
|
1571
|
+
|
|
1572
|
+
|
|
1573
|
+
|
|
1574
|
+
|
|
1575
|
+
|
|
1576
|
+
|
|
1577
|
+
|
|
1578
|
+
|
|
1579
|
+
|
|
1580
|
+
|
|
1581
|
+
|
|
1582
|
+
|
|
1583
|
+
|
|
1584
|
+
|
|
1585
|
+
|
|
1586
|
+
|
|
1587
|
+
|
|
1588
|
+
|
|
1589
|
+
|
|
1590
|
+
|
|
1591
|
+
* @example
|
|
1592
|
+
* // Transform elements
|
|
1593
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1594
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
1595
|
+
* console.log(doubled.peek()); // 2;
|
|
1596
|
+
*/
|
|
832
1597
|
map(callback, options, thisArg) {
|
|
833
1598
|
const { comparator, toElementFn, ...rest } = options != null ? options : {};
|
|
834
1599
|
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
@@ -932,196 +1697,6 @@ var graphTyped = (() => {
|
|
|
932
1697
|
}
|
|
933
1698
|
};
|
|
934
1699
|
|
|
935
|
-
// src/data-structures/base/linear-base.ts
|
|
936
|
-
var LinearBase = class _LinearBase extends IterableElementBase {
|
|
937
|
-
/**
|
|
938
|
-
* Construct a linear container with runtime options.
|
|
939
|
-
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
940
|
-
* @remarks Time O(1), Space O(1)
|
|
941
|
-
*/
|
|
942
|
-
constructor(options) {
|
|
943
|
-
super(options);
|
|
944
|
-
__publicField(this, "_maxLen", -1);
|
|
945
|
-
if (options) {
|
|
946
|
-
const { maxLen } = options;
|
|
947
|
-
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
/**
|
|
951
|
-
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
952
|
-
* @returns Maximum allowed length.
|
|
953
|
-
* @remarks Time O(1), Space O(1)
|
|
954
|
-
*/
|
|
955
|
-
get maxLen() {
|
|
956
|
-
return this._maxLen;
|
|
957
|
-
}
|
|
958
|
-
/**
|
|
959
|
-
* First index of a value from the left.
|
|
960
|
-
* @param searchElement - Value to match.
|
|
961
|
-
* @param fromIndex - Start position (supports negative index).
|
|
962
|
-
* @returns Index or `-1` if not found.
|
|
963
|
-
* @remarks Time O(n), Space O(1)
|
|
964
|
-
*/
|
|
965
|
-
indexOf(searchElement, fromIndex = 0) {
|
|
966
|
-
if (this.length === 0) return -1;
|
|
967
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
968
|
-
if (fromIndex < 0) fromIndex = 0;
|
|
969
|
-
for (let i = fromIndex; i < this.length; i++) {
|
|
970
|
-
const element = this.at(i);
|
|
971
|
-
if (element === searchElement) return i;
|
|
972
|
-
}
|
|
973
|
-
return -1;
|
|
974
|
-
}
|
|
975
|
-
/**
|
|
976
|
-
* Last index of a value from the right.
|
|
977
|
-
* @param searchElement - Value to match.
|
|
978
|
-
* @param fromIndex - Start position (supports negative index).
|
|
979
|
-
* @returns Index or `-1` if not found.
|
|
980
|
-
* @remarks Time O(n), Space O(1)
|
|
981
|
-
*/
|
|
982
|
-
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
983
|
-
if (this.length === 0) return -1;
|
|
984
|
-
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
985
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
986
|
-
for (let i = fromIndex; i >= 0; i--) {
|
|
987
|
-
const element = this.at(i);
|
|
988
|
-
if (element === searchElement) return i;
|
|
989
|
-
}
|
|
990
|
-
return -1;
|
|
991
|
-
}
|
|
992
|
-
/**
|
|
993
|
-
* Find the first index matching a predicate.
|
|
994
|
-
* @param predicate - `(element, index, self) => boolean`.
|
|
995
|
-
* @param thisArg - Optional `this` for callback.
|
|
996
|
-
* @returns Index or `-1`.
|
|
997
|
-
* @remarks Time O(n), Space O(1)
|
|
998
|
-
*/
|
|
999
|
-
findIndex(predicate, thisArg) {
|
|
1000
|
-
for (let i = 0; i < this.length; i++) {
|
|
1001
|
-
const item = this.at(i);
|
|
1002
|
-
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
1003
|
-
}
|
|
1004
|
-
return -1;
|
|
1005
|
-
}
|
|
1006
|
-
/**
|
|
1007
|
-
* Concatenate elements and/or containers.
|
|
1008
|
-
* @param items - Elements or other containers.
|
|
1009
|
-
* @returns New container with combined elements (`this` type).
|
|
1010
|
-
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
1011
|
-
*/
|
|
1012
|
-
concat(...items) {
|
|
1013
|
-
const newList = this.clone();
|
|
1014
|
-
for (const item of items) {
|
|
1015
|
-
if (item instanceof _LinearBase) {
|
|
1016
|
-
newList.pushMany(item);
|
|
1017
|
-
} else {
|
|
1018
|
-
newList.push(item);
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
return newList;
|
|
1022
|
-
}
|
|
1023
|
-
/**
|
|
1024
|
-
* In-place stable order via array sort semantics.
|
|
1025
|
-
* @param compareFn - Comparator `(a, b) => number`.
|
|
1026
|
-
* @returns This container.
|
|
1027
|
-
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
1028
|
-
*/
|
|
1029
|
-
sort(compareFn) {
|
|
1030
|
-
const arr = this.toArray();
|
|
1031
|
-
arr.sort(compareFn);
|
|
1032
|
-
this.clear();
|
|
1033
|
-
for (const item of arr) this.push(item);
|
|
1034
|
-
return this;
|
|
1035
|
-
}
|
|
1036
|
-
/**
|
|
1037
|
-
* Remove and/or insert elements at a position (array-compatible).
|
|
1038
|
-
* @param start - Start index (supports negative index).
|
|
1039
|
-
* @param deleteCount - How many to remove.
|
|
1040
|
-
* @param items - Elements to insert.
|
|
1041
|
-
* @returns Removed elements as a new list (`this` type).
|
|
1042
|
-
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
1043
|
-
*/
|
|
1044
|
-
splice(start, deleteCount = 0, ...items) {
|
|
1045
|
-
const removedList = this._createInstance();
|
|
1046
|
-
start = start < 0 ? this.length + start : start;
|
|
1047
|
-
start = Math.max(0, Math.min(start, this.length));
|
|
1048
|
-
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
1049
|
-
for (let i = 0; i < deleteCount; i++) {
|
|
1050
|
-
const removed = this.deleteAt(start);
|
|
1051
|
-
if (removed !== void 0) {
|
|
1052
|
-
removedList.push(removed);
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
for (let i = 0; i < items.length; i++) {
|
|
1056
|
-
this.addAt(start + i, items[i]);
|
|
1057
|
-
}
|
|
1058
|
-
return removedList;
|
|
1059
|
-
}
|
|
1060
|
-
/**
|
|
1061
|
-
* Join all elements into a string.
|
|
1062
|
-
* @param separator - Separator string.
|
|
1063
|
-
* @returns Concatenated string.
|
|
1064
|
-
* @remarks Time O(n), Space O(n)
|
|
1065
|
-
*/
|
|
1066
|
-
join(separator = ",") {
|
|
1067
|
-
return this.toArray().join(separator);
|
|
1068
|
-
}
|
|
1069
|
-
/**
|
|
1070
|
-
* Snapshot elements into a reversed array.
|
|
1071
|
-
* @returns New reversed array.
|
|
1072
|
-
* @remarks Time O(n), Space O(n)
|
|
1073
|
-
*/
|
|
1074
|
-
toReversedArray() {
|
|
1075
|
-
const array = [];
|
|
1076
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1077
|
-
array.push(this.at(i));
|
|
1078
|
-
}
|
|
1079
|
-
return array;
|
|
1080
|
-
}
|
|
1081
|
-
reduceRight(callbackfn, initialValue) {
|
|
1082
|
-
let accumulator = initialValue != null ? initialValue : 0;
|
|
1083
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1084
|
-
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
1085
|
-
}
|
|
1086
|
-
return accumulator;
|
|
1087
|
-
}
|
|
1088
|
-
/**
|
|
1089
|
-
* Create a shallow copy of a subrange.
|
|
1090
|
-
* @param start - Inclusive start (supports negative index).
|
|
1091
|
-
* @param end - Exclusive end (supports negative index).
|
|
1092
|
-
* @returns New list with the range (`this` type).
|
|
1093
|
-
* @remarks Time O(n), Space O(n)
|
|
1094
|
-
*/
|
|
1095
|
-
slice(start = 0, end = this.length) {
|
|
1096
|
-
start = start < 0 ? this.length + start : start;
|
|
1097
|
-
end = end < 0 ? this.length + end : end;
|
|
1098
|
-
const newList = this._createInstance();
|
|
1099
|
-
for (let i = start; i < end; i++) {
|
|
1100
|
-
newList.push(this.at(i));
|
|
1101
|
-
}
|
|
1102
|
-
return newList;
|
|
1103
|
-
}
|
|
1104
|
-
/**
|
|
1105
|
-
* Fill a range with a value.
|
|
1106
|
-
* @param value - Value to set.
|
|
1107
|
-
* @param start - Inclusive start.
|
|
1108
|
-
* @param end - Exclusive end.
|
|
1109
|
-
* @returns This list.
|
|
1110
|
-
* @remarks Time O(n), Space O(1)
|
|
1111
|
-
*/
|
|
1112
|
-
fill(value, start = 0, end = this.length) {
|
|
1113
|
-
start = start < 0 ? this.length + start : start;
|
|
1114
|
-
end = end < 0 ? this.length + end : end;
|
|
1115
|
-
if (start < 0) start = 0;
|
|
1116
|
-
if (end > this.length) end = this.length;
|
|
1117
|
-
if (start >= end) return this;
|
|
1118
|
-
for (let i = start; i < end; i++) {
|
|
1119
|
-
this.setAt(i, value);
|
|
1120
|
-
}
|
|
1121
|
-
return this;
|
|
1122
|
-
}
|
|
1123
|
-
};
|
|
1124
|
-
|
|
1125
1700
|
// src/data-structures/queue/queue.ts
|
|
1126
1701
|
var Queue = class _Queue extends LinearBase {
|
|
1127
1702
|
/**
|
|
@@ -1176,18 +1751,94 @@ var graphTyped = (() => {
|
|
|
1176
1751
|
this._autoCompactRatio = value;
|
|
1177
1752
|
}
|
|
1178
1753
|
/**
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1754
|
+
* Get the number of elements currently in the queue.
|
|
1755
|
+
* @remarks Time O(1), Space O(1)
|
|
1756
|
+
* @returns Current length.
|
|
1757
|
+
|
|
1758
|
+
|
|
1759
|
+
|
|
1760
|
+
|
|
1761
|
+
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
|
|
1765
|
+
|
|
1766
|
+
|
|
1767
|
+
|
|
1768
|
+
|
|
1769
|
+
|
|
1770
|
+
|
|
1771
|
+
|
|
1772
|
+
|
|
1773
|
+
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
|
|
1777
|
+
|
|
1778
|
+
|
|
1779
|
+
|
|
1780
|
+
|
|
1781
|
+
|
|
1782
|
+
|
|
1783
|
+
|
|
1784
|
+
|
|
1785
|
+
|
|
1786
|
+
|
|
1787
|
+
|
|
1788
|
+
|
|
1789
|
+
* @example
|
|
1790
|
+
* // Track queue length
|
|
1791
|
+
* const q = new Queue<number>();
|
|
1792
|
+
* console.log(q.length); // 0;
|
|
1793
|
+
* q.push(1);
|
|
1794
|
+
* q.push(2);
|
|
1795
|
+
* console.log(q.length); // 2;
|
|
1796
|
+
*/
|
|
1183
1797
|
get length() {
|
|
1184
1798
|
return this.elements.length - this._offset;
|
|
1185
1799
|
}
|
|
1186
1800
|
/**
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1801
|
+
* Get the first element (front) without removing it.
|
|
1802
|
+
* @remarks Time O(1), Space O(1)
|
|
1803
|
+
* @returns Front element or undefined.
|
|
1804
|
+
|
|
1805
|
+
|
|
1806
|
+
|
|
1807
|
+
|
|
1808
|
+
|
|
1809
|
+
|
|
1810
|
+
|
|
1811
|
+
|
|
1812
|
+
|
|
1813
|
+
|
|
1814
|
+
|
|
1815
|
+
|
|
1816
|
+
|
|
1817
|
+
|
|
1818
|
+
|
|
1819
|
+
|
|
1820
|
+
|
|
1821
|
+
|
|
1822
|
+
|
|
1823
|
+
|
|
1824
|
+
|
|
1825
|
+
|
|
1826
|
+
|
|
1827
|
+
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
|
|
1831
|
+
|
|
1832
|
+
|
|
1833
|
+
|
|
1834
|
+
|
|
1835
|
+
|
|
1836
|
+
* @example
|
|
1837
|
+
* // View the front element
|
|
1838
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
1839
|
+
* console.log(q.first); // 'first';
|
|
1840
|
+
* console.log(q.length); // 3;
|
|
1841
|
+
*/
|
|
1191
1842
|
get first() {
|
|
1192
1843
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
1193
1844
|
}
|
|
@@ -1210,19 +1861,111 @@ var graphTyped = (() => {
|
|
|
1210
1861
|
return new _Queue(elements);
|
|
1211
1862
|
}
|
|
1212
1863
|
/**
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1864
|
+
* Check whether the queue is empty.
|
|
1865
|
+
* @remarks Time O(1), Space O(1)
|
|
1866
|
+
* @returns True if length is 0.
|
|
1867
|
+
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
|
|
1871
|
+
|
|
1872
|
+
|
|
1873
|
+
|
|
1874
|
+
|
|
1875
|
+
|
|
1876
|
+
|
|
1877
|
+
|
|
1878
|
+
|
|
1879
|
+
|
|
1880
|
+
|
|
1881
|
+
|
|
1882
|
+
|
|
1883
|
+
|
|
1884
|
+
|
|
1885
|
+
|
|
1886
|
+
|
|
1887
|
+
|
|
1888
|
+
|
|
1889
|
+
|
|
1890
|
+
|
|
1891
|
+
|
|
1892
|
+
|
|
1893
|
+
|
|
1894
|
+
|
|
1895
|
+
|
|
1896
|
+
|
|
1897
|
+
|
|
1898
|
+
|
|
1899
|
+
* @example
|
|
1900
|
+
* // Queue for...of iteration and isEmpty check
|
|
1901
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
1902
|
+
*
|
|
1903
|
+
* const elements: string[] = [];
|
|
1904
|
+
* for (const item of queue) {
|
|
1905
|
+
* elements.push(item);
|
|
1906
|
+
* }
|
|
1907
|
+
*
|
|
1908
|
+
* // Verify all elements are iterated in order
|
|
1909
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
1910
|
+
*
|
|
1911
|
+
* // Process all elements
|
|
1912
|
+
* while (queue.length > 0) {
|
|
1913
|
+
* queue.shift();
|
|
1914
|
+
* }
|
|
1915
|
+
*
|
|
1916
|
+
* console.log(queue.length); // 0;
|
|
1917
|
+
*/
|
|
1217
1918
|
isEmpty() {
|
|
1218
1919
|
return this.length === 0;
|
|
1219
1920
|
}
|
|
1220
1921
|
/**
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1922
|
+
* Enqueue one element at the back.
|
|
1923
|
+
* @remarks Time O(1), Space O(1)
|
|
1924
|
+
* @param element - Element to enqueue.
|
|
1925
|
+
* @returns True on success.
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
|
|
1933
|
+
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
|
|
1937
|
+
|
|
1938
|
+
|
|
1939
|
+
|
|
1940
|
+
|
|
1941
|
+
|
|
1942
|
+
|
|
1943
|
+
|
|
1944
|
+
|
|
1945
|
+
|
|
1946
|
+
|
|
1947
|
+
|
|
1948
|
+
|
|
1949
|
+
|
|
1950
|
+
|
|
1951
|
+
|
|
1952
|
+
|
|
1953
|
+
|
|
1954
|
+
|
|
1955
|
+
|
|
1956
|
+
|
|
1957
|
+
|
|
1958
|
+
* @example
|
|
1959
|
+
* // basic Queue creation and push operation
|
|
1960
|
+
* // Create a simple Queue with initial values
|
|
1961
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
1962
|
+
*
|
|
1963
|
+
* // Verify the queue maintains insertion order
|
|
1964
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
1965
|
+
*
|
|
1966
|
+
* // Check length
|
|
1967
|
+
* console.log(queue.length); // 5;
|
|
1968
|
+
*/
|
|
1226
1969
|
push(element) {
|
|
1227
1970
|
this.elements.push(element);
|
|
1228
1971
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -1243,10 +1986,56 @@ var graphTyped = (() => {
|
|
|
1243
1986
|
return ans;
|
|
1244
1987
|
}
|
|
1245
1988
|
/**
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1989
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1990
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1991
|
+
* @returns Removed element or undefined.
|
|
1992
|
+
|
|
1993
|
+
|
|
1994
|
+
|
|
1995
|
+
|
|
1996
|
+
|
|
1997
|
+
|
|
1998
|
+
|
|
1999
|
+
|
|
2000
|
+
|
|
2001
|
+
|
|
2002
|
+
|
|
2003
|
+
|
|
2004
|
+
|
|
2005
|
+
|
|
2006
|
+
|
|
2007
|
+
|
|
2008
|
+
|
|
2009
|
+
|
|
2010
|
+
|
|
2011
|
+
|
|
2012
|
+
|
|
2013
|
+
|
|
2014
|
+
|
|
2015
|
+
|
|
2016
|
+
|
|
2017
|
+
|
|
2018
|
+
|
|
2019
|
+
|
|
2020
|
+
|
|
2021
|
+
|
|
2022
|
+
|
|
2023
|
+
|
|
2024
|
+
* @example
|
|
2025
|
+
* // Queue shift and peek operations
|
|
2026
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
2027
|
+
*
|
|
2028
|
+
* // Peek at the front element without removing it
|
|
2029
|
+
* console.log(queue.first); // 10;
|
|
2030
|
+
*
|
|
2031
|
+
* // Remove and get the first element (FIFO)
|
|
2032
|
+
* const first = queue.shift();
|
|
2033
|
+
* console.log(first); // 10;
|
|
2034
|
+
*
|
|
2035
|
+
* // Verify remaining elements and length decreased
|
|
2036
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
2037
|
+
* console.log(queue.length); // 3;
|
|
2038
|
+
*/
|
|
1250
2039
|
shift() {
|
|
1251
2040
|
if (this.length === 0) return void 0;
|
|
1252
2041
|
const first = this.first;
|
|
@@ -1255,11 +2044,45 @@ var graphTyped = (() => {
|
|
|
1255
2044
|
return first;
|
|
1256
2045
|
}
|
|
1257
2046
|
/**
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
2047
|
+
* Delete the first occurrence of a specific element.
|
|
2048
|
+
* @remarks Time O(N), Space O(1)
|
|
2049
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
2050
|
+
* @returns True if an element was removed.
|
|
2051
|
+
|
|
2052
|
+
|
|
2053
|
+
|
|
2054
|
+
|
|
2055
|
+
|
|
2056
|
+
|
|
2057
|
+
|
|
2058
|
+
|
|
2059
|
+
|
|
2060
|
+
|
|
2061
|
+
|
|
2062
|
+
|
|
2063
|
+
|
|
2064
|
+
|
|
2065
|
+
|
|
2066
|
+
|
|
2067
|
+
|
|
2068
|
+
|
|
2069
|
+
|
|
2070
|
+
|
|
2071
|
+
|
|
2072
|
+
|
|
2073
|
+
|
|
2074
|
+
|
|
2075
|
+
|
|
2076
|
+
|
|
2077
|
+
|
|
2078
|
+
|
|
2079
|
+
|
|
2080
|
+
* @example
|
|
2081
|
+
* // Remove specific element
|
|
2082
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
2083
|
+
* q.delete(2);
|
|
2084
|
+
* console.log(q.length); // 3;
|
|
2085
|
+
*/
|
|
1263
2086
|
delete(element) {
|
|
1264
2087
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
1265
2088
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -1270,11 +2093,45 @@ var graphTyped = (() => {
|
|
|
1270
2093
|
return false;
|
|
1271
2094
|
}
|
|
1272
2095
|
/**
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
2096
|
+
* Get the element at a given logical index.
|
|
2097
|
+
* @remarks Time O(1), Space O(1)
|
|
2098
|
+
* @param index - Zero-based index from the front.
|
|
2099
|
+
* @returns Element or undefined.
|
|
2100
|
+
|
|
2101
|
+
|
|
2102
|
+
|
|
2103
|
+
|
|
2104
|
+
|
|
2105
|
+
|
|
2106
|
+
|
|
2107
|
+
|
|
2108
|
+
|
|
2109
|
+
|
|
2110
|
+
|
|
2111
|
+
|
|
2112
|
+
|
|
2113
|
+
|
|
2114
|
+
|
|
2115
|
+
|
|
2116
|
+
|
|
2117
|
+
|
|
2118
|
+
|
|
2119
|
+
|
|
2120
|
+
|
|
2121
|
+
|
|
2122
|
+
|
|
2123
|
+
|
|
2124
|
+
|
|
2125
|
+
|
|
2126
|
+
|
|
2127
|
+
|
|
2128
|
+
|
|
2129
|
+
* @example
|
|
2130
|
+
* // Access element by index
|
|
2131
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
2132
|
+
* console.log(q.at(0)); // 'a';
|
|
2133
|
+
* console.log(q.at(2)); // 'c';
|
|
2134
|
+
*/
|
|
1278
2135
|
at(index) {
|
|
1279
2136
|
if (index < 0 || index >= this.length) return void 0;
|
|
1280
2137
|
return this._elements[this._offset + index];
|
|
@@ -1326,19 +2183,90 @@ var graphTyped = (() => {
|
|
|
1326
2183
|
return this;
|
|
1327
2184
|
}
|
|
1328
2185
|
/**
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
2186
|
+
* Remove all elements and reset offset.
|
|
2187
|
+
* @remarks Time O(1), Space O(1)
|
|
2188
|
+
* @returns void
|
|
2189
|
+
|
|
2190
|
+
|
|
2191
|
+
|
|
2192
|
+
|
|
2193
|
+
|
|
2194
|
+
|
|
2195
|
+
|
|
2196
|
+
|
|
2197
|
+
|
|
2198
|
+
|
|
2199
|
+
|
|
2200
|
+
|
|
2201
|
+
|
|
2202
|
+
|
|
2203
|
+
|
|
2204
|
+
|
|
2205
|
+
|
|
2206
|
+
|
|
2207
|
+
|
|
2208
|
+
|
|
2209
|
+
|
|
2210
|
+
|
|
2211
|
+
|
|
2212
|
+
|
|
2213
|
+
|
|
2214
|
+
|
|
2215
|
+
|
|
2216
|
+
|
|
2217
|
+
|
|
2218
|
+
|
|
2219
|
+
* @example
|
|
2220
|
+
* // Remove all elements
|
|
2221
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2222
|
+
* q.clear();
|
|
2223
|
+
* console.log(q.length); // 0;
|
|
2224
|
+
*/
|
|
1333
2225
|
clear() {
|
|
1334
2226
|
this._elements = [];
|
|
1335
2227
|
this._offset = 0;
|
|
1336
2228
|
}
|
|
1337
2229
|
/**
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
2230
|
+
* Compact storage by discarding consumed head elements.
|
|
2231
|
+
* @remarks Time O(N), Space O(N)
|
|
2232
|
+
* @returns True when compaction performed.
|
|
2233
|
+
|
|
2234
|
+
|
|
2235
|
+
|
|
2236
|
+
|
|
2237
|
+
|
|
2238
|
+
|
|
2239
|
+
|
|
2240
|
+
|
|
2241
|
+
|
|
2242
|
+
|
|
2243
|
+
|
|
2244
|
+
|
|
2245
|
+
|
|
2246
|
+
|
|
2247
|
+
|
|
2248
|
+
|
|
2249
|
+
|
|
2250
|
+
|
|
2251
|
+
|
|
2252
|
+
|
|
2253
|
+
|
|
2254
|
+
|
|
2255
|
+
|
|
2256
|
+
|
|
2257
|
+
|
|
2258
|
+
|
|
2259
|
+
|
|
2260
|
+
|
|
2261
|
+
|
|
2262
|
+
* @example
|
|
2263
|
+
* // Reclaim unused memory
|
|
2264
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2265
|
+
* q.shift();
|
|
2266
|
+
* q.shift();
|
|
2267
|
+
* q.compact();
|
|
2268
|
+
* console.log(q.length); // 3;
|
|
2269
|
+
*/
|
|
1342
2270
|
compact() {
|
|
1343
2271
|
this._elements = this.elements.slice(this._offset);
|
|
1344
2272
|
this._offset = 0;
|
|
@@ -1364,10 +2292,47 @@ var graphTyped = (() => {
|
|
|
1364
2292
|
return removed;
|
|
1365
2293
|
}
|
|
1366
2294
|
/**
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
2295
|
+
* Deep clone this queue and its parameters.
|
|
2296
|
+
* @remarks Time O(N), Space O(N)
|
|
2297
|
+
* @returns A new queue with the same content and options.
|
|
2298
|
+
|
|
2299
|
+
|
|
2300
|
+
|
|
2301
|
+
|
|
2302
|
+
|
|
2303
|
+
|
|
2304
|
+
|
|
2305
|
+
|
|
2306
|
+
|
|
2307
|
+
|
|
2308
|
+
|
|
2309
|
+
|
|
2310
|
+
|
|
2311
|
+
|
|
2312
|
+
|
|
2313
|
+
|
|
2314
|
+
|
|
2315
|
+
|
|
2316
|
+
|
|
2317
|
+
|
|
2318
|
+
|
|
2319
|
+
|
|
2320
|
+
|
|
2321
|
+
|
|
2322
|
+
|
|
2323
|
+
|
|
2324
|
+
|
|
2325
|
+
|
|
2326
|
+
|
|
2327
|
+
|
|
2328
|
+
* @example
|
|
2329
|
+
* // Create independent copy
|
|
2330
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2331
|
+
* const copy = q.clone();
|
|
2332
|
+
* copy.shift();
|
|
2333
|
+
* console.log(q.length); // 3;
|
|
2334
|
+
* console.log(copy.length); // 2;
|
|
2335
|
+
*/
|
|
1371
2336
|
clone() {
|
|
1372
2337
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1373
2338
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1375,12 +2340,47 @@ var graphTyped = (() => {
|
|
|
1375
2340
|
return out;
|
|
1376
2341
|
}
|
|
1377
2342
|
/**
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
2343
|
+
* Filter elements into a new queue of the same class.
|
|
2344
|
+
* @remarks Time O(N), Space O(N)
|
|
2345
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
2346
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
2347
|
+
* @returns A new queue with kept elements.
|
|
2348
|
+
|
|
2349
|
+
|
|
2350
|
+
|
|
2351
|
+
|
|
2352
|
+
|
|
2353
|
+
|
|
2354
|
+
|
|
2355
|
+
|
|
2356
|
+
|
|
2357
|
+
|
|
2358
|
+
|
|
2359
|
+
|
|
2360
|
+
|
|
2361
|
+
|
|
2362
|
+
|
|
2363
|
+
|
|
2364
|
+
|
|
2365
|
+
|
|
2366
|
+
|
|
2367
|
+
|
|
2368
|
+
|
|
2369
|
+
|
|
2370
|
+
|
|
2371
|
+
|
|
2372
|
+
|
|
2373
|
+
|
|
2374
|
+
|
|
2375
|
+
|
|
2376
|
+
|
|
2377
|
+
|
|
2378
|
+
* @example
|
|
2379
|
+
* // Filter elements
|
|
2380
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2381
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
2382
|
+
* console.log(evens.length); // 2;
|
|
2383
|
+
*/
|
|
1384
2384
|
filter(predicate, thisArg) {
|
|
1385
2385
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1386
2386
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1392,15 +2392,49 @@ var graphTyped = (() => {
|
|
|
1392
2392
|
return out;
|
|
1393
2393
|
}
|
|
1394
2394
|
/**
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
2395
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
2396
|
+
* @remarks Time O(N), Space O(N)
|
|
2397
|
+
* @template EM
|
|
2398
|
+
* @template RM
|
|
2399
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
2400
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
2401
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
2402
|
+
* @returns A new Queue with mapped elements.
|
|
2403
|
+
|
|
2404
|
+
|
|
2405
|
+
|
|
2406
|
+
|
|
2407
|
+
|
|
2408
|
+
|
|
2409
|
+
|
|
2410
|
+
|
|
2411
|
+
|
|
2412
|
+
|
|
2413
|
+
|
|
2414
|
+
|
|
2415
|
+
|
|
2416
|
+
|
|
2417
|
+
|
|
2418
|
+
|
|
2419
|
+
|
|
2420
|
+
|
|
2421
|
+
|
|
2422
|
+
|
|
2423
|
+
|
|
2424
|
+
|
|
2425
|
+
|
|
2426
|
+
|
|
2427
|
+
|
|
2428
|
+
|
|
2429
|
+
|
|
2430
|
+
|
|
2431
|
+
|
|
2432
|
+
* @example
|
|
2433
|
+
* // Transform elements
|
|
2434
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2435
|
+
* const doubled = q.map(x => x * 2);
|
|
2436
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
2437
|
+
*/
|
|
1404
2438
|
map(callback, options, thisArg) {
|
|
1405
2439
|
var _a, _b;
|
|
1406
2440
|
const out = new this.constructor([], {
|
|
@@ -2488,12 +3522,49 @@ var graphTyped = (() => {
|
|
|
2488
3522
|
return new DirectedEdge(src, dest, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
|
|
2489
3523
|
}
|
|
2490
3524
|
/**
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
3525
|
+
* Get the unique edge from `src` to `dest`, if present.
|
|
3526
|
+
* @param srcOrKey - Source vertex or key.
|
|
3527
|
+
* @param destOrKey - Destination vertex or key.
|
|
3528
|
+
* @returns Edge instance or `undefined`.
|
|
3529
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3530
|
+
|
|
3531
|
+
|
|
3532
|
+
|
|
3533
|
+
|
|
3534
|
+
|
|
3535
|
+
|
|
3536
|
+
|
|
3537
|
+
|
|
3538
|
+
|
|
3539
|
+
|
|
3540
|
+
|
|
3541
|
+
|
|
3542
|
+
|
|
3543
|
+
|
|
3544
|
+
|
|
3545
|
+
|
|
3546
|
+
|
|
3547
|
+
|
|
3548
|
+
|
|
3549
|
+
|
|
3550
|
+
|
|
3551
|
+
|
|
3552
|
+
|
|
3553
|
+
|
|
3554
|
+
|
|
3555
|
+
|
|
3556
|
+
|
|
3557
|
+
|
|
3558
|
+
|
|
3559
|
+
* @example
|
|
3560
|
+
* // Get edge between vertices
|
|
3561
|
+
* const g = new DirectedGraph();
|
|
3562
|
+
* g.addVertex('A');
|
|
3563
|
+
* g.addVertex('B');
|
|
3564
|
+
* g.addEdge('A', 'B', 5);
|
|
3565
|
+
* const edge = g.getEdge('A', 'B');
|
|
3566
|
+
* console.log(edge?.weight); // 5;
|
|
3567
|
+
*/
|
|
2497
3568
|
getEdge(srcOrKey, destOrKey) {
|
|
2498
3569
|
let edgeMap = [];
|
|
2499
3570
|
if (srcOrKey !== void 0 && destOrKey !== void 0) {
|
|
@@ -2533,12 +3604,69 @@ var graphTyped = (() => {
|
|
|
2533
3604
|
return removed;
|
|
2534
3605
|
}
|
|
2535
3606
|
/**
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
3607
|
+
* Delete an edge by instance or by `(srcKey, destKey)`.
|
|
3608
|
+
* @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
|
|
3609
|
+
* @param destVertexKey - Optional destination vertex/key when deleting by pair.
|
|
3610
|
+
* @returns Removed edge or `undefined`.
|
|
3611
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3612
|
+
|
|
3613
|
+
|
|
3614
|
+
|
|
3615
|
+
|
|
3616
|
+
|
|
3617
|
+
|
|
3618
|
+
|
|
3619
|
+
|
|
3620
|
+
|
|
3621
|
+
|
|
3622
|
+
|
|
3623
|
+
|
|
3624
|
+
|
|
3625
|
+
|
|
3626
|
+
|
|
3627
|
+
|
|
3628
|
+
|
|
3629
|
+
|
|
3630
|
+
|
|
3631
|
+
|
|
3632
|
+
|
|
3633
|
+
|
|
3634
|
+
|
|
3635
|
+
|
|
3636
|
+
|
|
3637
|
+
|
|
3638
|
+
|
|
3639
|
+
|
|
3640
|
+
|
|
3641
|
+
|
|
3642
|
+
|
|
3643
|
+
|
|
3644
|
+
* @example
|
|
3645
|
+
* // DirectedGraph deleteEdge and vertex operations
|
|
3646
|
+
* const graph = new DirectedGraph<string>();
|
|
3647
|
+
*
|
|
3648
|
+
* // Build a small graph
|
|
3649
|
+
* graph.addVertex('X');
|
|
3650
|
+
* graph.addVertex('Y');
|
|
3651
|
+
* graph.addVertex('Z');
|
|
3652
|
+
* graph.addEdge('X', 'Y', 1);
|
|
3653
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
3654
|
+
*
|
|
3655
|
+
* // Delete an edge
|
|
3656
|
+
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
3657
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
3658
|
+
*
|
|
3659
|
+
* // Edge in other direction should not exist
|
|
3660
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
3661
|
+
*
|
|
3662
|
+
* // Other edges should remain
|
|
3663
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
3664
|
+
*
|
|
3665
|
+
* // Delete a vertex
|
|
3666
|
+
* graph.deleteVertex('Y');
|
|
3667
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
3668
|
+
* console.log(graph.size); // 2;
|
|
3669
|
+
*/
|
|
2542
3670
|
deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
|
|
2543
3671
|
let removed = void 0;
|
|
2544
3672
|
let src, dest;
|
|
@@ -2565,6 +3693,47 @@ var graphTyped = (() => {
|
|
|
2565
3693
|
}
|
|
2566
3694
|
return removed;
|
|
2567
3695
|
}
|
|
3696
|
+
/**
|
|
3697
|
+
* Remove a vertex
|
|
3698
|
+
|
|
3699
|
+
|
|
3700
|
+
|
|
3701
|
+
|
|
3702
|
+
|
|
3703
|
+
|
|
3704
|
+
|
|
3705
|
+
|
|
3706
|
+
|
|
3707
|
+
|
|
3708
|
+
|
|
3709
|
+
|
|
3710
|
+
|
|
3711
|
+
|
|
3712
|
+
|
|
3713
|
+
|
|
3714
|
+
|
|
3715
|
+
|
|
3716
|
+
|
|
3717
|
+
|
|
3718
|
+
|
|
3719
|
+
|
|
3720
|
+
|
|
3721
|
+
|
|
3722
|
+
|
|
3723
|
+
|
|
3724
|
+
|
|
3725
|
+
|
|
3726
|
+
|
|
3727
|
+
* @example
|
|
3728
|
+
* // Remove a vertex
|
|
3729
|
+
* const g = new DirectedGraph();
|
|
3730
|
+
* g.addVertex('A');
|
|
3731
|
+
* g.addVertex('B');
|
|
3732
|
+
* g.addEdge('A', 'B');
|
|
3733
|
+
* g.deleteVertex('A');
|
|
3734
|
+
* console.log(g.hasVertex('A')); // false;
|
|
3735
|
+
* console.log(g.hasEdge('A', 'B')); // false;
|
|
3736
|
+
*/
|
|
2568
3737
|
deleteVertex(vertexOrKey) {
|
|
2569
3738
|
let vertexKey;
|
|
2570
3739
|
let vertex;
|
|
@@ -2596,11 +3765,49 @@ var graphTyped = (() => {
|
|
|
2596
3765
|
return removed;
|
|
2597
3766
|
}
|
|
2598
3767
|
/**
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
3768
|
+
* Incoming edges of a vertex.
|
|
3769
|
+
* @param vertexOrKey - Vertex or key.
|
|
3770
|
+
* @returns Array of incoming edges.
|
|
3771
|
+
* @remarks Time O(deg_in), Space O(deg_in)
|
|
3772
|
+
|
|
3773
|
+
|
|
3774
|
+
|
|
3775
|
+
|
|
3776
|
+
|
|
3777
|
+
|
|
3778
|
+
|
|
3779
|
+
|
|
3780
|
+
|
|
3781
|
+
|
|
3782
|
+
|
|
3783
|
+
|
|
3784
|
+
|
|
3785
|
+
|
|
3786
|
+
|
|
3787
|
+
|
|
3788
|
+
|
|
3789
|
+
|
|
3790
|
+
|
|
3791
|
+
|
|
3792
|
+
|
|
3793
|
+
|
|
3794
|
+
|
|
3795
|
+
|
|
3796
|
+
|
|
3797
|
+
|
|
3798
|
+
|
|
3799
|
+
|
|
3800
|
+
|
|
3801
|
+
* @example
|
|
3802
|
+
* // Get incoming edges
|
|
3803
|
+
* const g = new DirectedGraph();
|
|
3804
|
+
* g.addVertex('A');
|
|
3805
|
+
* g.addVertex('B');
|
|
3806
|
+
* g.addVertex('C');
|
|
3807
|
+
* g.addEdge('A', 'C');
|
|
3808
|
+
* g.addEdge('B', 'C');
|
|
3809
|
+
* console.log(g.incomingEdgesOf('C').length); // 2;
|
|
3810
|
+
*/
|
|
2604
3811
|
incomingEdgesOf(vertexOrKey) {
|
|
2605
3812
|
const target = this._getVertex(vertexOrKey);
|
|
2606
3813
|
if (target) {
|
|
@@ -2609,11 +3816,49 @@ var graphTyped = (() => {
|
|
|
2609
3816
|
return [];
|
|
2610
3817
|
}
|
|
2611
3818
|
/**
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
3819
|
+
* Outgoing edges of a vertex.
|
|
3820
|
+
* @param vertexOrKey - Vertex or key.
|
|
3821
|
+
* @returns Array of outgoing edges.
|
|
3822
|
+
* @remarks Time O(deg_out), Space O(deg_out)
|
|
3823
|
+
|
|
3824
|
+
|
|
3825
|
+
|
|
3826
|
+
|
|
3827
|
+
|
|
3828
|
+
|
|
3829
|
+
|
|
3830
|
+
|
|
3831
|
+
|
|
3832
|
+
|
|
3833
|
+
|
|
3834
|
+
|
|
3835
|
+
|
|
3836
|
+
|
|
3837
|
+
|
|
3838
|
+
|
|
3839
|
+
|
|
3840
|
+
|
|
3841
|
+
|
|
3842
|
+
|
|
3843
|
+
|
|
3844
|
+
|
|
3845
|
+
|
|
3846
|
+
|
|
3847
|
+
|
|
3848
|
+
|
|
3849
|
+
|
|
3850
|
+
|
|
3851
|
+
|
|
3852
|
+
* @example
|
|
3853
|
+
* // Get outgoing edges
|
|
3854
|
+
* const g = new DirectedGraph();
|
|
3855
|
+
* g.addVertex('A');
|
|
3856
|
+
* g.addVertex('B');
|
|
3857
|
+
* g.addVertex('C');
|
|
3858
|
+
* g.addEdge('A', 'B');
|
|
3859
|
+
* g.addEdge('A', 'C');
|
|
3860
|
+
* console.log(g.outgoingEdgesOf('A').length); // 2;
|
|
3861
|
+
*/
|
|
2617
3862
|
outgoingEdgesOf(vertexOrKey) {
|
|
2618
3863
|
const target = this._getVertex(vertexOrKey);
|
|
2619
3864
|
if (target) {
|
|
@@ -2672,11 +3917,65 @@ var graphTyped = (() => {
|
|
|
2672
3917
|
return destinations;
|
|
2673
3918
|
}
|
|
2674
3919
|
/**
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
3920
|
+
* Topological sort if DAG; returns `undefined` if a cycle exists.
|
|
3921
|
+
* @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
|
|
3922
|
+
* @returns Array of keys/vertices, or `undefined` when cycle is found.
|
|
3923
|
+
* @remarks Time O(V + E), Space O(V)
|
|
3924
|
+
|
|
3925
|
+
|
|
3926
|
+
|
|
3927
|
+
|
|
3928
|
+
|
|
3929
|
+
|
|
3930
|
+
|
|
3931
|
+
|
|
3932
|
+
|
|
3933
|
+
|
|
3934
|
+
|
|
3935
|
+
|
|
3936
|
+
|
|
3937
|
+
|
|
3938
|
+
|
|
3939
|
+
|
|
3940
|
+
|
|
3941
|
+
|
|
3942
|
+
|
|
3943
|
+
|
|
3944
|
+
|
|
3945
|
+
|
|
3946
|
+
|
|
3947
|
+
|
|
3948
|
+
|
|
3949
|
+
|
|
3950
|
+
|
|
3951
|
+
|
|
3952
|
+
|
|
3953
|
+
|
|
3954
|
+
|
|
3955
|
+
|
|
3956
|
+
* @example
|
|
3957
|
+
* // DirectedGraph topologicalSort for task scheduling
|
|
3958
|
+
* const graph = new DirectedGraph<string>();
|
|
3959
|
+
*
|
|
3960
|
+
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
3961
|
+
* graph.addVertex('Design');
|
|
3962
|
+
* graph.addVertex('Implement');
|
|
3963
|
+
* graph.addVertex('Test');
|
|
3964
|
+
* graph.addVertex('Deploy');
|
|
3965
|
+
*
|
|
3966
|
+
* // Add dependency edges
|
|
3967
|
+
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
3968
|
+
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
3969
|
+
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
3970
|
+
*
|
|
3971
|
+
* // Topological sort gives valid execution order
|
|
3972
|
+
* const executionOrder = graph.topologicalSort();
|
|
3973
|
+
* console.log(executionOrder); // defined;
|
|
3974
|
+
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
3975
|
+
*
|
|
3976
|
+
* // All vertices should be included
|
|
3977
|
+
* console.log(executionOrder?.length); // 4;
|
|
3978
|
+
*/
|
|
2680
3979
|
topologicalSort(propertyName) {
|
|
2681
3980
|
propertyName = propertyName != null ? propertyName : "key";
|
|
2682
3981
|
const statusMap = /* @__PURE__ */ new Map();
|
|
@@ -2708,6 +4007,45 @@ var graphTyped = (() => {
|
|
|
2708
4007
|
if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
|
|
2709
4008
|
return sorted.reverse();
|
|
2710
4009
|
}
|
|
4010
|
+
/**
|
|
4011
|
+
* Get all edges
|
|
4012
|
+
|
|
4013
|
+
|
|
4014
|
+
|
|
4015
|
+
|
|
4016
|
+
|
|
4017
|
+
|
|
4018
|
+
|
|
4019
|
+
|
|
4020
|
+
|
|
4021
|
+
|
|
4022
|
+
|
|
4023
|
+
|
|
4024
|
+
|
|
4025
|
+
|
|
4026
|
+
|
|
4027
|
+
|
|
4028
|
+
|
|
4029
|
+
|
|
4030
|
+
|
|
4031
|
+
|
|
4032
|
+
|
|
4033
|
+
|
|
4034
|
+
|
|
4035
|
+
|
|
4036
|
+
|
|
4037
|
+
|
|
4038
|
+
|
|
4039
|
+
|
|
4040
|
+
|
|
4041
|
+
* @example
|
|
4042
|
+
* // Get all edges
|
|
4043
|
+
* const g = new DirectedGraph();
|
|
4044
|
+
* g.addVertex('A');
|
|
4045
|
+
* g.addVertex('B');
|
|
4046
|
+
* g.addEdge('A', 'B', 3);
|
|
4047
|
+
* console.log(g.edgeSet().length); // 1;
|
|
4048
|
+
*/
|
|
2711
4049
|
edgeSet() {
|
|
2712
4050
|
let edgeMap = [];
|
|
2713
4051
|
this._outEdgeMap.forEach((outEdges) => {
|
|
@@ -2715,6 +4053,49 @@ var graphTyped = (() => {
|
|
|
2715
4053
|
});
|
|
2716
4054
|
return edgeMap;
|
|
2717
4055
|
}
|
|
4056
|
+
/**
|
|
4057
|
+
* Get outgoing neighbors
|
|
4058
|
+
|
|
4059
|
+
|
|
4060
|
+
|
|
4061
|
+
|
|
4062
|
+
|
|
4063
|
+
|
|
4064
|
+
|
|
4065
|
+
|
|
4066
|
+
|
|
4067
|
+
|
|
4068
|
+
|
|
4069
|
+
|
|
4070
|
+
|
|
4071
|
+
|
|
4072
|
+
|
|
4073
|
+
|
|
4074
|
+
|
|
4075
|
+
|
|
4076
|
+
|
|
4077
|
+
|
|
4078
|
+
|
|
4079
|
+
|
|
4080
|
+
|
|
4081
|
+
|
|
4082
|
+
|
|
4083
|
+
|
|
4084
|
+
|
|
4085
|
+
|
|
4086
|
+
|
|
4087
|
+
|
|
4088
|
+
* @example
|
|
4089
|
+
* // Get outgoing neighbors
|
|
4090
|
+
* const g = new DirectedGraph();
|
|
4091
|
+
* g.addVertex('A');
|
|
4092
|
+
* g.addVertex('B');
|
|
4093
|
+
* g.addVertex('C');
|
|
4094
|
+
* g.addEdge('A', 'B');
|
|
4095
|
+
* g.addEdge('A', 'C');
|
|
4096
|
+
* const neighbors = g.getNeighbors('A');
|
|
4097
|
+
* console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
|
|
4098
|
+
*/
|
|
2718
4099
|
getNeighbors(vertexOrKey) {
|
|
2719
4100
|
const neighbors = [];
|
|
2720
4101
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -2772,10 +4153,52 @@ var graphTyped = (() => {
|
|
|
2772
4153
|
return super.clone();
|
|
2773
4154
|
}
|
|
2774
4155
|
/**
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
4156
|
+
* Tarjan's algorithm for strongly connected components.
|
|
4157
|
+
* @returns `{ dfnMap, lowMap, SCCs }`.
|
|
4158
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
4159
|
+
|
|
4160
|
+
|
|
4161
|
+
|
|
4162
|
+
|
|
4163
|
+
|
|
4164
|
+
|
|
4165
|
+
|
|
4166
|
+
|
|
4167
|
+
|
|
4168
|
+
|
|
4169
|
+
|
|
4170
|
+
|
|
4171
|
+
|
|
4172
|
+
|
|
4173
|
+
|
|
4174
|
+
|
|
4175
|
+
|
|
4176
|
+
|
|
4177
|
+
|
|
4178
|
+
|
|
4179
|
+
|
|
4180
|
+
|
|
4181
|
+
|
|
4182
|
+
|
|
4183
|
+
|
|
4184
|
+
|
|
4185
|
+
|
|
4186
|
+
|
|
4187
|
+
|
|
4188
|
+
* @example
|
|
4189
|
+
* // Find strongly connected components
|
|
4190
|
+
* const g = new DirectedGraph();
|
|
4191
|
+
* g.addVertex('A');
|
|
4192
|
+
* g.addVertex('B');
|
|
4193
|
+
* g.addVertex('C');
|
|
4194
|
+
* g.addEdge('A', 'B');
|
|
4195
|
+
* g.addEdge('B', 'C');
|
|
4196
|
+
* g.addEdge('C', 'A');
|
|
4197
|
+
* const { SCCs } = g.tarjan();
|
|
4198
|
+
* // A→B→C→A forms one SCC with 3 members
|
|
4199
|
+
* const sccArrays = [...SCCs.values()];
|
|
4200
|
+
* console.log(sccArrays.some(scc => scc.length === 3)); // true;
|
|
4201
|
+
*/
|
|
2779
4202
|
tarjan() {
|
|
2780
4203
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
2781
4204
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -2833,10 +4256,50 @@ var graphTyped = (() => {
|
|
|
2833
4256
|
return this.tarjan().lowMap;
|
|
2834
4257
|
}
|
|
2835
4258
|
/**
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
4259
|
+
* Strongly connected components computed by `tarjan()`.
|
|
4260
|
+
* @returns Map from SCC id to vertices.
|
|
4261
|
+
* @remarks Time O(#SCC + V), Space O(V)
|
|
4262
|
+
|
|
4263
|
+
|
|
4264
|
+
|
|
4265
|
+
|
|
4266
|
+
|
|
4267
|
+
|
|
4268
|
+
|
|
4269
|
+
|
|
4270
|
+
|
|
4271
|
+
|
|
4272
|
+
|
|
4273
|
+
|
|
4274
|
+
|
|
4275
|
+
|
|
4276
|
+
|
|
4277
|
+
|
|
4278
|
+
|
|
4279
|
+
|
|
4280
|
+
|
|
4281
|
+
|
|
4282
|
+
|
|
4283
|
+
|
|
4284
|
+
|
|
4285
|
+
|
|
4286
|
+
|
|
4287
|
+
|
|
4288
|
+
|
|
4289
|
+
|
|
4290
|
+
|
|
4291
|
+
* @example
|
|
4292
|
+
* // Get strongly connected components
|
|
4293
|
+
* const g = new DirectedGraph();
|
|
4294
|
+
* g.addVertex(1);
|
|
4295
|
+
* g.addVertex(2);
|
|
4296
|
+
* g.addVertex(3);
|
|
4297
|
+
* g.addEdge(1, 2);
|
|
4298
|
+
* g.addEdge(2, 3);
|
|
4299
|
+
* g.addEdge(3, 1);
|
|
4300
|
+
* const sccs = g.getSCCs(); // Map<number, VO[]>
|
|
4301
|
+
* console.log(sccs.size); // >= 1;
|
|
4302
|
+
*/
|
|
2840
4303
|
getSCCs() {
|
|
2841
4304
|
return this.tarjan().SCCs;
|
|
2842
4305
|
}
|
|
@@ -2952,12 +4415,48 @@ var graphTyped = (() => {
|
|
|
2952
4415
|
return new UndirectedEdge(v1, v2, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
|
|
2953
4416
|
}
|
|
2954
4417
|
/**
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
4418
|
+
* Get an undirected edge between two vertices, if present.
|
|
4419
|
+
* @param v1 - One vertex or key.
|
|
4420
|
+
* @param v2 - The other vertex or key.
|
|
4421
|
+
* @returns Edge instance or `undefined`.
|
|
4422
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
4423
|
+
|
|
4424
|
+
|
|
4425
|
+
|
|
4426
|
+
|
|
4427
|
+
|
|
4428
|
+
|
|
4429
|
+
|
|
4430
|
+
|
|
4431
|
+
|
|
4432
|
+
|
|
4433
|
+
|
|
4434
|
+
|
|
4435
|
+
|
|
4436
|
+
|
|
4437
|
+
|
|
4438
|
+
|
|
4439
|
+
|
|
4440
|
+
|
|
4441
|
+
|
|
4442
|
+
|
|
4443
|
+
|
|
4444
|
+
|
|
4445
|
+
|
|
4446
|
+
|
|
4447
|
+
|
|
4448
|
+
|
|
4449
|
+
|
|
4450
|
+
|
|
4451
|
+
|
|
4452
|
+
* @example
|
|
4453
|
+
* // Get edge between vertices
|
|
4454
|
+
* const g = new UndirectedGraph();
|
|
4455
|
+
* g.addVertex('A');
|
|
4456
|
+
* g.addVertex('B');
|
|
4457
|
+
* g.addEdge('A', 'B', 7);
|
|
4458
|
+
* console.log(g.getEdge('A', 'B')?.weight); // 7;
|
|
4459
|
+
*/
|
|
2961
4460
|
getEdge(v1, v2) {
|
|
2962
4461
|
var _a;
|
|
2963
4462
|
let edgeMap = [];
|
|
@@ -2995,12 +4494,71 @@ var graphTyped = (() => {
|
|
|
2995
4494
|
return removed;
|
|
2996
4495
|
}
|
|
2997
4496
|
/**
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
4497
|
+
* Delete an edge by instance or by a pair of keys.
|
|
4498
|
+
* @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
|
|
4499
|
+
* @param otherSideVertexKey - Required second endpoint when deleting by pair.
|
|
4500
|
+
* @returns Removed edge or `undefined`.
|
|
4501
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
4502
|
+
|
|
4503
|
+
|
|
4504
|
+
|
|
4505
|
+
|
|
4506
|
+
|
|
4507
|
+
|
|
4508
|
+
|
|
4509
|
+
|
|
4510
|
+
|
|
4511
|
+
|
|
4512
|
+
|
|
4513
|
+
|
|
4514
|
+
|
|
4515
|
+
|
|
4516
|
+
|
|
4517
|
+
|
|
4518
|
+
|
|
4519
|
+
|
|
4520
|
+
|
|
4521
|
+
|
|
4522
|
+
|
|
4523
|
+
|
|
4524
|
+
|
|
4525
|
+
|
|
4526
|
+
|
|
4527
|
+
|
|
4528
|
+
|
|
4529
|
+
|
|
4530
|
+
|
|
4531
|
+
|
|
4532
|
+
|
|
4533
|
+
|
|
4534
|
+
* @example
|
|
4535
|
+
* // UndirectedGraph deleteEdge and vertex operations
|
|
4536
|
+
* const graph = new UndirectedGraph<string>();
|
|
4537
|
+
*
|
|
4538
|
+
* // Build a simple undirected graph
|
|
4539
|
+
* graph.addVertex('X');
|
|
4540
|
+
* graph.addVertex('Y');
|
|
4541
|
+
* graph.addVertex('Z');
|
|
4542
|
+
* graph.addEdge('X', 'Y', 1);
|
|
4543
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
4544
|
+
* graph.addEdge('X', 'Z', 3);
|
|
4545
|
+
*
|
|
4546
|
+
* // Delete an edge
|
|
4547
|
+
* graph.deleteEdge('X', 'Y');
|
|
4548
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
4549
|
+
*
|
|
4550
|
+
* // Bidirectional deletion confirmed
|
|
4551
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
4552
|
+
*
|
|
4553
|
+
* // Other edges should remain
|
|
4554
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
4555
|
+
* console.log(graph.hasEdge('Z', 'Y')); // true;
|
|
4556
|
+
*
|
|
4557
|
+
* // Delete a vertex
|
|
4558
|
+
* graph.deleteVertex('Y');
|
|
4559
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
4560
|
+
* console.log(graph.size); // 2;
|
|
4561
|
+
*/
|
|
3004
4562
|
deleteEdge(edgeOrOneSideVertexKey, otherSideVertexKey) {
|
|
3005
4563
|
let oneSide, otherSide;
|
|
3006
4564
|
if (this.isVertexKey(edgeOrOneSideVertexKey)) {
|
|
@@ -3021,11 +4579,48 @@ var graphTyped = (() => {
|
|
|
3021
4579
|
}
|
|
3022
4580
|
}
|
|
3023
4581
|
/**
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
4582
|
+
* Delete a vertex and remove it from all neighbor lists.
|
|
4583
|
+
* @param vertexOrKey - Vertex or key.
|
|
4584
|
+
* @returns `true` if removed; otherwise `false`.
|
|
4585
|
+
* @remarks Time O(deg), Space O(1)
|
|
4586
|
+
|
|
4587
|
+
|
|
4588
|
+
|
|
4589
|
+
|
|
4590
|
+
|
|
4591
|
+
|
|
4592
|
+
|
|
4593
|
+
|
|
4594
|
+
|
|
4595
|
+
|
|
4596
|
+
|
|
4597
|
+
|
|
4598
|
+
|
|
4599
|
+
|
|
4600
|
+
|
|
4601
|
+
|
|
4602
|
+
|
|
4603
|
+
|
|
4604
|
+
|
|
4605
|
+
|
|
4606
|
+
|
|
4607
|
+
|
|
4608
|
+
|
|
4609
|
+
|
|
4610
|
+
|
|
4611
|
+
|
|
4612
|
+
|
|
4613
|
+
|
|
4614
|
+
|
|
4615
|
+
* @example
|
|
4616
|
+
* // Remove vertex and edges
|
|
4617
|
+
* const g = new UndirectedGraph();
|
|
4618
|
+
* g.addVertex('A');
|
|
4619
|
+
* g.addVertex('B');
|
|
4620
|
+
* g.addEdge('A', 'B');
|
|
4621
|
+
* g.deleteVertex('A');
|
|
4622
|
+
* console.log(g.hasVertex('A')); // false;
|
|
4623
|
+
*/
|
|
3029
4624
|
deleteVertex(vertexOrKey) {
|
|
3030
4625
|
let vertexKey;
|
|
3031
4626
|
let vertex;
|
|
@@ -3081,10 +4676,46 @@ var graphTyped = (() => {
|
|
|
3081
4676
|
}
|
|
3082
4677
|
}
|
|
3083
4678
|
/**
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
4679
|
+
* Unique set of undirected edges across endpoints.
|
|
4680
|
+
* @returns Array of edges.
|
|
4681
|
+
* @remarks Time O(E), Space O(E)
|
|
4682
|
+
|
|
4683
|
+
|
|
4684
|
+
|
|
4685
|
+
|
|
4686
|
+
|
|
4687
|
+
|
|
4688
|
+
|
|
4689
|
+
|
|
4690
|
+
|
|
4691
|
+
|
|
4692
|
+
|
|
4693
|
+
|
|
4694
|
+
|
|
4695
|
+
|
|
4696
|
+
|
|
4697
|
+
|
|
4698
|
+
|
|
4699
|
+
|
|
4700
|
+
|
|
4701
|
+
|
|
4702
|
+
|
|
4703
|
+
|
|
4704
|
+
|
|
4705
|
+
|
|
4706
|
+
|
|
4707
|
+
|
|
4708
|
+
|
|
4709
|
+
|
|
4710
|
+
|
|
4711
|
+
* @example
|
|
4712
|
+
* // Get all edges
|
|
4713
|
+
* const g = new UndirectedGraph();
|
|
4714
|
+
* g.addVertex('A');
|
|
4715
|
+
* g.addVertex('B');
|
|
4716
|
+
* g.addEdge('A', 'B');
|
|
4717
|
+
* console.log(g.edgeSet().length); // 1;
|
|
4718
|
+
*/
|
|
3088
4719
|
edgeSet() {
|
|
3089
4720
|
const edgeSet = /* @__PURE__ */ new Set();
|
|
3090
4721
|
this._edgeMap.forEach((edgeMap) => {
|
|
@@ -3094,6 +4725,73 @@ var graphTyped = (() => {
|
|
|
3094
4725
|
});
|
|
3095
4726
|
return [...edgeSet];
|
|
3096
4727
|
}
|
|
4728
|
+
/**
|
|
4729
|
+
* UndirectedGraph connectivity and neighbors
|
|
4730
|
+
|
|
4731
|
+
|
|
4732
|
+
|
|
4733
|
+
|
|
4734
|
+
|
|
4735
|
+
|
|
4736
|
+
|
|
4737
|
+
|
|
4738
|
+
|
|
4739
|
+
|
|
4740
|
+
|
|
4741
|
+
|
|
4742
|
+
|
|
4743
|
+
|
|
4744
|
+
|
|
4745
|
+
|
|
4746
|
+
|
|
4747
|
+
|
|
4748
|
+
|
|
4749
|
+
|
|
4750
|
+
|
|
4751
|
+
|
|
4752
|
+
|
|
4753
|
+
|
|
4754
|
+
|
|
4755
|
+
|
|
4756
|
+
|
|
4757
|
+
|
|
4758
|
+
|
|
4759
|
+
|
|
4760
|
+
|
|
4761
|
+
|
|
4762
|
+
* @example
|
|
4763
|
+
* // UndirectedGraph connectivity and neighbors
|
|
4764
|
+
* const graph = new UndirectedGraph<string>();
|
|
4765
|
+
*
|
|
4766
|
+
* // Build a friendship network
|
|
4767
|
+
* const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
|
|
4768
|
+
* for (const person of people) {
|
|
4769
|
+
* graph.addVertex(person);
|
|
4770
|
+
* }
|
|
4771
|
+
*
|
|
4772
|
+
* // Add friendships (undirected edges)
|
|
4773
|
+
* graph.addEdge('Alice', 'Bob', 1);
|
|
4774
|
+
* graph.addEdge('Alice', 'Charlie', 1);
|
|
4775
|
+
* graph.addEdge('Bob', 'Diana', 1);
|
|
4776
|
+
* graph.addEdge('Charlie', 'Eve', 1);
|
|
4777
|
+
* graph.addEdge('Diana', 'Eve', 1);
|
|
4778
|
+
*
|
|
4779
|
+
* // Get friends of each person
|
|
4780
|
+
* const aliceFriends = graph.getNeighbors('Alice');
|
|
4781
|
+
* console.log(aliceFriends[0].key); // 'Bob';
|
|
4782
|
+
* console.log(aliceFriends[1].key); // 'Charlie';
|
|
4783
|
+
* console.log(aliceFriends.length); // 2;
|
|
4784
|
+
*
|
|
4785
|
+
* const dianaFriends = graph.getNeighbors('Diana');
|
|
4786
|
+
* console.log(dianaFriends[0].key); // 'Bob';
|
|
4787
|
+
* console.log(dianaFriends[1].key); // 'Eve';
|
|
4788
|
+
* console.log(dianaFriends.length); // 2;
|
|
4789
|
+
*
|
|
4790
|
+
* // Verify bidirectional friendship
|
|
4791
|
+
* const bobFriends = graph.getNeighbors('Bob');
|
|
4792
|
+
* console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
|
|
4793
|
+
* console.log(bobFriends[1].key); // 'Diana';
|
|
4794
|
+
*/
|
|
3097
4795
|
getNeighbors(vertexOrKey) {
|
|
3098
4796
|
const neighbors = [];
|
|
3099
4797
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -3150,10 +4848,49 @@ var graphTyped = (() => {
|
|
|
3150
4848
|
return super.clone();
|
|
3151
4849
|
}
|
|
3152
4850
|
/**
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
4851
|
+
* Tarjan-based bridge and articulation point detection.
|
|
4852
|
+
* @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
|
|
4853
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
4854
|
+
|
|
4855
|
+
|
|
4856
|
+
|
|
4857
|
+
|
|
4858
|
+
|
|
4859
|
+
|
|
4860
|
+
|
|
4861
|
+
|
|
4862
|
+
|
|
4863
|
+
|
|
4864
|
+
|
|
4865
|
+
|
|
4866
|
+
|
|
4867
|
+
|
|
4868
|
+
|
|
4869
|
+
|
|
4870
|
+
|
|
4871
|
+
|
|
4872
|
+
|
|
4873
|
+
|
|
4874
|
+
|
|
4875
|
+
|
|
4876
|
+
|
|
4877
|
+
|
|
4878
|
+
|
|
4879
|
+
|
|
4880
|
+
|
|
4881
|
+
|
|
4882
|
+
|
|
4883
|
+
* @example
|
|
4884
|
+
* // Find articulation points and bridges
|
|
4885
|
+
* const g = new UndirectedGraph();
|
|
4886
|
+
* g.addVertex('A');
|
|
4887
|
+
* g.addVertex('B');
|
|
4888
|
+
* g.addVertex('C');
|
|
4889
|
+
* g.addEdge('A', 'B');
|
|
4890
|
+
* g.addEdge('B', 'C');
|
|
4891
|
+
* const result = g.tarjan();
|
|
4892
|
+
* console.log(result); // defined;
|
|
4893
|
+
*/
|
|
3157
4894
|
tarjan() {
|
|
3158
4895
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
3159
4896
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -3253,11 +4990,51 @@ var graphTyped = (() => {
|
|
|
3253
4990
|
return components;
|
|
3254
4991
|
}
|
|
3255
4992
|
/**
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
4993
|
+
* Detect whether the graph contains a cycle.
|
|
4994
|
+
* Uses DFS with parent tracking.
|
|
4995
|
+
* @returns `true` if a cycle exists, `false` otherwise.
|
|
4996
|
+
* @remarks Time O(V + E), Space O(V)
|
|
4997
|
+
|
|
4998
|
+
|
|
4999
|
+
|
|
5000
|
+
|
|
5001
|
+
|
|
5002
|
+
|
|
5003
|
+
|
|
5004
|
+
|
|
5005
|
+
|
|
5006
|
+
|
|
5007
|
+
|
|
5008
|
+
|
|
5009
|
+
|
|
5010
|
+
|
|
5011
|
+
|
|
5012
|
+
|
|
5013
|
+
|
|
5014
|
+
|
|
5015
|
+
|
|
5016
|
+
|
|
5017
|
+
|
|
5018
|
+
|
|
5019
|
+
|
|
5020
|
+
|
|
5021
|
+
|
|
5022
|
+
|
|
5023
|
+
|
|
5024
|
+
|
|
5025
|
+
|
|
5026
|
+
* @example
|
|
5027
|
+
* // Detect cycle
|
|
5028
|
+
* const g = new UndirectedGraph();
|
|
5029
|
+
* g.addVertex('A');
|
|
5030
|
+
* g.addVertex('B');
|
|
5031
|
+
* g.addVertex('C');
|
|
5032
|
+
* g.addEdge('A', 'B');
|
|
5033
|
+
* g.addEdge('B', 'C');
|
|
5034
|
+
* console.log(g.hasCycle()); // false;
|
|
5035
|
+
* g.addEdge('C', 'A');
|
|
5036
|
+
* console.log(g.hasCycle()); // true;
|
|
5037
|
+
*/
|
|
3261
5038
|
hasCycle() {
|
|
3262
5039
|
const visited = /* @__PURE__ */ new Set();
|
|
3263
5040
|
const dfs = (vertex, parent) => {
|
|
@@ -3279,18 +5056,97 @@ var graphTyped = (() => {
|
|
|
3279
5056
|
return false;
|
|
3280
5057
|
}
|
|
3281
5058
|
/**
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
5059
|
+
* Get bridges discovered by `tarjan()`.
|
|
5060
|
+
* @returns Array of edges that are bridges.
|
|
5061
|
+
* @remarks Time O(B), Space O(1)
|
|
5062
|
+
|
|
5063
|
+
|
|
5064
|
+
|
|
5065
|
+
|
|
5066
|
+
|
|
5067
|
+
|
|
5068
|
+
|
|
5069
|
+
|
|
5070
|
+
|
|
5071
|
+
|
|
5072
|
+
|
|
5073
|
+
|
|
5074
|
+
|
|
5075
|
+
|
|
5076
|
+
|
|
5077
|
+
|
|
5078
|
+
|
|
5079
|
+
|
|
5080
|
+
|
|
5081
|
+
|
|
5082
|
+
|
|
5083
|
+
|
|
5084
|
+
|
|
5085
|
+
|
|
5086
|
+
|
|
5087
|
+
|
|
5088
|
+
|
|
5089
|
+
|
|
5090
|
+
|
|
5091
|
+
* @example
|
|
5092
|
+
* // Find bridge edges
|
|
5093
|
+
* const g = new UndirectedGraph();
|
|
5094
|
+
* g.addVertex('A');
|
|
5095
|
+
* g.addVertex('B');
|
|
5096
|
+
* g.addVertex('C');
|
|
5097
|
+
* g.addEdge('A', 'B');
|
|
5098
|
+
* g.addEdge('B', 'C');
|
|
5099
|
+
* const bridges = g.getBridges();
|
|
5100
|
+
* console.log(bridges.length); // 2;
|
|
5101
|
+
*/
|
|
3286
5102
|
getBridges() {
|
|
3287
5103
|
return this.tarjan().bridges;
|
|
3288
5104
|
}
|
|
3289
5105
|
/**
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
5106
|
+
* Get articulation points discovered by `tarjan()`.
|
|
5107
|
+
* @returns Array of cut vertices.
|
|
5108
|
+
* @remarks Time O(C), Space O(1)
|
|
5109
|
+
|
|
5110
|
+
|
|
5111
|
+
|
|
5112
|
+
|
|
5113
|
+
|
|
5114
|
+
|
|
5115
|
+
|
|
5116
|
+
|
|
5117
|
+
|
|
5118
|
+
|
|
5119
|
+
|
|
5120
|
+
|
|
5121
|
+
|
|
5122
|
+
|
|
5123
|
+
|
|
5124
|
+
|
|
5125
|
+
|
|
5126
|
+
|
|
5127
|
+
|
|
5128
|
+
|
|
5129
|
+
|
|
5130
|
+
|
|
5131
|
+
|
|
5132
|
+
|
|
5133
|
+
|
|
5134
|
+
|
|
5135
|
+
|
|
5136
|
+
|
|
5137
|
+
|
|
5138
|
+
* @example
|
|
5139
|
+
* // Find articulation points
|
|
5140
|
+
* const g = new UndirectedGraph();
|
|
5141
|
+
* g.addVertex('A');
|
|
5142
|
+
* g.addVertex('B');
|
|
5143
|
+
* g.addVertex('C');
|
|
5144
|
+
* g.addEdge('A', 'B');
|
|
5145
|
+
* g.addEdge('B', 'C');
|
|
5146
|
+
* const cuts = g.getCutVertices();
|
|
5147
|
+
* console.log(cuts.length); // 1;
|
|
5148
|
+
* console.log(cuts[0].key); // 'B';
|
|
5149
|
+
*/
|
|
3294
5150
|
getCutVertices() {
|
|
3295
5151
|
return this.tarjan().cutVertices;
|
|
3296
5152
|
}
|