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
|
@@ -277,7 +277,7 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
277
277
|
if (options) {
|
|
278
278
|
const { toElementFn } = options;
|
|
279
279
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
280
|
-
else if (toElementFn) throw new TypeError(
|
|
280
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
281
281
|
}
|
|
282
282
|
}
|
|
283
283
|
/**
|
|
@@ -433,7 +433,7 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
433
433
|
acc = initialValue;
|
|
434
434
|
} else {
|
|
435
435
|
const first = iter.next();
|
|
436
|
-
if (first.done) throw new TypeError(
|
|
436
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
437
437
|
acc = first.value;
|
|
438
438
|
index = 1;
|
|
439
439
|
}
|
|
@@ -477,6 +477,198 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
477
477
|
__name(_IterableElementBase, "IterableElementBase");
|
|
478
478
|
var IterableElementBase = _IterableElementBase;
|
|
479
479
|
|
|
480
|
+
// src/data-structures/base/linear-base.ts
|
|
481
|
+
var _LinearBase = class _LinearBase extends IterableElementBase {
|
|
482
|
+
/**
|
|
483
|
+
* Construct a linear container with runtime options.
|
|
484
|
+
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
485
|
+
* @remarks Time O(1), Space O(1)
|
|
486
|
+
*/
|
|
487
|
+
constructor(options) {
|
|
488
|
+
super(options);
|
|
489
|
+
__publicField(this, "_maxLen", -1);
|
|
490
|
+
if (options) {
|
|
491
|
+
const { maxLen } = options;
|
|
492
|
+
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
497
|
+
* @returns Maximum allowed length.
|
|
498
|
+
* @remarks Time O(1), Space O(1)
|
|
499
|
+
*/
|
|
500
|
+
get maxLen() {
|
|
501
|
+
return this._maxLen;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* First index of a value from the left.
|
|
505
|
+
* @param searchElement - Value to match.
|
|
506
|
+
* @param fromIndex - Start position (supports negative index).
|
|
507
|
+
* @returns Index or `-1` if not found.
|
|
508
|
+
* @remarks Time O(n), Space O(1)
|
|
509
|
+
*/
|
|
510
|
+
indexOf(searchElement, fromIndex = 0) {
|
|
511
|
+
if (this.length === 0) return -1;
|
|
512
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
513
|
+
if (fromIndex < 0) fromIndex = 0;
|
|
514
|
+
for (let i = fromIndex; i < this.length; i++) {
|
|
515
|
+
const element = this.at(i);
|
|
516
|
+
if (element === searchElement) return i;
|
|
517
|
+
}
|
|
518
|
+
return -1;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Last index of a value from the right.
|
|
522
|
+
* @param searchElement - Value to match.
|
|
523
|
+
* @param fromIndex - Start position (supports negative index).
|
|
524
|
+
* @returns Index or `-1` if not found.
|
|
525
|
+
* @remarks Time O(n), Space O(1)
|
|
526
|
+
*/
|
|
527
|
+
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
528
|
+
if (this.length === 0) return -1;
|
|
529
|
+
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
530
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
531
|
+
for (let i = fromIndex; i >= 0; i--) {
|
|
532
|
+
const element = this.at(i);
|
|
533
|
+
if (element === searchElement) return i;
|
|
534
|
+
}
|
|
535
|
+
return -1;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Find the first index matching a predicate.
|
|
539
|
+
* @param predicate - `(element, index, self) => boolean`.
|
|
540
|
+
* @param thisArg - Optional `this` for callback.
|
|
541
|
+
* @returns Index or `-1`.
|
|
542
|
+
* @remarks Time O(n), Space O(1)
|
|
543
|
+
*/
|
|
544
|
+
findIndex(predicate, thisArg) {
|
|
545
|
+
for (let i = 0; i < this.length; i++) {
|
|
546
|
+
const item = this.at(i);
|
|
547
|
+
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
548
|
+
}
|
|
549
|
+
return -1;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Concatenate elements and/or containers.
|
|
553
|
+
* @param items - Elements or other containers.
|
|
554
|
+
* @returns New container with combined elements (`this` type).
|
|
555
|
+
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
556
|
+
*/
|
|
557
|
+
concat(...items) {
|
|
558
|
+
const newList = this.clone();
|
|
559
|
+
for (const item of items) {
|
|
560
|
+
if (item instanceof _LinearBase) {
|
|
561
|
+
newList.pushMany(item);
|
|
562
|
+
} else {
|
|
563
|
+
newList.push(item);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
return newList;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* In-place stable order via array sort semantics.
|
|
570
|
+
* @param compareFn - Comparator `(a, b) => number`.
|
|
571
|
+
* @returns This container.
|
|
572
|
+
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
573
|
+
*/
|
|
574
|
+
sort(compareFn) {
|
|
575
|
+
const arr = this.toArray();
|
|
576
|
+
arr.sort(compareFn);
|
|
577
|
+
this.clear();
|
|
578
|
+
for (const item of arr) this.push(item);
|
|
579
|
+
return this;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Remove and/or insert elements at a position (array-compatible).
|
|
583
|
+
* @param start - Start index (supports negative index).
|
|
584
|
+
* @param deleteCount - How many to remove.
|
|
585
|
+
* @param items - Elements to insert.
|
|
586
|
+
* @returns Removed elements as a new list (`this` type).
|
|
587
|
+
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
588
|
+
*/
|
|
589
|
+
splice(start, deleteCount = 0, ...items) {
|
|
590
|
+
const removedList = this._createInstance();
|
|
591
|
+
start = start < 0 ? this.length + start : start;
|
|
592
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
593
|
+
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
594
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
595
|
+
const removed = this.deleteAt(start);
|
|
596
|
+
if (removed !== void 0) {
|
|
597
|
+
removedList.push(removed);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
for (let i = 0; i < items.length; i++) {
|
|
601
|
+
this.addAt(start + i, items[i]);
|
|
602
|
+
}
|
|
603
|
+
return removedList;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Join all elements into a string.
|
|
607
|
+
* @param separator - Separator string.
|
|
608
|
+
* @returns Concatenated string.
|
|
609
|
+
* @remarks Time O(n), Space O(n)
|
|
610
|
+
*/
|
|
611
|
+
join(separator = ",") {
|
|
612
|
+
return this.toArray().join(separator);
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Snapshot elements into a reversed array.
|
|
616
|
+
* @returns New reversed array.
|
|
617
|
+
* @remarks Time O(n), Space O(n)
|
|
618
|
+
*/
|
|
619
|
+
toReversedArray() {
|
|
620
|
+
const array = [];
|
|
621
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
622
|
+
array.push(this.at(i));
|
|
623
|
+
}
|
|
624
|
+
return array;
|
|
625
|
+
}
|
|
626
|
+
reduceRight(callbackfn, initialValue) {
|
|
627
|
+
let accumulator = initialValue != null ? initialValue : 0;
|
|
628
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
629
|
+
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
630
|
+
}
|
|
631
|
+
return accumulator;
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Create a shallow copy of a subrange.
|
|
635
|
+
* @param start - Inclusive start (supports negative index).
|
|
636
|
+
* @param end - Exclusive end (supports negative index).
|
|
637
|
+
* @returns New list with the range (`this` type).
|
|
638
|
+
* @remarks Time O(n), Space O(n)
|
|
639
|
+
*/
|
|
640
|
+
slice(start = 0, end = this.length) {
|
|
641
|
+
start = start < 0 ? this.length + start : start;
|
|
642
|
+
end = end < 0 ? this.length + end : end;
|
|
643
|
+
const newList = this._createInstance();
|
|
644
|
+
for (let i = start; i < end; i++) {
|
|
645
|
+
newList.push(this.at(i));
|
|
646
|
+
}
|
|
647
|
+
return newList;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Fill a range with a value.
|
|
651
|
+
* @param value - Value to set.
|
|
652
|
+
* @param start - Inclusive start.
|
|
653
|
+
* @param end - Exclusive end.
|
|
654
|
+
* @returns This list.
|
|
655
|
+
* @remarks Time O(n), Space O(1)
|
|
656
|
+
*/
|
|
657
|
+
fill(value, start = 0, end = this.length) {
|
|
658
|
+
start = start < 0 ? this.length + start : start;
|
|
659
|
+
end = end < 0 ? this.length + end : end;
|
|
660
|
+
if (start < 0) start = 0;
|
|
661
|
+
if (end > this.length) end = this.length;
|
|
662
|
+
if (start >= end) return this;
|
|
663
|
+
for (let i = start; i < end; i++) {
|
|
664
|
+
this.setAt(i, value);
|
|
665
|
+
}
|
|
666
|
+
return this;
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
__name(_LinearBase, "LinearBase");
|
|
670
|
+
var LinearBase = _LinearBase;
|
|
671
|
+
|
|
480
672
|
// src/data-structures/heap/heap.ts
|
|
481
673
|
var _Heap = class _Heap extends IterableElementBase {
|
|
482
674
|
/**
|
|
@@ -514,10 +706,51 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
514
706
|
return this._elements;
|
|
515
707
|
}
|
|
516
708
|
/**
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
709
|
+
* Get the number of elements.
|
|
710
|
+
* @remarks Time O(1), Space O(1)
|
|
711
|
+
* @returns Heap size.
|
|
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
|
+
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
* @example
|
|
745
|
+
* // Track heap capacity
|
|
746
|
+
* const heap = new Heap<number>();
|
|
747
|
+
* console.log(heap.size); // 0;
|
|
748
|
+
* heap.add(10);
|
|
749
|
+
* heap.add(20);
|
|
750
|
+
* console.log(heap.size); // 2;
|
|
751
|
+
* heap.poll();
|
|
752
|
+
* console.log(heap.size); // 1;
|
|
753
|
+
*/
|
|
521
754
|
get size() {
|
|
522
755
|
return this.elements.length;
|
|
523
756
|
}
|
|
@@ -556,21 +789,103 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
556
789
|
return new _Heap(elements, options);
|
|
557
790
|
}
|
|
558
791
|
/**
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
792
|
+
* Insert an element.
|
|
793
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
794
|
+
* @param element - Element to insert.
|
|
795
|
+
* @returns True.
|
|
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
|
+
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
* @example
|
|
829
|
+
* // basic Heap creation and add operation
|
|
830
|
+
* // Create a min heap (default)
|
|
831
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
832
|
+
*
|
|
833
|
+
* // Verify size
|
|
834
|
+
* console.log(minHeap.size); // 6;
|
|
835
|
+
*
|
|
836
|
+
* // Add new element
|
|
837
|
+
* minHeap.add(4);
|
|
838
|
+
* console.log(minHeap.size); // 7;
|
|
839
|
+
*
|
|
840
|
+
* // Min heap property: smallest element at root
|
|
841
|
+
* const min = minHeap.peek();
|
|
842
|
+
* console.log(min); // 1;
|
|
843
|
+
*/
|
|
564
844
|
add(element) {
|
|
565
845
|
this._elements.push(element);
|
|
566
846
|
return this._bubbleUp(this.elements.length - 1);
|
|
567
847
|
}
|
|
568
848
|
/**
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
849
|
+
* Insert many elements from an iterable.
|
|
850
|
+
* @remarks Time O(N log N), Space O(1)
|
|
851
|
+
* @param elements - Iterable of elements or raw values.
|
|
852
|
+
* @returns Array of per-element success flags.
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
* @example
|
|
883
|
+
* // Add multiple elements
|
|
884
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
885
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
886
|
+
* console.log(heap.peek()); // 1;
|
|
887
|
+
* console.log(heap.size); // 4;
|
|
888
|
+
*/
|
|
574
889
|
addMany(elements) {
|
|
575
890
|
const flags = [];
|
|
576
891
|
for (const el of elements) {
|
|
@@ -585,10 +900,67 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
585
900
|
return flags;
|
|
586
901
|
}
|
|
587
902
|
/**
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
903
|
+
* Remove and return the top element.
|
|
904
|
+
* @remarks Time O(log N), Space O(1)
|
|
905
|
+
* @returns Top element or undefined.
|
|
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
|
+
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
* @example
|
|
939
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
940
|
+
* interface Task {
|
|
941
|
+
* id: number;
|
|
942
|
+
* priority: number;
|
|
943
|
+
* name: string;
|
|
944
|
+
* }
|
|
945
|
+
*
|
|
946
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
947
|
+
* const tasks: Task[] = [
|
|
948
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
949
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
950
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
951
|
+
* ];
|
|
952
|
+
*
|
|
953
|
+
* const maxHeap = new Heap(tasks, {
|
|
954
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
955
|
+
* });
|
|
956
|
+
*
|
|
957
|
+
* console.log(maxHeap.size); // 3;
|
|
958
|
+
*
|
|
959
|
+
* // Peek returns highest priority task
|
|
960
|
+
* const topTask = maxHeap.peek();
|
|
961
|
+
* console.log(topTask?.priority); // 8;
|
|
962
|
+
* console.log(topTask?.name); // 'Alert';
|
|
963
|
+
*/
|
|
592
964
|
poll() {
|
|
593
965
|
if (this.elements.length === 0) return;
|
|
594
966
|
const value = this.elements[0];
|
|
@@ -600,26 +972,188 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
600
972
|
return value;
|
|
601
973
|
}
|
|
602
974
|
/**
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
975
|
+
* Get the current top element without removing it.
|
|
976
|
+
* @remarks Time O(1), Space O(1)
|
|
977
|
+
* @returns Top element or undefined.
|
|
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
|
+
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
* @example
|
|
1011
|
+
* // Heap for event processing with priority
|
|
1012
|
+
* interface Event {
|
|
1013
|
+
* id: number;
|
|
1014
|
+
* type: 'critical' | 'warning' | 'info';
|
|
1015
|
+
* timestamp: number;
|
|
1016
|
+
* message: string;
|
|
1017
|
+
* }
|
|
1018
|
+
*
|
|
1019
|
+
* // Custom priority: critical > warning > info
|
|
1020
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
1021
|
+
*
|
|
1022
|
+
* const eventHeap = new Heap<Event>([], {
|
|
1023
|
+
* comparator: (a: Event, b: Event) => {
|
|
1024
|
+
* const priorityA = priorityMap[a.type];
|
|
1025
|
+
* const priorityB = priorityMap[b.type];
|
|
1026
|
+
* return priorityB - priorityA; // Higher priority first
|
|
1027
|
+
* }
|
|
1028
|
+
* });
|
|
1029
|
+
*
|
|
1030
|
+
* // Add events in random order
|
|
1031
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
1032
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
1033
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
1034
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
1035
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
1036
|
+
*
|
|
1037
|
+
* console.log(eventHeap.size); // 5;
|
|
1038
|
+
*
|
|
1039
|
+
* // Process events by priority (critical first)
|
|
1040
|
+
* const processedOrder: Event[] = [];
|
|
1041
|
+
* while (eventHeap.size > 0) {
|
|
1042
|
+
* const event = eventHeap.poll();
|
|
1043
|
+
* if (event) {
|
|
1044
|
+
* processedOrder.push(event);
|
|
1045
|
+
* }
|
|
1046
|
+
* }
|
|
1047
|
+
*
|
|
1048
|
+
* // Verify critical events came first
|
|
1049
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
1050
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
1051
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
1052
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
1053
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
1054
|
+
*
|
|
1055
|
+
* // Verify O(log n) operations
|
|
1056
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
1057
|
+
*
|
|
1058
|
+
* // Add - O(log n)
|
|
1059
|
+
* newHeap.add(2);
|
|
1060
|
+
* console.log(newHeap.size); // 5;
|
|
1061
|
+
*
|
|
1062
|
+
* // Poll - O(log n)
|
|
1063
|
+
* const removed = newHeap.poll();
|
|
1064
|
+
* console.log(removed); // 1;
|
|
1065
|
+
*
|
|
1066
|
+
* // Peek - O(1)
|
|
1067
|
+
* const top = newHeap.peek();
|
|
1068
|
+
* console.log(top); // 2;
|
|
1069
|
+
*/
|
|
607
1070
|
peek() {
|
|
608
1071
|
return this.elements[0];
|
|
609
1072
|
}
|
|
610
1073
|
/**
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
1074
|
+
* Check whether the heap is empty.
|
|
1075
|
+
* @remarks Time O(1), Space O(1)
|
|
1076
|
+
* @returns True if size is 0.
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
* @example
|
|
1108
|
+
* // Check if heap is empty
|
|
1109
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
1110
|
+
* console.log(heap.isEmpty()); // true;
|
|
1111
|
+
* heap.add(1);
|
|
1112
|
+
* console.log(heap.isEmpty()); // false;
|
|
1113
|
+
*/
|
|
615
1114
|
isEmpty() {
|
|
616
1115
|
return this.size === 0;
|
|
617
1116
|
}
|
|
618
1117
|
/**
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
1118
|
+
* Remove all elements.
|
|
1119
|
+
* @remarks Time O(1), Space O(1)
|
|
1120
|
+
* @returns void
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
* @example
|
|
1152
|
+
* // Remove all elements
|
|
1153
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1154
|
+
* heap.clear();
|
|
1155
|
+
* console.log(heap.isEmpty()); // true;
|
|
1156
|
+
*/
|
|
623
1157
|
clear() {
|
|
624
1158
|
this._elements = [];
|
|
625
1159
|
}
|
|
@@ -634,21 +1168,83 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
634
1168
|
return this.fix();
|
|
635
1169
|
}
|
|
636
1170
|
/**
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
1171
|
+
* Check if an equal element exists in the heap.
|
|
1172
|
+
* @remarks Time O(N), Space O(1)
|
|
1173
|
+
* @param element - Element to search for.
|
|
1174
|
+
* @returns True if found.
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
* @example
|
|
1199
|
+
* // Check element existence
|
|
1200
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1201
|
+
* console.log(heap.has(1)); // true;
|
|
1202
|
+
* console.log(heap.has(99)); // false;
|
|
1203
|
+
*/
|
|
642
1204
|
has(element) {
|
|
643
1205
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
644
1206
|
return false;
|
|
645
1207
|
}
|
|
646
1208
|
/**
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
1209
|
+
* Delete one occurrence of an element.
|
|
1210
|
+
* @remarks Time O(N), Space O(1)
|
|
1211
|
+
* @param element - Element to delete.
|
|
1212
|
+
* @returns True if an element was removed.
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
* @example
|
|
1243
|
+
* // Remove specific element
|
|
1244
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
1245
|
+
* heap.delete(4);
|
|
1246
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
1247
|
+
*/
|
|
652
1248
|
delete(element) {
|
|
653
1249
|
let index = -1;
|
|
654
1250
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -706,11 +1302,39 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
706
1302
|
return this;
|
|
707
1303
|
}
|
|
708
1304
|
/**
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
1305
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
1306
|
+
* @remarks Time O(N), Space O(H)
|
|
1307
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
1308
|
+
* @returns Array of visited elements.
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
* @example
|
|
1333
|
+
* // Depth-first traversal
|
|
1334
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1335
|
+
* const result = heap.dfs('IN');
|
|
1336
|
+
* console.log(result.length); // 3;
|
|
1337
|
+
*/
|
|
714
1338
|
dfs(order = "PRE") {
|
|
715
1339
|
const result = [];
|
|
716
1340
|
const _dfs = /* @__PURE__ */ __name((index) => {
|
|
@@ -747,10 +1371,47 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
747
1371
|
return results;
|
|
748
1372
|
}
|
|
749
1373
|
/**
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
1374
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
1375
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1376
|
+
* @returns Sorted array of elements.
|
|
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
|
+
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
|
|
1406
|
+
|
|
1407
|
+
|
|
1408
|
+
|
|
1409
|
+
* @example
|
|
1410
|
+
* // Sort elements using heap
|
|
1411
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
1412
|
+
* const sorted = heap.sort();
|
|
1413
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
1414
|
+
*/
|
|
754
1415
|
sort() {
|
|
755
1416
|
const visited = [];
|
|
756
1417
|
const cloned = this._createInstance();
|
|
@@ -762,22 +1423,94 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
762
1423
|
return visited;
|
|
763
1424
|
}
|
|
764
1425
|
/**
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
1426
|
+
* Deep clone this heap.
|
|
1427
|
+
* @remarks Time O(N), Space O(N)
|
|
1428
|
+
* @returns A new heap with the same elements.
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
|
|
1453
|
+
|
|
1454
|
+
|
|
1455
|
+
|
|
1456
|
+
|
|
1457
|
+
|
|
1458
|
+
|
|
1459
|
+
* @example
|
|
1460
|
+
* // Create independent copy
|
|
1461
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
1462
|
+
* const copy = heap.clone();
|
|
1463
|
+
* copy.poll();
|
|
1464
|
+
* console.log(heap.size); // 3;
|
|
1465
|
+
* console.log(copy.size); // 2;
|
|
1466
|
+
*/
|
|
769
1467
|
clone() {
|
|
770
1468
|
const next = this._createInstance();
|
|
771
1469
|
for (const x of this.elements) next.add(x);
|
|
772
1470
|
return next;
|
|
773
1471
|
}
|
|
774
1472
|
/**
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
1473
|
+
* Filter elements into a new heap of the same class.
|
|
1474
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1475
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
1476
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1477
|
+
* @returns A new heap with the kept elements.
|
|
1478
|
+
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
|
|
1482
|
+
|
|
1483
|
+
|
|
1484
|
+
|
|
1485
|
+
|
|
1486
|
+
|
|
1487
|
+
|
|
1488
|
+
|
|
1489
|
+
|
|
1490
|
+
|
|
1491
|
+
|
|
1492
|
+
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
|
|
1503
|
+
|
|
1504
|
+
|
|
1505
|
+
|
|
1506
|
+
|
|
1507
|
+
|
|
1508
|
+
* @example
|
|
1509
|
+
* // Filter elements
|
|
1510
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
1511
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
1512
|
+
* console.log(evens.size); // 2;
|
|
1513
|
+
*/
|
|
781
1514
|
filter(callback, thisArg) {
|
|
782
1515
|
const out = this._createInstance();
|
|
783
1516
|
let i = 0;
|
|
@@ -791,15 +1524,49 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
791
1524
|
return out;
|
|
792
1525
|
}
|
|
793
1526
|
/**
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
1527
|
+
* Map elements into a new heap of possibly different element type.
|
|
1528
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1529
|
+
* @template EM
|
|
1530
|
+
* @template RM
|
|
1531
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
1532
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
1533
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1534
|
+
* @returns A new heap with mapped elements.
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
|
|
1559
|
+
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
|
|
1563
|
+
|
|
1564
|
+
* @example
|
|
1565
|
+
* // Transform elements
|
|
1566
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1567
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
1568
|
+
* console.log(doubled.peek()); // 2;
|
|
1569
|
+
*/
|
|
803
1570
|
map(callback, options, thisArg) {
|
|
804
1571
|
const { comparator, toElementFn, ...rest } = options != null ? options : {};
|
|
805
1572
|
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
@@ -905,198 +1672,6 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
905
1672
|
__name(_Heap, "Heap");
|
|
906
1673
|
var Heap = _Heap;
|
|
907
1674
|
|
|
908
|
-
// src/data-structures/base/linear-base.ts
|
|
909
|
-
var _LinearBase = class _LinearBase extends IterableElementBase {
|
|
910
|
-
/**
|
|
911
|
-
* Construct a linear container with runtime options.
|
|
912
|
-
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
913
|
-
* @remarks Time O(1), Space O(1)
|
|
914
|
-
*/
|
|
915
|
-
constructor(options) {
|
|
916
|
-
super(options);
|
|
917
|
-
__publicField(this, "_maxLen", -1);
|
|
918
|
-
if (options) {
|
|
919
|
-
const { maxLen } = options;
|
|
920
|
-
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
/**
|
|
924
|
-
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
925
|
-
* @returns Maximum allowed length.
|
|
926
|
-
* @remarks Time O(1), Space O(1)
|
|
927
|
-
*/
|
|
928
|
-
get maxLen() {
|
|
929
|
-
return this._maxLen;
|
|
930
|
-
}
|
|
931
|
-
/**
|
|
932
|
-
* First index of a value from the left.
|
|
933
|
-
* @param searchElement - Value to match.
|
|
934
|
-
* @param fromIndex - Start position (supports negative index).
|
|
935
|
-
* @returns Index or `-1` if not found.
|
|
936
|
-
* @remarks Time O(n), Space O(1)
|
|
937
|
-
*/
|
|
938
|
-
indexOf(searchElement, fromIndex = 0) {
|
|
939
|
-
if (this.length === 0) return -1;
|
|
940
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
941
|
-
if (fromIndex < 0) fromIndex = 0;
|
|
942
|
-
for (let i = fromIndex; i < this.length; i++) {
|
|
943
|
-
const element = this.at(i);
|
|
944
|
-
if (element === searchElement) return i;
|
|
945
|
-
}
|
|
946
|
-
return -1;
|
|
947
|
-
}
|
|
948
|
-
/**
|
|
949
|
-
* Last index of a value from the right.
|
|
950
|
-
* @param searchElement - Value to match.
|
|
951
|
-
* @param fromIndex - Start position (supports negative index).
|
|
952
|
-
* @returns Index or `-1` if not found.
|
|
953
|
-
* @remarks Time O(n), Space O(1)
|
|
954
|
-
*/
|
|
955
|
-
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
956
|
-
if (this.length === 0) return -1;
|
|
957
|
-
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
958
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
959
|
-
for (let i = fromIndex; i >= 0; i--) {
|
|
960
|
-
const element = this.at(i);
|
|
961
|
-
if (element === searchElement) return i;
|
|
962
|
-
}
|
|
963
|
-
return -1;
|
|
964
|
-
}
|
|
965
|
-
/**
|
|
966
|
-
* Find the first index matching a predicate.
|
|
967
|
-
* @param predicate - `(element, index, self) => boolean`.
|
|
968
|
-
* @param thisArg - Optional `this` for callback.
|
|
969
|
-
* @returns Index or `-1`.
|
|
970
|
-
* @remarks Time O(n), Space O(1)
|
|
971
|
-
*/
|
|
972
|
-
findIndex(predicate, thisArg) {
|
|
973
|
-
for (let i = 0; i < this.length; i++) {
|
|
974
|
-
const item = this.at(i);
|
|
975
|
-
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
976
|
-
}
|
|
977
|
-
return -1;
|
|
978
|
-
}
|
|
979
|
-
/**
|
|
980
|
-
* Concatenate elements and/or containers.
|
|
981
|
-
* @param items - Elements or other containers.
|
|
982
|
-
* @returns New container with combined elements (`this` type).
|
|
983
|
-
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
984
|
-
*/
|
|
985
|
-
concat(...items) {
|
|
986
|
-
const newList = this.clone();
|
|
987
|
-
for (const item of items) {
|
|
988
|
-
if (item instanceof _LinearBase) {
|
|
989
|
-
newList.pushMany(item);
|
|
990
|
-
} else {
|
|
991
|
-
newList.push(item);
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
return newList;
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* In-place stable order via array sort semantics.
|
|
998
|
-
* @param compareFn - Comparator `(a, b) => number`.
|
|
999
|
-
* @returns This container.
|
|
1000
|
-
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
1001
|
-
*/
|
|
1002
|
-
sort(compareFn) {
|
|
1003
|
-
const arr = this.toArray();
|
|
1004
|
-
arr.sort(compareFn);
|
|
1005
|
-
this.clear();
|
|
1006
|
-
for (const item of arr) this.push(item);
|
|
1007
|
-
return this;
|
|
1008
|
-
}
|
|
1009
|
-
/**
|
|
1010
|
-
* Remove and/or insert elements at a position (array-compatible).
|
|
1011
|
-
* @param start - Start index (supports negative index).
|
|
1012
|
-
* @param deleteCount - How many to remove.
|
|
1013
|
-
* @param items - Elements to insert.
|
|
1014
|
-
* @returns Removed elements as a new list (`this` type).
|
|
1015
|
-
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
1016
|
-
*/
|
|
1017
|
-
splice(start, deleteCount = 0, ...items) {
|
|
1018
|
-
const removedList = this._createInstance();
|
|
1019
|
-
start = start < 0 ? this.length + start : start;
|
|
1020
|
-
start = Math.max(0, Math.min(start, this.length));
|
|
1021
|
-
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
1022
|
-
for (let i = 0; i < deleteCount; i++) {
|
|
1023
|
-
const removed = this.deleteAt(start);
|
|
1024
|
-
if (removed !== void 0) {
|
|
1025
|
-
removedList.push(removed);
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
for (let i = 0; i < items.length; i++) {
|
|
1029
|
-
this.addAt(start + i, items[i]);
|
|
1030
|
-
}
|
|
1031
|
-
return removedList;
|
|
1032
|
-
}
|
|
1033
|
-
/**
|
|
1034
|
-
* Join all elements into a string.
|
|
1035
|
-
* @param separator - Separator string.
|
|
1036
|
-
* @returns Concatenated string.
|
|
1037
|
-
* @remarks Time O(n), Space O(n)
|
|
1038
|
-
*/
|
|
1039
|
-
join(separator = ",") {
|
|
1040
|
-
return this.toArray().join(separator);
|
|
1041
|
-
}
|
|
1042
|
-
/**
|
|
1043
|
-
* Snapshot elements into a reversed array.
|
|
1044
|
-
* @returns New reversed array.
|
|
1045
|
-
* @remarks Time O(n), Space O(n)
|
|
1046
|
-
*/
|
|
1047
|
-
toReversedArray() {
|
|
1048
|
-
const array = [];
|
|
1049
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1050
|
-
array.push(this.at(i));
|
|
1051
|
-
}
|
|
1052
|
-
return array;
|
|
1053
|
-
}
|
|
1054
|
-
reduceRight(callbackfn, initialValue) {
|
|
1055
|
-
let accumulator = initialValue != null ? initialValue : 0;
|
|
1056
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1057
|
-
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
1058
|
-
}
|
|
1059
|
-
return accumulator;
|
|
1060
|
-
}
|
|
1061
|
-
/**
|
|
1062
|
-
* Create a shallow copy of a subrange.
|
|
1063
|
-
* @param start - Inclusive start (supports negative index).
|
|
1064
|
-
* @param end - Exclusive end (supports negative index).
|
|
1065
|
-
* @returns New list with the range (`this` type).
|
|
1066
|
-
* @remarks Time O(n), Space O(n)
|
|
1067
|
-
*/
|
|
1068
|
-
slice(start = 0, end = this.length) {
|
|
1069
|
-
start = start < 0 ? this.length + start : start;
|
|
1070
|
-
end = end < 0 ? this.length + end : end;
|
|
1071
|
-
const newList = this._createInstance();
|
|
1072
|
-
for (let i = start; i < end; i++) {
|
|
1073
|
-
newList.push(this.at(i));
|
|
1074
|
-
}
|
|
1075
|
-
return newList;
|
|
1076
|
-
}
|
|
1077
|
-
/**
|
|
1078
|
-
* Fill a range with a value.
|
|
1079
|
-
* @param value - Value to set.
|
|
1080
|
-
* @param start - Inclusive start.
|
|
1081
|
-
* @param end - Exclusive end.
|
|
1082
|
-
* @returns This list.
|
|
1083
|
-
* @remarks Time O(n), Space O(1)
|
|
1084
|
-
*/
|
|
1085
|
-
fill(value, start = 0, end = this.length) {
|
|
1086
|
-
start = start < 0 ? this.length + start : start;
|
|
1087
|
-
end = end < 0 ? this.length + end : end;
|
|
1088
|
-
if (start < 0) start = 0;
|
|
1089
|
-
if (end > this.length) end = this.length;
|
|
1090
|
-
if (start >= end) return this;
|
|
1091
|
-
for (let i = start; i < end; i++) {
|
|
1092
|
-
this.setAt(i, value);
|
|
1093
|
-
}
|
|
1094
|
-
return this;
|
|
1095
|
-
}
|
|
1096
|
-
};
|
|
1097
|
-
__name(_LinearBase, "LinearBase");
|
|
1098
|
-
var LinearBase = _LinearBase;
|
|
1099
|
-
|
|
1100
1675
|
// src/data-structures/queue/queue.ts
|
|
1101
1676
|
var _Queue = class _Queue extends LinearBase {
|
|
1102
1677
|
/**
|
|
@@ -1151,18 +1726,94 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1151
1726
|
this._autoCompactRatio = value;
|
|
1152
1727
|
}
|
|
1153
1728
|
/**
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1729
|
+
* Get the number of elements currently in the queue.
|
|
1730
|
+
* @remarks Time O(1), Space O(1)
|
|
1731
|
+
* @returns Current length.
|
|
1732
|
+
|
|
1733
|
+
|
|
1734
|
+
|
|
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
|
+
* @example
|
|
1765
|
+
* // Track queue length
|
|
1766
|
+
* const q = new Queue<number>();
|
|
1767
|
+
* console.log(q.length); // 0;
|
|
1768
|
+
* q.push(1);
|
|
1769
|
+
* q.push(2);
|
|
1770
|
+
* console.log(q.length); // 2;
|
|
1771
|
+
*/
|
|
1158
1772
|
get length() {
|
|
1159
1773
|
return this.elements.length - this._offset;
|
|
1160
1774
|
}
|
|
1161
1775
|
/**
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1776
|
+
* Get the first element (front) without removing it.
|
|
1777
|
+
* @remarks Time O(1), Space O(1)
|
|
1778
|
+
* @returns Front element or undefined.
|
|
1779
|
+
|
|
1780
|
+
|
|
1781
|
+
|
|
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
|
+
* @example
|
|
1812
|
+
* // View the front element
|
|
1813
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
1814
|
+
* console.log(q.first); // 'first';
|
|
1815
|
+
* console.log(q.length); // 3;
|
|
1816
|
+
*/
|
|
1166
1817
|
get first() {
|
|
1167
1818
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
1168
1819
|
}
|
|
@@ -1185,19 +1836,111 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1185
1836
|
return new _Queue(elements);
|
|
1186
1837
|
}
|
|
1187
1838
|
/**
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1839
|
+
* Check whether the queue is empty.
|
|
1840
|
+
* @remarks Time O(1), Space O(1)
|
|
1841
|
+
* @returns True if length is 0.
|
|
1842
|
+
|
|
1843
|
+
|
|
1844
|
+
|
|
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
|
+
* @example
|
|
1875
|
+
* // Queue for...of iteration and isEmpty check
|
|
1876
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
1877
|
+
*
|
|
1878
|
+
* const elements: string[] = [];
|
|
1879
|
+
* for (const item of queue) {
|
|
1880
|
+
* elements.push(item);
|
|
1881
|
+
* }
|
|
1882
|
+
*
|
|
1883
|
+
* // Verify all elements are iterated in order
|
|
1884
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
1885
|
+
*
|
|
1886
|
+
* // Process all elements
|
|
1887
|
+
* while (queue.length > 0) {
|
|
1888
|
+
* queue.shift();
|
|
1889
|
+
* }
|
|
1890
|
+
*
|
|
1891
|
+
* console.log(queue.length); // 0;
|
|
1892
|
+
*/
|
|
1192
1893
|
isEmpty() {
|
|
1193
1894
|
return this.length === 0;
|
|
1194
1895
|
}
|
|
1195
1896
|
/**
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1897
|
+
* Enqueue one element at the back.
|
|
1898
|
+
* @remarks Time O(1), Space O(1)
|
|
1899
|
+
* @param element - Element to enqueue.
|
|
1900
|
+
* @returns True on success.
|
|
1901
|
+
|
|
1902
|
+
|
|
1903
|
+
|
|
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
|
+
* @example
|
|
1934
|
+
* // basic Queue creation and push operation
|
|
1935
|
+
* // Create a simple Queue with initial values
|
|
1936
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
1937
|
+
*
|
|
1938
|
+
* // Verify the queue maintains insertion order
|
|
1939
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
1940
|
+
*
|
|
1941
|
+
* // Check length
|
|
1942
|
+
* console.log(queue.length); // 5;
|
|
1943
|
+
*/
|
|
1201
1944
|
push(element) {
|
|
1202
1945
|
this.elements.push(element);
|
|
1203
1946
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -1218,10 +1961,56 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1218
1961
|
return ans;
|
|
1219
1962
|
}
|
|
1220
1963
|
/**
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1964
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1965
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1966
|
+
* @returns Removed element or undefined.
|
|
1967
|
+
|
|
1968
|
+
|
|
1969
|
+
|
|
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
|
+
* @example
|
|
2000
|
+
* // Queue shift and peek operations
|
|
2001
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
2002
|
+
*
|
|
2003
|
+
* // Peek at the front element without removing it
|
|
2004
|
+
* console.log(queue.first); // 10;
|
|
2005
|
+
*
|
|
2006
|
+
* // Remove and get the first element (FIFO)
|
|
2007
|
+
* const first = queue.shift();
|
|
2008
|
+
* console.log(first); // 10;
|
|
2009
|
+
*
|
|
2010
|
+
* // Verify remaining elements and length decreased
|
|
2011
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
2012
|
+
* console.log(queue.length); // 3;
|
|
2013
|
+
*/
|
|
1225
2014
|
shift() {
|
|
1226
2015
|
if (this.length === 0) return void 0;
|
|
1227
2016
|
const first = this.first;
|
|
@@ -1230,11 +2019,45 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1230
2019
|
return first;
|
|
1231
2020
|
}
|
|
1232
2021
|
/**
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
2022
|
+
* Delete the first occurrence of a specific element.
|
|
2023
|
+
* @remarks Time O(N), Space O(1)
|
|
2024
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
2025
|
+
* @returns True if an element was removed.
|
|
2026
|
+
|
|
2027
|
+
|
|
2028
|
+
|
|
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
|
+
* @example
|
|
2056
|
+
* // Remove specific element
|
|
2057
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
2058
|
+
* q.delete(2);
|
|
2059
|
+
* console.log(q.length); // 3;
|
|
2060
|
+
*/
|
|
1238
2061
|
delete(element) {
|
|
1239
2062
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
1240
2063
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -1245,11 +2068,45 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1245
2068
|
return false;
|
|
1246
2069
|
}
|
|
1247
2070
|
/**
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
2071
|
+
* Get the element at a given logical index.
|
|
2072
|
+
* @remarks Time O(1), Space O(1)
|
|
2073
|
+
* @param index - Zero-based index from the front.
|
|
2074
|
+
* @returns Element or undefined.
|
|
2075
|
+
|
|
2076
|
+
|
|
2077
|
+
|
|
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
|
+
* @example
|
|
2105
|
+
* // Access element by index
|
|
2106
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
2107
|
+
* console.log(q.at(0)); // 'a';
|
|
2108
|
+
* console.log(q.at(2)); // 'c';
|
|
2109
|
+
*/
|
|
1253
2110
|
at(index) {
|
|
1254
2111
|
if (index < 0 || index >= this.length) return void 0;
|
|
1255
2112
|
return this._elements[this._offset + index];
|
|
@@ -1301,19 +2158,90 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1301
2158
|
return this;
|
|
1302
2159
|
}
|
|
1303
2160
|
/**
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
2161
|
+
* Remove all elements and reset offset.
|
|
2162
|
+
* @remarks Time O(1), Space O(1)
|
|
2163
|
+
* @returns void
|
|
2164
|
+
|
|
2165
|
+
|
|
2166
|
+
|
|
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
|
+
* @example
|
|
2195
|
+
* // Remove all elements
|
|
2196
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2197
|
+
* q.clear();
|
|
2198
|
+
* console.log(q.length); // 0;
|
|
2199
|
+
*/
|
|
1308
2200
|
clear() {
|
|
1309
2201
|
this._elements = [];
|
|
1310
2202
|
this._offset = 0;
|
|
1311
2203
|
}
|
|
1312
2204
|
/**
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
2205
|
+
* Compact storage by discarding consumed head elements.
|
|
2206
|
+
* @remarks Time O(N), Space O(N)
|
|
2207
|
+
* @returns True when compaction performed.
|
|
2208
|
+
|
|
2209
|
+
|
|
2210
|
+
|
|
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
|
+
* @example
|
|
2238
|
+
* // Reclaim unused memory
|
|
2239
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2240
|
+
* q.shift();
|
|
2241
|
+
* q.shift();
|
|
2242
|
+
* q.compact();
|
|
2243
|
+
* console.log(q.length); // 3;
|
|
2244
|
+
*/
|
|
1317
2245
|
compact() {
|
|
1318
2246
|
this._elements = this.elements.slice(this._offset);
|
|
1319
2247
|
this._offset = 0;
|
|
@@ -1339,10 +2267,47 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1339
2267
|
return removed;
|
|
1340
2268
|
}
|
|
1341
2269
|
/**
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
2270
|
+
* Deep clone this queue and its parameters.
|
|
2271
|
+
* @remarks Time O(N), Space O(N)
|
|
2272
|
+
* @returns A new queue with the same content and options.
|
|
2273
|
+
|
|
2274
|
+
|
|
2275
|
+
|
|
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
|
+
* @example
|
|
2304
|
+
* // Create independent copy
|
|
2305
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2306
|
+
* const copy = q.clone();
|
|
2307
|
+
* copy.shift();
|
|
2308
|
+
* console.log(q.length); // 3;
|
|
2309
|
+
* console.log(copy.length); // 2;
|
|
2310
|
+
*/
|
|
1346
2311
|
clone() {
|
|
1347
2312
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1348
2313
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1350,12 +2315,47 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1350
2315
|
return out;
|
|
1351
2316
|
}
|
|
1352
2317
|
/**
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
2318
|
+
* Filter elements into a new queue of the same class.
|
|
2319
|
+
* @remarks Time O(N), Space O(N)
|
|
2320
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
2321
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
2322
|
+
* @returns A new queue with kept elements.
|
|
2323
|
+
|
|
2324
|
+
|
|
2325
|
+
|
|
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
|
+
* @example
|
|
2354
|
+
* // Filter elements
|
|
2355
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2356
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
2357
|
+
* console.log(evens.length); // 2;
|
|
2358
|
+
*/
|
|
1359
2359
|
filter(predicate, thisArg) {
|
|
1360
2360
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1361
2361
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1367,15 +2367,49 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1367
2367
|
return out;
|
|
1368
2368
|
}
|
|
1369
2369
|
/**
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
2370
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
2371
|
+
* @remarks Time O(N), Space O(N)
|
|
2372
|
+
* @template EM
|
|
2373
|
+
* @template RM
|
|
2374
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
2375
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
2376
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
2377
|
+
* @returns A new Queue with mapped elements.
|
|
2378
|
+
|
|
2379
|
+
|
|
2380
|
+
|
|
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
|
+
* @example
|
|
2408
|
+
* // Transform elements
|
|
2409
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2410
|
+
* const doubled = q.map(x => x * 2);
|
|
2411
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
2412
|
+
*/
|
|
1379
2413
|
map(callback, options, thisArg) {
|
|
1380
2414
|
var _a, _b;
|
|
1381
2415
|
const out = new this.constructor([], {
|
|
@@ -2475,12 +3509,49 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2475
3509
|
return new DirectedEdge(src, dest, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 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 != null ? 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
|
}
|
|
@@ -2945,12 +4408,48 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2945
4408
|
return new UndirectedEdge(v1, v2, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
|
|
2946
4409
|
}
|
|
2947
4410
|
/**
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
4411
|
+
* Get an undirected edge between two vertices, if present.
|
|
4412
|
+
* @param v1 - One vertex or key.
|
|
4413
|
+
* @param v2 - The other vertex or key.
|
|
4414
|
+
* @returns Edge instance or `undefined`.
|
|
4415
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
4416
|
+
|
|
4417
|
+
|
|
4418
|
+
|
|
4419
|
+
|
|
4420
|
+
|
|
4421
|
+
|
|
4422
|
+
|
|
4423
|
+
|
|
4424
|
+
|
|
4425
|
+
|
|
4426
|
+
|
|
4427
|
+
|
|
4428
|
+
|
|
4429
|
+
|
|
4430
|
+
|
|
4431
|
+
|
|
4432
|
+
|
|
4433
|
+
|
|
4434
|
+
|
|
4435
|
+
|
|
4436
|
+
|
|
4437
|
+
|
|
4438
|
+
|
|
4439
|
+
|
|
4440
|
+
|
|
4441
|
+
|
|
4442
|
+
|
|
4443
|
+
|
|
4444
|
+
|
|
4445
|
+
* @example
|
|
4446
|
+
* // Get edge between vertices
|
|
4447
|
+
* const g = new UndirectedGraph();
|
|
4448
|
+
* g.addVertex('A');
|
|
4449
|
+
* g.addVertex('B');
|
|
4450
|
+
* g.addEdge('A', 'B', 7);
|
|
4451
|
+
* console.log(g.getEdge('A', 'B')?.weight); // 7;
|
|
4452
|
+
*/
|
|
2954
4453
|
getEdge(v1, v2) {
|
|
2955
4454
|
var _a;
|
|
2956
4455
|
let edgeMap = [];
|
|
@@ -2988,12 +4487,71 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2988
4487
|
return removed;
|
|
2989
4488
|
}
|
|
2990
4489
|
/**
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
4490
|
+
* Delete an edge by instance or by a pair of keys.
|
|
4491
|
+
* @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
|
|
4492
|
+
* @param otherSideVertexKey - Required second endpoint when deleting by pair.
|
|
4493
|
+
* @returns Removed edge or `undefined`.
|
|
4494
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
4495
|
+
|
|
4496
|
+
|
|
4497
|
+
|
|
4498
|
+
|
|
4499
|
+
|
|
4500
|
+
|
|
4501
|
+
|
|
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
|
+
* @example
|
|
4528
|
+
* // UndirectedGraph deleteEdge and vertex operations
|
|
4529
|
+
* const graph = new UndirectedGraph<string>();
|
|
4530
|
+
*
|
|
4531
|
+
* // Build a simple undirected graph
|
|
4532
|
+
* graph.addVertex('X');
|
|
4533
|
+
* graph.addVertex('Y');
|
|
4534
|
+
* graph.addVertex('Z');
|
|
4535
|
+
* graph.addEdge('X', 'Y', 1);
|
|
4536
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
4537
|
+
* graph.addEdge('X', 'Z', 3);
|
|
4538
|
+
*
|
|
4539
|
+
* // Delete an edge
|
|
4540
|
+
* graph.deleteEdge('X', 'Y');
|
|
4541
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
4542
|
+
*
|
|
4543
|
+
* // Bidirectional deletion confirmed
|
|
4544
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
4545
|
+
*
|
|
4546
|
+
* // Other edges should remain
|
|
4547
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
4548
|
+
* console.log(graph.hasEdge('Z', 'Y')); // true;
|
|
4549
|
+
*
|
|
4550
|
+
* // Delete a vertex
|
|
4551
|
+
* graph.deleteVertex('Y');
|
|
4552
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
4553
|
+
* console.log(graph.size); // 2;
|
|
4554
|
+
*/
|
|
2997
4555
|
deleteEdge(edgeOrOneSideVertexKey, otherSideVertexKey) {
|
|
2998
4556
|
let oneSide, otherSide;
|
|
2999
4557
|
if (this.isVertexKey(edgeOrOneSideVertexKey)) {
|
|
@@ -3014,11 +4572,48 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3014
4572
|
}
|
|
3015
4573
|
}
|
|
3016
4574
|
/**
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
4575
|
+
* Delete a vertex and remove it from all neighbor lists.
|
|
4576
|
+
* @param vertexOrKey - Vertex or key.
|
|
4577
|
+
* @returns `true` if removed; otherwise `false`.
|
|
4578
|
+
* @remarks Time O(deg), Space O(1)
|
|
4579
|
+
|
|
4580
|
+
|
|
4581
|
+
|
|
4582
|
+
|
|
4583
|
+
|
|
4584
|
+
|
|
4585
|
+
|
|
4586
|
+
|
|
4587
|
+
|
|
4588
|
+
|
|
4589
|
+
|
|
4590
|
+
|
|
4591
|
+
|
|
4592
|
+
|
|
4593
|
+
|
|
4594
|
+
|
|
4595
|
+
|
|
4596
|
+
|
|
4597
|
+
|
|
4598
|
+
|
|
4599
|
+
|
|
4600
|
+
|
|
4601
|
+
|
|
4602
|
+
|
|
4603
|
+
|
|
4604
|
+
|
|
4605
|
+
|
|
4606
|
+
|
|
4607
|
+
|
|
4608
|
+
* @example
|
|
4609
|
+
* // Remove vertex and edges
|
|
4610
|
+
* const g = new UndirectedGraph();
|
|
4611
|
+
* g.addVertex('A');
|
|
4612
|
+
* g.addVertex('B');
|
|
4613
|
+
* g.addEdge('A', 'B');
|
|
4614
|
+
* g.deleteVertex('A');
|
|
4615
|
+
* console.log(g.hasVertex('A')); // false;
|
|
4616
|
+
*/
|
|
3022
4617
|
deleteVertex(vertexOrKey) {
|
|
3023
4618
|
let vertexKey;
|
|
3024
4619
|
let vertex;
|
|
@@ -3074,10 +4669,46 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3074
4669
|
}
|
|
3075
4670
|
}
|
|
3076
4671
|
/**
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
4672
|
+
* Unique set of undirected edges across endpoints.
|
|
4673
|
+
* @returns Array of edges.
|
|
4674
|
+
* @remarks Time O(E), Space O(E)
|
|
4675
|
+
|
|
4676
|
+
|
|
4677
|
+
|
|
4678
|
+
|
|
4679
|
+
|
|
4680
|
+
|
|
4681
|
+
|
|
4682
|
+
|
|
4683
|
+
|
|
4684
|
+
|
|
4685
|
+
|
|
4686
|
+
|
|
4687
|
+
|
|
4688
|
+
|
|
4689
|
+
|
|
4690
|
+
|
|
4691
|
+
|
|
4692
|
+
|
|
4693
|
+
|
|
4694
|
+
|
|
4695
|
+
|
|
4696
|
+
|
|
4697
|
+
|
|
4698
|
+
|
|
4699
|
+
|
|
4700
|
+
|
|
4701
|
+
|
|
4702
|
+
|
|
4703
|
+
|
|
4704
|
+
* @example
|
|
4705
|
+
* // Get all edges
|
|
4706
|
+
* const g = new UndirectedGraph();
|
|
4707
|
+
* g.addVertex('A');
|
|
4708
|
+
* g.addVertex('B');
|
|
4709
|
+
* g.addEdge('A', 'B');
|
|
4710
|
+
* console.log(g.edgeSet().length); // 1;
|
|
4711
|
+
*/
|
|
3081
4712
|
edgeSet() {
|
|
3082
4713
|
const edgeSet = /* @__PURE__ */ new Set();
|
|
3083
4714
|
this._edgeMap.forEach((edgeMap) => {
|
|
@@ -3087,6 +4718,73 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3087
4718
|
});
|
|
3088
4719
|
return [...edgeSet];
|
|
3089
4720
|
}
|
|
4721
|
+
/**
|
|
4722
|
+
* UndirectedGraph connectivity and neighbors
|
|
4723
|
+
|
|
4724
|
+
|
|
4725
|
+
|
|
4726
|
+
|
|
4727
|
+
|
|
4728
|
+
|
|
4729
|
+
|
|
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
|
+
* @example
|
|
4756
|
+
* // UndirectedGraph connectivity and neighbors
|
|
4757
|
+
* const graph = new UndirectedGraph<string>();
|
|
4758
|
+
*
|
|
4759
|
+
* // Build a friendship network
|
|
4760
|
+
* const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
|
|
4761
|
+
* for (const person of people) {
|
|
4762
|
+
* graph.addVertex(person);
|
|
4763
|
+
* }
|
|
4764
|
+
*
|
|
4765
|
+
* // Add friendships (undirected edges)
|
|
4766
|
+
* graph.addEdge('Alice', 'Bob', 1);
|
|
4767
|
+
* graph.addEdge('Alice', 'Charlie', 1);
|
|
4768
|
+
* graph.addEdge('Bob', 'Diana', 1);
|
|
4769
|
+
* graph.addEdge('Charlie', 'Eve', 1);
|
|
4770
|
+
* graph.addEdge('Diana', 'Eve', 1);
|
|
4771
|
+
*
|
|
4772
|
+
* // Get friends of each person
|
|
4773
|
+
* const aliceFriends = graph.getNeighbors('Alice');
|
|
4774
|
+
* console.log(aliceFriends[0].key); // 'Bob';
|
|
4775
|
+
* console.log(aliceFriends[1].key); // 'Charlie';
|
|
4776
|
+
* console.log(aliceFriends.length); // 2;
|
|
4777
|
+
*
|
|
4778
|
+
* const dianaFriends = graph.getNeighbors('Diana');
|
|
4779
|
+
* console.log(dianaFriends[0].key); // 'Bob';
|
|
4780
|
+
* console.log(dianaFriends[1].key); // 'Eve';
|
|
4781
|
+
* console.log(dianaFriends.length); // 2;
|
|
4782
|
+
*
|
|
4783
|
+
* // Verify bidirectional friendship
|
|
4784
|
+
* const bobFriends = graph.getNeighbors('Bob');
|
|
4785
|
+
* console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
|
|
4786
|
+
* console.log(bobFriends[1].key); // 'Diana';
|
|
4787
|
+
*/
|
|
3090
4788
|
getNeighbors(vertexOrKey) {
|
|
3091
4789
|
const neighbors = [];
|
|
3092
4790
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -3143,10 +4841,49 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3143
4841
|
return super.clone();
|
|
3144
4842
|
}
|
|
3145
4843
|
/**
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
4844
|
+
* Tarjan-based bridge and articulation point detection.
|
|
4845
|
+
* @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
|
|
4846
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
4847
|
+
|
|
4848
|
+
|
|
4849
|
+
|
|
4850
|
+
|
|
4851
|
+
|
|
4852
|
+
|
|
4853
|
+
|
|
4854
|
+
|
|
4855
|
+
|
|
4856
|
+
|
|
4857
|
+
|
|
4858
|
+
|
|
4859
|
+
|
|
4860
|
+
|
|
4861
|
+
|
|
4862
|
+
|
|
4863
|
+
|
|
4864
|
+
|
|
4865
|
+
|
|
4866
|
+
|
|
4867
|
+
|
|
4868
|
+
|
|
4869
|
+
|
|
4870
|
+
|
|
4871
|
+
|
|
4872
|
+
|
|
4873
|
+
|
|
4874
|
+
|
|
4875
|
+
|
|
4876
|
+
* @example
|
|
4877
|
+
* // Find articulation points and bridges
|
|
4878
|
+
* const g = new UndirectedGraph();
|
|
4879
|
+
* g.addVertex('A');
|
|
4880
|
+
* g.addVertex('B');
|
|
4881
|
+
* g.addVertex('C');
|
|
4882
|
+
* g.addEdge('A', 'B');
|
|
4883
|
+
* g.addEdge('B', 'C');
|
|
4884
|
+
* const result = g.tarjan();
|
|
4885
|
+
* console.log(result); // defined;
|
|
4886
|
+
*/
|
|
3150
4887
|
tarjan() {
|
|
3151
4888
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
3152
4889
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -3246,11 +4983,51 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3246
4983
|
return components;
|
|
3247
4984
|
}
|
|
3248
4985
|
/**
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
4986
|
+
* Detect whether the graph contains a cycle.
|
|
4987
|
+
* Uses DFS with parent tracking.
|
|
4988
|
+
* @returns `true` if a cycle exists, `false` otherwise.
|
|
4989
|
+
* @remarks Time O(V + E), Space O(V)
|
|
4990
|
+
|
|
4991
|
+
|
|
4992
|
+
|
|
4993
|
+
|
|
4994
|
+
|
|
4995
|
+
|
|
4996
|
+
|
|
4997
|
+
|
|
4998
|
+
|
|
4999
|
+
|
|
5000
|
+
|
|
5001
|
+
|
|
5002
|
+
|
|
5003
|
+
|
|
5004
|
+
|
|
5005
|
+
|
|
5006
|
+
|
|
5007
|
+
|
|
5008
|
+
|
|
5009
|
+
|
|
5010
|
+
|
|
5011
|
+
|
|
5012
|
+
|
|
5013
|
+
|
|
5014
|
+
|
|
5015
|
+
|
|
5016
|
+
|
|
5017
|
+
|
|
5018
|
+
|
|
5019
|
+
* @example
|
|
5020
|
+
* // Detect cycle
|
|
5021
|
+
* const g = new UndirectedGraph();
|
|
5022
|
+
* g.addVertex('A');
|
|
5023
|
+
* g.addVertex('B');
|
|
5024
|
+
* g.addVertex('C');
|
|
5025
|
+
* g.addEdge('A', 'B');
|
|
5026
|
+
* g.addEdge('B', 'C');
|
|
5027
|
+
* console.log(g.hasCycle()); // false;
|
|
5028
|
+
* g.addEdge('C', 'A');
|
|
5029
|
+
* console.log(g.hasCycle()); // true;
|
|
5030
|
+
*/
|
|
3254
5031
|
hasCycle() {
|
|
3255
5032
|
const visited = /* @__PURE__ */ new Set();
|
|
3256
5033
|
const dfs = /* @__PURE__ */ __name((vertex, parent) => {
|
|
@@ -3272,18 +5049,97 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3272
5049
|
return false;
|
|
3273
5050
|
}
|
|
3274
5051
|
/**
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
5052
|
+
* Get bridges discovered by `tarjan()`.
|
|
5053
|
+
* @returns Array of edges that are bridges.
|
|
5054
|
+
* @remarks Time O(B), Space O(1)
|
|
5055
|
+
|
|
5056
|
+
|
|
5057
|
+
|
|
5058
|
+
|
|
5059
|
+
|
|
5060
|
+
|
|
5061
|
+
|
|
5062
|
+
|
|
5063
|
+
|
|
5064
|
+
|
|
5065
|
+
|
|
5066
|
+
|
|
5067
|
+
|
|
5068
|
+
|
|
5069
|
+
|
|
5070
|
+
|
|
5071
|
+
|
|
5072
|
+
|
|
5073
|
+
|
|
5074
|
+
|
|
5075
|
+
|
|
5076
|
+
|
|
5077
|
+
|
|
5078
|
+
|
|
5079
|
+
|
|
5080
|
+
|
|
5081
|
+
|
|
5082
|
+
|
|
5083
|
+
|
|
5084
|
+
* @example
|
|
5085
|
+
* // Find bridge edges
|
|
5086
|
+
* const g = new UndirectedGraph();
|
|
5087
|
+
* g.addVertex('A');
|
|
5088
|
+
* g.addVertex('B');
|
|
5089
|
+
* g.addVertex('C');
|
|
5090
|
+
* g.addEdge('A', 'B');
|
|
5091
|
+
* g.addEdge('B', 'C');
|
|
5092
|
+
* const bridges = g.getBridges();
|
|
5093
|
+
* console.log(bridges.length); // 2;
|
|
5094
|
+
*/
|
|
3279
5095
|
getBridges() {
|
|
3280
5096
|
return this.tarjan().bridges;
|
|
3281
5097
|
}
|
|
3282
5098
|
/**
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
5099
|
+
* Get articulation points discovered by `tarjan()`.
|
|
5100
|
+
* @returns Array of cut vertices.
|
|
5101
|
+
* @remarks Time O(C), Space O(1)
|
|
5102
|
+
|
|
5103
|
+
|
|
5104
|
+
|
|
5105
|
+
|
|
5106
|
+
|
|
5107
|
+
|
|
5108
|
+
|
|
5109
|
+
|
|
5110
|
+
|
|
5111
|
+
|
|
5112
|
+
|
|
5113
|
+
|
|
5114
|
+
|
|
5115
|
+
|
|
5116
|
+
|
|
5117
|
+
|
|
5118
|
+
|
|
5119
|
+
|
|
5120
|
+
|
|
5121
|
+
|
|
5122
|
+
|
|
5123
|
+
|
|
5124
|
+
|
|
5125
|
+
|
|
5126
|
+
|
|
5127
|
+
|
|
5128
|
+
|
|
5129
|
+
|
|
5130
|
+
|
|
5131
|
+
* @example
|
|
5132
|
+
* // Find articulation points
|
|
5133
|
+
* const g = new UndirectedGraph();
|
|
5134
|
+
* g.addVertex('A');
|
|
5135
|
+
* g.addVertex('B');
|
|
5136
|
+
* g.addVertex('C');
|
|
5137
|
+
* g.addEdge('A', 'B');
|
|
5138
|
+
* g.addEdge('B', 'C');
|
|
5139
|
+
* const cuts = g.getCutVertices();
|
|
5140
|
+
* console.log(cuts.length); // 1;
|
|
5141
|
+
* console.log(cuts[0].key); // 'B';
|
|
5142
|
+
*/
|
|
3287
5143
|
getCutVertices() {
|
|
3288
5144
|
return this.tarjan().cutVertices;
|
|
3289
5145
|
}
|