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
|
@@ -275,7 +275,7 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
275
275
|
if (options) {
|
|
276
276
|
const { toElementFn } = options;
|
|
277
277
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
278
|
-
else if (toElementFn) throw new TypeError(
|
|
278
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
/**
|
|
@@ -431,7 +431,7 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
431
431
|
acc = initialValue;
|
|
432
432
|
} else {
|
|
433
433
|
const first = iter.next();
|
|
434
|
-
if (first.done) throw new TypeError(
|
|
434
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
435
435
|
acc = first.value;
|
|
436
436
|
index = 1;
|
|
437
437
|
}
|
|
@@ -475,6 +475,198 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
475
475
|
__name(_IterableElementBase, "IterableElementBase");
|
|
476
476
|
var IterableElementBase = _IterableElementBase;
|
|
477
477
|
|
|
478
|
+
// src/data-structures/base/linear-base.ts
|
|
479
|
+
var _LinearBase = class _LinearBase extends IterableElementBase {
|
|
480
|
+
/**
|
|
481
|
+
* Construct a linear container with runtime options.
|
|
482
|
+
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
483
|
+
* @remarks Time O(1), Space O(1)
|
|
484
|
+
*/
|
|
485
|
+
constructor(options) {
|
|
486
|
+
super(options);
|
|
487
|
+
__publicField(this, "_maxLen", -1);
|
|
488
|
+
if (options) {
|
|
489
|
+
const { maxLen } = options;
|
|
490
|
+
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
495
|
+
* @returns Maximum allowed length.
|
|
496
|
+
* @remarks Time O(1), Space O(1)
|
|
497
|
+
*/
|
|
498
|
+
get maxLen() {
|
|
499
|
+
return this._maxLen;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* First index of a value from the left.
|
|
503
|
+
* @param searchElement - Value to match.
|
|
504
|
+
* @param fromIndex - Start position (supports negative index).
|
|
505
|
+
* @returns Index or `-1` if not found.
|
|
506
|
+
* @remarks Time O(n), Space O(1)
|
|
507
|
+
*/
|
|
508
|
+
indexOf(searchElement, fromIndex = 0) {
|
|
509
|
+
if (this.length === 0) return -1;
|
|
510
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
511
|
+
if (fromIndex < 0) fromIndex = 0;
|
|
512
|
+
for (let i = fromIndex; i < this.length; i++) {
|
|
513
|
+
const element = this.at(i);
|
|
514
|
+
if (element === searchElement) return i;
|
|
515
|
+
}
|
|
516
|
+
return -1;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Last index of a value from the right.
|
|
520
|
+
* @param searchElement - Value to match.
|
|
521
|
+
* @param fromIndex - Start position (supports negative index).
|
|
522
|
+
* @returns Index or `-1` if not found.
|
|
523
|
+
* @remarks Time O(n), Space O(1)
|
|
524
|
+
*/
|
|
525
|
+
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
526
|
+
if (this.length === 0) return -1;
|
|
527
|
+
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
528
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
529
|
+
for (let i = fromIndex; i >= 0; i--) {
|
|
530
|
+
const element = this.at(i);
|
|
531
|
+
if (element === searchElement) return i;
|
|
532
|
+
}
|
|
533
|
+
return -1;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Find the first index matching a predicate.
|
|
537
|
+
* @param predicate - `(element, index, self) => boolean`.
|
|
538
|
+
* @param thisArg - Optional `this` for callback.
|
|
539
|
+
* @returns Index or `-1`.
|
|
540
|
+
* @remarks Time O(n), Space O(1)
|
|
541
|
+
*/
|
|
542
|
+
findIndex(predicate, thisArg) {
|
|
543
|
+
for (let i = 0; i < this.length; i++) {
|
|
544
|
+
const item = this.at(i);
|
|
545
|
+
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
546
|
+
}
|
|
547
|
+
return -1;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Concatenate elements and/or containers.
|
|
551
|
+
* @param items - Elements or other containers.
|
|
552
|
+
* @returns New container with combined elements (`this` type).
|
|
553
|
+
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
554
|
+
*/
|
|
555
|
+
concat(...items) {
|
|
556
|
+
const newList = this.clone();
|
|
557
|
+
for (const item of items) {
|
|
558
|
+
if (item instanceof _LinearBase) {
|
|
559
|
+
newList.pushMany(item);
|
|
560
|
+
} else {
|
|
561
|
+
newList.push(item);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return newList;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* In-place stable order via array sort semantics.
|
|
568
|
+
* @param compareFn - Comparator `(a, b) => number`.
|
|
569
|
+
* @returns This container.
|
|
570
|
+
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
571
|
+
*/
|
|
572
|
+
sort(compareFn) {
|
|
573
|
+
const arr = this.toArray();
|
|
574
|
+
arr.sort(compareFn);
|
|
575
|
+
this.clear();
|
|
576
|
+
for (const item of arr) this.push(item);
|
|
577
|
+
return this;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Remove and/or insert elements at a position (array-compatible).
|
|
581
|
+
* @param start - Start index (supports negative index).
|
|
582
|
+
* @param deleteCount - How many to remove.
|
|
583
|
+
* @param items - Elements to insert.
|
|
584
|
+
* @returns Removed elements as a new list (`this` type).
|
|
585
|
+
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
586
|
+
*/
|
|
587
|
+
splice(start, deleteCount = 0, ...items) {
|
|
588
|
+
const removedList = this._createInstance();
|
|
589
|
+
start = start < 0 ? this.length + start : start;
|
|
590
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
591
|
+
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
592
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
593
|
+
const removed = this.deleteAt(start);
|
|
594
|
+
if (removed !== void 0) {
|
|
595
|
+
removedList.push(removed);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
for (let i = 0; i < items.length; i++) {
|
|
599
|
+
this.addAt(start + i, items[i]);
|
|
600
|
+
}
|
|
601
|
+
return removedList;
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Join all elements into a string.
|
|
605
|
+
* @param separator - Separator string.
|
|
606
|
+
* @returns Concatenated string.
|
|
607
|
+
* @remarks Time O(n), Space O(n)
|
|
608
|
+
*/
|
|
609
|
+
join(separator = ",") {
|
|
610
|
+
return this.toArray().join(separator);
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Snapshot elements into a reversed array.
|
|
614
|
+
* @returns New reversed array.
|
|
615
|
+
* @remarks Time O(n), Space O(n)
|
|
616
|
+
*/
|
|
617
|
+
toReversedArray() {
|
|
618
|
+
const array = [];
|
|
619
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
620
|
+
array.push(this.at(i));
|
|
621
|
+
}
|
|
622
|
+
return array;
|
|
623
|
+
}
|
|
624
|
+
reduceRight(callbackfn, initialValue) {
|
|
625
|
+
let accumulator = initialValue != null ? initialValue : 0;
|
|
626
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
627
|
+
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
628
|
+
}
|
|
629
|
+
return accumulator;
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Create a shallow copy of a subrange.
|
|
633
|
+
* @param start - Inclusive start (supports negative index).
|
|
634
|
+
* @param end - Exclusive end (supports negative index).
|
|
635
|
+
* @returns New list with the range (`this` type).
|
|
636
|
+
* @remarks Time O(n), Space O(n)
|
|
637
|
+
*/
|
|
638
|
+
slice(start = 0, end = this.length) {
|
|
639
|
+
start = start < 0 ? this.length + start : start;
|
|
640
|
+
end = end < 0 ? this.length + end : end;
|
|
641
|
+
const newList = this._createInstance();
|
|
642
|
+
for (let i = start; i < end; i++) {
|
|
643
|
+
newList.push(this.at(i));
|
|
644
|
+
}
|
|
645
|
+
return newList;
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Fill a range with a value.
|
|
649
|
+
* @param value - Value to set.
|
|
650
|
+
* @param start - Inclusive start.
|
|
651
|
+
* @param end - Exclusive end.
|
|
652
|
+
* @returns This list.
|
|
653
|
+
* @remarks Time O(n), Space O(1)
|
|
654
|
+
*/
|
|
655
|
+
fill(value, start = 0, end = this.length) {
|
|
656
|
+
start = start < 0 ? this.length + start : start;
|
|
657
|
+
end = end < 0 ? this.length + end : end;
|
|
658
|
+
if (start < 0) start = 0;
|
|
659
|
+
if (end > this.length) end = this.length;
|
|
660
|
+
if (start >= end) return this;
|
|
661
|
+
for (let i = start; i < end; i++) {
|
|
662
|
+
this.setAt(i, value);
|
|
663
|
+
}
|
|
664
|
+
return this;
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
__name(_LinearBase, "LinearBase");
|
|
668
|
+
var LinearBase = _LinearBase;
|
|
669
|
+
|
|
478
670
|
// src/data-structures/heap/heap.ts
|
|
479
671
|
var _Heap = class _Heap extends IterableElementBase {
|
|
480
672
|
/**
|
|
@@ -512,10 +704,51 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
512
704
|
return this._elements;
|
|
513
705
|
}
|
|
514
706
|
/**
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
707
|
+
* Get the number of elements.
|
|
708
|
+
* @remarks Time O(1), Space O(1)
|
|
709
|
+
* @returns Heap size.
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
* @example
|
|
743
|
+
* // Track heap capacity
|
|
744
|
+
* const heap = new Heap<number>();
|
|
745
|
+
* console.log(heap.size); // 0;
|
|
746
|
+
* heap.add(10);
|
|
747
|
+
* heap.add(20);
|
|
748
|
+
* console.log(heap.size); // 2;
|
|
749
|
+
* heap.poll();
|
|
750
|
+
* console.log(heap.size); // 1;
|
|
751
|
+
*/
|
|
519
752
|
get size() {
|
|
520
753
|
return this.elements.length;
|
|
521
754
|
}
|
|
@@ -554,21 +787,103 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
554
787
|
return new _Heap(elements, options);
|
|
555
788
|
}
|
|
556
789
|
/**
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
790
|
+
* Insert an element.
|
|
791
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
792
|
+
* @param element - Element to insert.
|
|
793
|
+
* @returns True.
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
* @example
|
|
827
|
+
* // basic Heap creation and add operation
|
|
828
|
+
* // Create a min heap (default)
|
|
829
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
830
|
+
*
|
|
831
|
+
* // Verify size
|
|
832
|
+
* console.log(minHeap.size); // 6;
|
|
833
|
+
*
|
|
834
|
+
* // Add new element
|
|
835
|
+
* minHeap.add(4);
|
|
836
|
+
* console.log(minHeap.size); // 7;
|
|
837
|
+
*
|
|
838
|
+
* // Min heap property: smallest element at root
|
|
839
|
+
* const min = minHeap.peek();
|
|
840
|
+
* console.log(min); // 1;
|
|
841
|
+
*/
|
|
562
842
|
add(element) {
|
|
563
843
|
this._elements.push(element);
|
|
564
844
|
return this._bubbleUp(this.elements.length - 1);
|
|
565
845
|
}
|
|
566
846
|
/**
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
847
|
+
* Insert many elements from an iterable.
|
|
848
|
+
* @remarks Time O(N log N), Space O(1)
|
|
849
|
+
* @param elements - Iterable of elements or raw values.
|
|
850
|
+
* @returns Array of per-element success flags.
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
* @example
|
|
881
|
+
* // Add multiple elements
|
|
882
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
883
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
884
|
+
* console.log(heap.peek()); // 1;
|
|
885
|
+
* console.log(heap.size); // 4;
|
|
886
|
+
*/
|
|
572
887
|
addMany(elements) {
|
|
573
888
|
const flags = [];
|
|
574
889
|
for (const el of elements) {
|
|
@@ -583,10 +898,67 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
583
898
|
return flags;
|
|
584
899
|
}
|
|
585
900
|
/**
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
901
|
+
* Remove and return the top element.
|
|
902
|
+
* @remarks Time O(log N), Space O(1)
|
|
903
|
+
* @returns Top element or undefined.
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
* @example
|
|
937
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
938
|
+
* interface Task {
|
|
939
|
+
* id: number;
|
|
940
|
+
* priority: number;
|
|
941
|
+
* name: string;
|
|
942
|
+
* }
|
|
943
|
+
*
|
|
944
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
945
|
+
* const tasks: Task[] = [
|
|
946
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
947
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
948
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
949
|
+
* ];
|
|
950
|
+
*
|
|
951
|
+
* const maxHeap = new Heap(tasks, {
|
|
952
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
953
|
+
* });
|
|
954
|
+
*
|
|
955
|
+
* console.log(maxHeap.size); // 3;
|
|
956
|
+
*
|
|
957
|
+
* // Peek returns highest priority task
|
|
958
|
+
* const topTask = maxHeap.peek();
|
|
959
|
+
* console.log(topTask?.priority); // 8;
|
|
960
|
+
* console.log(topTask?.name); // 'Alert';
|
|
961
|
+
*/
|
|
590
962
|
poll() {
|
|
591
963
|
if (this.elements.length === 0) return;
|
|
592
964
|
const value = this.elements[0];
|
|
@@ -598,26 +970,188 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
598
970
|
return value;
|
|
599
971
|
}
|
|
600
972
|
/**
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
973
|
+
* Get the current top element without removing it.
|
|
974
|
+
* @remarks Time O(1), Space O(1)
|
|
975
|
+
* @returns Top element or undefined.
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
* @example
|
|
1009
|
+
* // Heap for event processing with priority
|
|
1010
|
+
* interface Event {
|
|
1011
|
+
* id: number;
|
|
1012
|
+
* type: 'critical' | 'warning' | 'info';
|
|
1013
|
+
* timestamp: number;
|
|
1014
|
+
* message: string;
|
|
1015
|
+
* }
|
|
1016
|
+
*
|
|
1017
|
+
* // Custom priority: critical > warning > info
|
|
1018
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
1019
|
+
*
|
|
1020
|
+
* const eventHeap = new Heap<Event>([], {
|
|
1021
|
+
* comparator: (a: Event, b: Event) => {
|
|
1022
|
+
* const priorityA = priorityMap[a.type];
|
|
1023
|
+
* const priorityB = priorityMap[b.type];
|
|
1024
|
+
* return priorityB - priorityA; // Higher priority first
|
|
1025
|
+
* }
|
|
1026
|
+
* });
|
|
1027
|
+
*
|
|
1028
|
+
* // Add events in random order
|
|
1029
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
1030
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
1031
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
1032
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
1033
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
1034
|
+
*
|
|
1035
|
+
* console.log(eventHeap.size); // 5;
|
|
1036
|
+
*
|
|
1037
|
+
* // Process events by priority (critical first)
|
|
1038
|
+
* const processedOrder: Event[] = [];
|
|
1039
|
+
* while (eventHeap.size > 0) {
|
|
1040
|
+
* const event = eventHeap.poll();
|
|
1041
|
+
* if (event) {
|
|
1042
|
+
* processedOrder.push(event);
|
|
1043
|
+
* }
|
|
1044
|
+
* }
|
|
1045
|
+
*
|
|
1046
|
+
* // Verify critical events came first
|
|
1047
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
1048
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
1049
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
1050
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
1051
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
1052
|
+
*
|
|
1053
|
+
* // Verify O(log n) operations
|
|
1054
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
1055
|
+
*
|
|
1056
|
+
* // Add - O(log n)
|
|
1057
|
+
* newHeap.add(2);
|
|
1058
|
+
* console.log(newHeap.size); // 5;
|
|
1059
|
+
*
|
|
1060
|
+
* // Poll - O(log n)
|
|
1061
|
+
* const removed = newHeap.poll();
|
|
1062
|
+
* console.log(removed); // 1;
|
|
1063
|
+
*
|
|
1064
|
+
* // Peek - O(1)
|
|
1065
|
+
* const top = newHeap.peek();
|
|
1066
|
+
* console.log(top); // 2;
|
|
1067
|
+
*/
|
|
605
1068
|
peek() {
|
|
606
1069
|
return this.elements[0];
|
|
607
1070
|
}
|
|
608
1071
|
/**
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
1072
|
+
* Check whether the heap is empty.
|
|
1073
|
+
* @remarks Time O(1), Space O(1)
|
|
1074
|
+
* @returns True if size is 0.
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
* @example
|
|
1106
|
+
* // Check if heap is empty
|
|
1107
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
1108
|
+
* console.log(heap.isEmpty()); // true;
|
|
1109
|
+
* heap.add(1);
|
|
1110
|
+
* console.log(heap.isEmpty()); // false;
|
|
1111
|
+
*/
|
|
613
1112
|
isEmpty() {
|
|
614
1113
|
return this.size === 0;
|
|
615
1114
|
}
|
|
616
1115
|
/**
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
1116
|
+
* Remove all elements.
|
|
1117
|
+
* @remarks Time O(1), Space O(1)
|
|
1118
|
+
* @returns void
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
* @example
|
|
1150
|
+
* // Remove all elements
|
|
1151
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1152
|
+
* heap.clear();
|
|
1153
|
+
* console.log(heap.isEmpty()); // true;
|
|
1154
|
+
*/
|
|
621
1155
|
clear() {
|
|
622
1156
|
this._elements = [];
|
|
623
1157
|
}
|
|
@@ -632,21 +1166,83 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
632
1166
|
return this.fix();
|
|
633
1167
|
}
|
|
634
1168
|
/**
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
1169
|
+
* Check if an equal element exists in the heap.
|
|
1170
|
+
* @remarks Time O(N), Space O(1)
|
|
1171
|
+
* @param element - Element to search for.
|
|
1172
|
+
* @returns True if found.
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
* @example
|
|
1197
|
+
* // Check element existence
|
|
1198
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1199
|
+
* console.log(heap.has(1)); // true;
|
|
1200
|
+
* console.log(heap.has(99)); // false;
|
|
1201
|
+
*/
|
|
640
1202
|
has(element) {
|
|
641
1203
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
642
1204
|
return false;
|
|
643
1205
|
}
|
|
644
1206
|
/**
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
1207
|
+
* Delete one occurrence of an element.
|
|
1208
|
+
* @remarks Time O(N), Space O(1)
|
|
1209
|
+
* @param element - Element to delete.
|
|
1210
|
+
* @returns True if an element was removed.
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
|
|
1240
|
+
* @example
|
|
1241
|
+
* // Remove specific element
|
|
1242
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
1243
|
+
* heap.delete(4);
|
|
1244
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
1245
|
+
*/
|
|
650
1246
|
delete(element) {
|
|
651
1247
|
let index = -1;
|
|
652
1248
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -704,11 +1300,39 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
704
1300
|
return this;
|
|
705
1301
|
}
|
|
706
1302
|
/**
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
1303
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
1304
|
+
* @remarks Time O(N), Space O(H)
|
|
1305
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
1306
|
+
* @returns Array of visited elements.
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
* @example
|
|
1331
|
+
* // Depth-first traversal
|
|
1332
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1333
|
+
* const result = heap.dfs('IN');
|
|
1334
|
+
* console.log(result.length); // 3;
|
|
1335
|
+
*/
|
|
712
1336
|
dfs(order = "PRE") {
|
|
713
1337
|
const result = [];
|
|
714
1338
|
const _dfs = /* @__PURE__ */ __name((index) => {
|
|
@@ -745,10 +1369,47 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
745
1369
|
return results;
|
|
746
1370
|
}
|
|
747
1371
|
/**
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
1372
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
1373
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1374
|
+
* @returns Sorted array of elements.
|
|
1375
|
+
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
|
|
1382
|
+
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
|
|
1388
|
+
|
|
1389
|
+
|
|
1390
|
+
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
|
|
1401
|
+
|
|
1402
|
+
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
|
|
1406
|
+
|
|
1407
|
+
* @example
|
|
1408
|
+
* // Sort elements using heap
|
|
1409
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
1410
|
+
* const sorted = heap.sort();
|
|
1411
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
1412
|
+
*/
|
|
752
1413
|
sort() {
|
|
753
1414
|
const visited = [];
|
|
754
1415
|
const cloned = this._createInstance();
|
|
@@ -760,22 +1421,94 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
760
1421
|
return visited;
|
|
761
1422
|
}
|
|
762
1423
|
/**
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1424
|
+
* Deep clone this heap.
|
|
1425
|
+
* @remarks Time O(N), Space O(N)
|
|
1426
|
+
* @returns A new heap with the same elements.
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
|
|
1453
|
+
|
|
1454
|
+
|
|
1455
|
+
|
|
1456
|
+
|
|
1457
|
+
* @example
|
|
1458
|
+
* // Create independent copy
|
|
1459
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
1460
|
+
* const copy = heap.clone();
|
|
1461
|
+
* copy.poll();
|
|
1462
|
+
* console.log(heap.size); // 3;
|
|
1463
|
+
* console.log(copy.size); // 2;
|
|
1464
|
+
*/
|
|
767
1465
|
clone() {
|
|
768
1466
|
const next = this._createInstance();
|
|
769
1467
|
for (const x of this.elements) next.add(x);
|
|
770
1468
|
return next;
|
|
771
1469
|
}
|
|
772
1470
|
/**
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
1471
|
+
* Filter elements into a new heap of the same class.
|
|
1472
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1473
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
1474
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1475
|
+
* @returns A new heap with the kept elements.
|
|
1476
|
+
|
|
1477
|
+
|
|
1478
|
+
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
|
|
1482
|
+
|
|
1483
|
+
|
|
1484
|
+
|
|
1485
|
+
|
|
1486
|
+
|
|
1487
|
+
|
|
1488
|
+
|
|
1489
|
+
|
|
1490
|
+
|
|
1491
|
+
|
|
1492
|
+
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
|
|
1503
|
+
|
|
1504
|
+
|
|
1505
|
+
|
|
1506
|
+
* @example
|
|
1507
|
+
* // Filter elements
|
|
1508
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
1509
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
1510
|
+
* console.log(evens.size); // 2;
|
|
1511
|
+
*/
|
|
779
1512
|
filter(callback, thisArg) {
|
|
780
1513
|
const out = this._createInstance();
|
|
781
1514
|
let i = 0;
|
|
@@ -789,15 +1522,49 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
789
1522
|
return out;
|
|
790
1523
|
}
|
|
791
1524
|
/**
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
1525
|
+
* Map elements into a new heap of possibly different element type.
|
|
1526
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1527
|
+
* @template EM
|
|
1528
|
+
* @template RM
|
|
1529
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
1530
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
1531
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1532
|
+
* @returns A new heap with mapped elements.
|
|
1533
|
+
|
|
1534
|
+
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
|
|
1559
|
+
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
* @example
|
|
1563
|
+
* // Transform elements
|
|
1564
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1565
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
1566
|
+
* console.log(doubled.peek()); // 2;
|
|
1567
|
+
*/
|
|
801
1568
|
map(callback, options, thisArg) {
|
|
802
1569
|
const { comparator, toElementFn, ...rest } = options != null ? options : {};
|
|
803
1570
|
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
@@ -903,198 +1670,6 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
903
1670
|
__name(_Heap, "Heap");
|
|
904
1671
|
var Heap = _Heap;
|
|
905
1672
|
|
|
906
|
-
// src/data-structures/base/linear-base.ts
|
|
907
|
-
var _LinearBase = class _LinearBase extends IterableElementBase {
|
|
908
|
-
/**
|
|
909
|
-
* Construct a linear container with runtime options.
|
|
910
|
-
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
911
|
-
* @remarks Time O(1), Space O(1)
|
|
912
|
-
*/
|
|
913
|
-
constructor(options) {
|
|
914
|
-
super(options);
|
|
915
|
-
__publicField(this, "_maxLen", -1);
|
|
916
|
-
if (options) {
|
|
917
|
-
const { maxLen } = options;
|
|
918
|
-
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
/**
|
|
922
|
-
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
923
|
-
* @returns Maximum allowed length.
|
|
924
|
-
* @remarks Time O(1), Space O(1)
|
|
925
|
-
*/
|
|
926
|
-
get maxLen() {
|
|
927
|
-
return this._maxLen;
|
|
928
|
-
}
|
|
929
|
-
/**
|
|
930
|
-
* First index of a value from the left.
|
|
931
|
-
* @param searchElement - Value to match.
|
|
932
|
-
* @param fromIndex - Start position (supports negative index).
|
|
933
|
-
* @returns Index or `-1` if not found.
|
|
934
|
-
* @remarks Time O(n), Space O(1)
|
|
935
|
-
*/
|
|
936
|
-
indexOf(searchElement, fromIndex = 0) {
|
|
937
|
-
if (this.length === 0) return -1;
|
|
938
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
939
|
-
if (fromIndex < 0) fromIndex = 0;
|
|
940
|
-
for (let i = fromIndex; i < this.length; i++) {
|
|
941
|
-
const element = this.at(i);
|
|
942
|
-
if (element === searchElement) return i;
|
|
943
|
-
}
|
|
944
|
-
return -1;
|
|
945
|
-
}
|
|
946
|
-
/**
|
|
947
|
-
* Last index of a value from the right.
|
|
948
|
-
* @param searchElement - Value to match.
|
|
949
|
-
* @param fromIndex - Start position (supports negative index).
|
|
950
|
-
* @returns Index or `-1` if not found.
|
|
951
|
-
* @remarks Time O(n), Space O(1)
|
|
952
|
-
*/
|
|
953
|
-
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
954
|
-
if (this.length === 0) return -1;
|
|
955
|
-
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
956
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
957
|
-
for (let i = fromIndex; i >= 0; i--) {
|
|
958
|
-
const element = this.at(i);
|
|
959
|
-
if (element === searchElement) return i;
|
|
960
|
-
}
|
|
961
|
-
return -1;
|
|
962
|
-
}
|
|
963
|
-
/**
|
|
964
|
-
* Find the first index matching a predicate.
|
|
965
|
-
* @param predicate - `(element, index, self) => boolean`.
|
|
966
|
-
* @param thisArg - Optional `this` for callback.
|
|
967
|
-
* @returns Index or `-1`.
|
|
968
|
-
* @remarks Time O(n), Space O(1)
|
|
969
|
-
*/
|
|
970
|
-
findIndex(predicate, thisArg) {
|
|
971
|
-
for (let i = 0; i < this.length; i++) {
|
|
972
|
-
const item = this.at(i);
|
|
973
|
-
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
974
|
-
}
|
|
975
|
-
return -1;
|
|
976
|
-
}
|
|
977
|
-
/**
|
|
978
|
-
* Concatenate elements and/or containers.
|
|
979
|
-
* @param items - Elements or other containers.
|
|
980
|
-
* @returns New container with combined elements (`this` type).
|
|
981
|
-
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
982
|
-
*/
|
|
983
|
-
concat(...items) {
|
|
984
|
-
const newList = this.clone();
|
|
985
|
-
for (const item of items) {
|
|
986
|
-
if (item instanceof _LinearBase) {
|
|
987
|
-
newList.pushMany(item);
|
|
988
|
-
} else {
|
|
989
|
-
newList.push(item);
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
return newList;
|
|
993
|
-
}
|
|
994
|
-
/**
|
|
995
|
-
* In-place stable order via array sort semantics.
|
|
996
|
-
* @param compareFn - Comparator `(a, b) => number`.
|
|
997
|
-
* @returns This container.
|
|
998
|
-
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
999
|
-
*/
|
|
1000
|
-
sort(compareFn) {
|
|
1001
|
-
const arr = this.toArray();
|
|
1002
|
-
arr.sort(compareFn);
|
|
1003
|
-
this.clear();
|
|
1004
|
-
for (const item of arr) this.push(item);
|
|
1005
|
-
return this;
|
|
1006
|
-
}
|
|
1007
|
-
/**
|
|
1008
|
-
* Remove and/or insert elements at a position (array-compatible).
|
|
1009
|
-
* @param start - Start index (supports negative index).
|
|
1010
|
-
* @param deleteCount - How many to remove.
|
|
1011
|
-
* @param items - Elements to insert.
|
|
1012
|
-
* @returns Removed elements as a new list (`this` type).
|
|
1013
|
-
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
1014
|
-
*/
|
|
1015
|
-
splice(start, deleteCount = 0, ...items) {
|
|
1016
|
-
const removedList = this._createInstance();
|
|
1017
|
-
start = start < 0 ? this.length + start : start;
|
|
1018
|
-
start = Math.max(0, Math.min(start, this.length));
|
|
1019
|
-
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
1020
|
-
for (let i = 0; i < deleteCount; i++) {
|
|
1021
|
-
const removed = this.deleteAt(start);
|
|
1022
|
-
if (removed !== void 0) {
|
|
1023
|
-
removedList.push(removed);
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
for (let i = 0; i < items.length; i++) {
|
|
1027
|
-
this.addAt(start + i, items[i]);
|
|
1028
|
-
}
|
|
1029
|
-
return removedList;
|
|
1030
|
-
}
|
|
1031
|
-
/**
|
|
1032
|
-
* Join all elements into a string.
|
|
1033
|
-
* @param separator - Separator string.
|
|
1034
|
-
* @returns Concatenated string.
|
|
1035
|
-
* @remarks Time O(n), Space O(n)
|
|
1036
|
-
*/
|
|
1037
|
-
join(separator = ",") {
|
|
1038
|
-
return this.toArray().join(separator);
|
|
1039
|
-
}
|
|
1040
|
-
/**
|
|
1041
|
-
* Snapshot elements into a reversed array.
|
|
1042
|
-
* @returns New reversed array.
|
|
1043
|
-
* @remarks Time O(n), Space O(n)
|
|
1044
|
-
*/
|
|
1045
|
-
toReversedArray() {
|
|
1046
|
-
const array = [];
|
|
1047
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1048
|
-
array.push(this.at(i));
|
|
1049
|
-
}
|
|
1050
|
-
return array;
|
|
1051
|
-
}
|
|
1052
|
-
reduceRight(callbackfn, initialValue) {
|
|
1053
|
-
let accumulator = initialValue != null ? initialValue : 0;
|
|
1054
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1055
|
-
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
1056
|
-
}
|
|
1057
|
-
return accumulator;
|
|
1058
|
-
}
|
|
1059
|
-
/**
|
|
1060
|
-
* Create a shallow copy of a subrange.
|
|
1061
|
-
* @param start - Inclusive start (supports negative index).
|
|
1062
|
-
* @param end - Exclusive end (supports negative index).
|
|
1063
|
-
* @returns New list with the range (`this` type).
|
|
1064
|
-
* @remarks Time O(n), Space O(n)
|
|
1065
|
-
*/
|
|
1066
|
-
slice(start = 0, end = this.length) {
|
|
1067
|
-
start = start < 0 ? this.length + start : start;
|
|
1068
|
-
end = end < 0 ? this.length + end : end;
|
|
1069
|
-
const newList = this._createInstance();
|
|
1070
|
-
for (let i = start; i < end; i++) {
|
|
1071
|
-
newList.push(this.at(i));
|
|
1072
|
-
}
|
|
1073
|
-
return newList;
|
|
1074
|
-
}
|
|
1075
|
-
/**
|
|
1076
|
-
* Fill a range with a value.
|
|
1077
|
-
* @param value - Value to set.
|
|
1078
|
-
* @param start - Inclusive start.
|
|
1079
|
-
* @param end - Exclusive end.
|
|
1080
|
-
* @returns This list.
|
|
1081
|
-
* @remarks Time O(n), Space O(1)
|
|
1082
|
-
*/
|
|
1083
|
-
fill(value, start = 0, end = this.length) {
|
|
1084
|
-
start = start < 0 ? this.length + start : start;
|
|
1085
|
-
end = end < 0 ? this.length + end : end;
|
|
1086
|
-
if (start < 0) start = 0;
|
|
1087
|
-
if (end > this.length) end = this.length;
|
|
1088
|
-
if (start >= end) return this;
|
|
1089
|
-
for (let i = start; i < end; i++) {
|
|
1090
|
-
this.setAt(i, value);
|
|
1091
|
-
}
|
|
1092
|
-
return this;
|
|
1093
|
-
}
|
|
1094
|
-
};
|
|
1095
|
-
__name(_LinearBase, "LinearBase");
|
|
1096
|
-
var LinearBase = _LinearBase;
|
|
1097
|
-
|
|
1098
1673
|
// src/data-structures/queue/queue.ts
|
|
1099
1674
|
var _Queue = class _Queue extends LinearBase {
|
|
1100
1675
|
/**
|
|
@@ -1149,18 +1724,94 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1149
1724
|
this._autoCompactRatio = value;
|
|
1150
1725
|
}
|
|
1151
1726
|
/**
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1727
|
+
* Get the number of elements currently in the queue.
|
|
1728
|
+
* @remarks Time O(1), Space O(1)
|
|
1729
|
+
* @returns Current length.
|
|
1730
|
+
|
|
1731
|
+
|
|
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
|
+
* @example
|
|
1763
|
+
* // Track queue length
|
|
1764
|
+
* const q = new Queue<number>();
|
|
1765
|
+
* console.log(q.length); // 0;
|
|
1766
|
+
* q.push(1);
|
|
1767
|
+
* q.push(2);
|
|
1768
|
+
* console.log(q.length); // 2;
|
|
1769
|
+
*/
|
|
1156
1770
|
get length() {
|
|
1157
1771
|
return this.elements.length - this._offset;
|
|
1158
1772
|
}
|
|
1159
1773
|
/**
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1774
|
+
* Get the first element (front) without removing it.
|
|
1775
|
+
* @remarks Time O(1), Space O(1)
|
|
1776
|
+
* @returns Front element or undefined.
|
|
1777
|
+
|
|
1778
|
+
|
|
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
|
+
* @example
|
|
1810
|
+
* // View the front element
|
|
1811
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
1812
|
+
* console.log(q.first); // 'first';
|
|
1813
|
+
* console.log(q.length); // 3;
|
|
1814
|
+
*/
|
|
1164
1815
|
get first() {
|
|
1165
1816
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
1166
1817
|
}
|
|
@@ -1183,19 +1834,111 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1183
1834
|
return new _Queue(elements);
|
|
1184
1835
|
}
|
|
1185
1836
|
/**
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1837
|
+
* Check whether the queue is empty.
|
|
1838
|
+
* @remarks Time O(1), Space O(1)
|
|
1839
|
+
* @returns True if length is 0.
|
|
1840
|
+
|
|
1841
|
+
|
|
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
|
+
* @example
|
|
1873
|
+
* // Queue for...of iteration and isEmpty check
|
|
1874
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
1875
|
+
*
|
|
1876
|
+
* const elements: string[] = [];
|
|
1877
|
+
* for (const item of queue) {
|
|
1878
|
+
* elements.push(item);
|
|
1879
|
+
* }
|
|
1880
|
+
*
|
|
1881
|
+
* // Verify all elements are iterated in order
|
|
1882
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
1883
|
+
*
|
|
1884
|
+
* // Process all elements
|
|
1885
|
+
* while (queue.length > 0) {
|
|
1886
|
+
* queue.shift();
|
|
1887
|
+
* }
|
|
1888
|
+
*
|
|
1889
|
+
* console.log(queue.length); // 0;
|
|
1890
|
+
*/
|
|
1190
1891
|
isEmpty() {
|
|
1191
1892
|
return this.length === 0;
|
|
1192
1893
|
}
|
|
1193
1894
|
/**
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1895
|
+
* Enqueue one element at the back.
|
|
1896
|
+
* @remarks Time O(1), Space O(1)
|
|
1897
|
+
* @param element - Element to enqueue.
|
|
1898
|
+
* @returns True on success.
|
|
1899
|
+
|
|
1900
|
+
|
|
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
|
+
* @example
|
|
1932
|
+
* // basic Queue creation and push operation
|
|
1933
|
+
* // Create a simple Queue with initial values
|
|
1934
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
1935
|
+
*
|
|
1936
|
+
* // Verify the queue maintains insertion order
|
|
1937
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
1938
|
+
*
|
|
1939
|
+
* // Check length
|
|
1940
|
+
* console.log(queue.length); // 5;
|
|
1941
|
+
*/
|
|
1199
1942
|
push(element) {
|
|
1200
1943
|
this.elements.push(element);
|
|
1201
1944
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -1216,10 +1959,56 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1216
1959
|
return ans;
|
|
1217
1960
|
}
|
|
1218
1961
|
/**
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1962
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1963
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1964
|
+
* @returns Removed element or undefined.
|
|
1965
|
+
|
|
1966
|
+
|
|
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
|
+
* @example
|
|
1998
|
+
* // Queue shift and peek operations
|
|
1999
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
2000
|
+
*
|
|
2001
|
+
* // Peek at the front element without removing it
|
|
2002
|
+
* console.log(queue.first); // 10;
|
|
2003
|
+
*
|
|
2004
|
+
* // Remove and get the first element (FIFO)
|
|
2005
|
+
* const first = queue.shift();
|
|
2006
|
+
* console.log(first); // 10;
|
|
2007
|
+
*
|
|
2008
|
+
* // Verify remaining elements and length decreased
|
|
2009
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
2010
|
+
* console.log(queue.length); // 3;
|
|
2011
|
+
*/
|
|
1223
2012
|
shift() {
|
|
1224
2013
|
if (this.length === 0) return void 0;
|
|
1225
2014
|
const first = this.first;
|
|
@@ -1228,11 +2017,45 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1228
2017
|
return first;
|
|
1229
2018
|
}
|
|
1230
2019
|
/**
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
2020
|
+
* Delete the first occurrence of a specific element.
|
|
2021
|
+
* @remarks Time O(N), Space O(1)
|
|
2022
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
2023
|
+
* @returns True if an element was removed.
|
|
2024
|
+
|
|
2025
|
+
|
|
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
|
+
* @example
|
|
2054
|
+
* // Remove specific element
|
|
2055
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
2056
|
+
* q.delete(2);
|
|
2057
|
+
* console.log(q.length); // 3;
|
|
2058
|
+
*/
|
|
1236
2059
|
delete(element) {
|
|
1237
2060
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
1238
2061
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -1243,11 +2066,45 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1243
2066
|
return false;
|
|
1244
2067
|
}
|
|
1245
2068
|
/**
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
2069
|
+
* Get the element at a given logical index.
|
|
2070
|
+
* @remarks Time O(1), Space O(1)
|
|
2071
|
+
* @param index - Zero-based index from the front.
|
|
2072
|
+
* @returns Element or undefined.
|
|
2073
|
+
|
|
2074
|
+
|
|
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
|
+
* @example
|
|
2103
|
+
* // Access element by index
|
|
2104
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
2105
|
+
* console.log(q.at(0)); // 'a';
|
|
2106
|
+
* console.log(q.at(2)); // 'c';
|
|
2107
|
+
*/
|
|
1251
2108
|
at(index) {
|
|
1252
2109
|
if (index < 0 || index >= this.length) return void 0;
|
|
1253
2110
|
return this._elements[this._offset + index];
|
|
@@ -1299,19 +2156,90 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1299
2156
|
return this;
|
|
1300
2157
|
}
|
|
1301
2158
|
/**
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
2159
|
+
* Remove all elements and reset offset.
|
|
2160
|
+
* @remarks Time O(1), Space O(1)
|
|
2161
|
+
* @returns void
|
|
2162
|
+
|
|
2163
|
+
|
|
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
|
+
* @example
|
|
2193
|
+
* // Remove all elements
|
|
2194
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2195
|
+
* q.clear();
|
|
2196
|
+
* console.log(q.length); // 0;
|
|
2197
|
+
*/
|
|
1306
2198
|
clear() {
|
|
1307
2199
|
this._elements = [];
|
|
1308
2200
|
this._offset = 0;
|
|
1309
2201
|
}
|
|
1310
2202
|
/**
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
2203
|
+
* Compact storage by discarding consumed head elements.
|
|
2204
|
+
* @remarks Time O(N), Space O(N)
|
|
2205
|
+
* @returns True when compaction performed.
|
|
2206
|
+
|
|
2207
|
+
|
|
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
|
+
* @example
|
|
2236
|
+
* // Reclaim unused memory
|
|
2237
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2238
|
+
* q.shift();
|
|
2239
|
+
* q.shift();
|
|
2240
|
+
* q.compact();
|
|
2241
|
+
* console.log(q.length); // 3;
|
|
2242
|
+
*/
|
|
1315
2243
|
compact() {
|
|
1316
2244
|
this._elements = this.elements.slice(this._offset);
|
|
1317
2245
|
this._offset = 0;
|
|
@@ -1337,10 +2265,47 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1337
2265
|
return removed;
|
|
1338
2266
|
}
|
|
1339
2267
|
/**
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
2268
|
+
* Deep clone this queue and its parameters.
|
|
2269
|
+
* @remarks Time O(N), Space O(N)
|
|
2270
|
+
* @returns A new queue with the same content and options.
|
|
2271
|
+
|
|
2272
|
+
|
|
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
|
+
* @example
|
|
2302
|
+
* // Create independent copy
|
|
2303
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2304
|
+
* const copy = q.clone();
|
|
2305
|
+
* copy.shift();
|
|
2306
|
+
* console.log(q.length); // 3;
|
|
2307
|
+
* console.log(copy.length); // 2;
|
|
2308
|
+
*/
|
|
1344
2309
|
clone() {
|
|
1345
2310
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1346
2311
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1348,12 +2313,47 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1348
2313
|
return out;
|
|
1349
2314
|
}
|
|
1350
2315
|
/**
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
2316
|
+
* Filter elements into a new queue of the same class.
|
|
2317
|
+
* @remarks Time O(N), Space O(N)
|
|
2318
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
2319
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
2320
|
+
* @returns A new queue with kept elements.
|
|
2321
|
+
|
|
2322
|
+
|
|
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
|
+
* @example
|
|
2352
|
+
* // Filter elements
|
|
2353
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2354
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
2355
|
+
* console.log(evens.length); // 2;
|
|
2356
|
+
*/
|
|
1357
2357
|
filter(predicate, thisArg) {
|
|
1358
2358
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1359
2359
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1365,15 +2365,49 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1365
2365
|
return out;
|
|
1366
2366
|
}
|
|
1367
2367
|
/**
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
2368
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
2369
|
+
* @remarks Time O(N), Space O(N)
|
|
2370
|
+
* @template EM
|
|
2371
|
+
* @template RM
|
|
2372
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
2373
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
2374
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
2375
|
+
* @returns A new Queue with mapped elements.
|
|
2376
|
+
|
|
2377
|
+
|
|
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
|
+
* @example
|
|
2406
|
+
* // Transform elements
|
|
2407
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2408
|
+
* const doubled = q.map(x => x * 2);
|
|
2409
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
2410
|
+
*/
|
|
1377
2411
|
map(callback, options, thisArg) {
|
|
1378
2412
|
var _a, _b;
|
|
1379
2413
|
const out = new this.constructor([], {
|
|
@@ -2473,12 +3507,49 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2473
3507
|
return new DirectedEdge(src, dest, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
|
|
2474
3508
|
}
|
|
2475
3509
|
/**
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
3510
|
+
* Get the unique edge from `src` to `dest`, if present.
|
|
3511
|
+
* @param srcOrKey - Source vertex or key.
|
|
3512
|
+
* @param destOrKey - Destination vertex or key.
|
|
3513
|
+
* @returns Edge instance or `undefined`.
|
|
3514
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3515
|
+
|
|
3516
|
+
|
|
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
|
+
* @example
|
|
3545
|
+
* // Get edge between vertices
|
|
3546
|
+
* const g = new DirectedGraph();
|
|
3547
|
+
* g.addVertex('A');
|
|
3548
|
+
* g.addVertex('B');
|
|
3549
|
+
* g.addEdge('A', 'B', 5);
|
|
3550
|
+
* const edge = g.getEdge('A', 'B');
|
|
3551
|
+
* console.log(edge?.weight); // 5;
|
|
3552
|
+
*/
|
|
2482
3553
|
getEdge(srcOrKey, destOrKey) {
|
|
2483
3554
|
let edgeMap = [];
|
|
2484
3555
|
if (srcOrKey !== void 0 && destOrKey !== void 0) {
|
|
@@ -2518,12 +3589,69 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2518
3589
|
return removed;
|
|
2519
3590
|
}
|
|
2520
3591
|
/**
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
3592
|
+
* Delete an edge by instance or by `(srcKey, destKey)`.
|
|
3593
|
+
* @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
|
|
3594
|
+
* @param destVertexKey - Optional destination vertex/key when deleting by pair.
|
|
3595
|
+
* @returns Removed edge or `undefined`.
|
|
3596
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3597
|
+
|
|
3598
|
+
|
|
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
|
+
* @example
|
|
3630
|
+
* // DirectedGraph deleteEdge and vertex operations
|
|
3631
|
+
* const graph = new DirectedGraph<string>();
|
|
3632
|
+
*
|
|
3633
|
+
* // Build a small graph
|
|
3634
|
+
* graph.addVertex('X');
|
|
3635
|
+
* graph.addVertex('Y');
|
|
3636
|
+
* graph.addVertex('Z');
|
|
3637
|
+
* graph.addEdge('X', 'Y', 1);
|
|
3638
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
3639
|
+
*
|
|
3640
|
+
* // Delete an edge
|
|
3641
|
+
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
3642
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
3643
|
+
*
|
|
3644
|
+
* // Edge in other direction should not exist
|
|
3645
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
3646
|
+
*
|
|
3647
|
+
* // Other edges should remain
|
|
3648
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
3649
|
+
*
|
|
3650
|
+
* // Delete a vertex
|
|
3651
|
+
* graph.deleteVertex('Y');
|
|
3652
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
3653
|
+
* console.log(graph.size); // 2;
|
|
3654
|
+
*/
|
|
2527
3655
|
deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
|
|
2528
3656
|
let removed = void 0;
|
|
2529
3657
|
let src, dest;
|
|
@@ -2550,6 +3678,47 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2550
3678
|
}
|
|
2551
3679
|
return removed;
|
|
2552
3680
|
}
|
|
3681
|
+
/**
|
|
3682
|
+
* Remove a vertex
|
|
3683
|
+
|
|
3684
|
+
|
|
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
|
+
* @example
|
|
3713
|
+
* // Remove a vertex
|
|
3714
|
+
* const g = new DirectedGraph();
|
|
3715
|
+
* g.addVertex('A');
|
|
3716
|
+
* g.addVertex('B');
|
|
3717
|
+
* g.addEdge('A', 'B');
|
|
3718
|
+
* g.deleteVertex('A');
|
|
3719
|
+
* console.log(g.hasVertex('A')); // false;
|
|
3720
|
+
* console.log(g.hasEdge('A', 'B')); // false;
|
|
3721
|
+
*/
|
|
2553
3722
|
deleteVertex(vertexOrKey) {
|
|
2554
3723
|
let vertexKey;
|
|
2555
3724
|
let vertex;
|
|
@@ -2581,11 +3750,49 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2581
3750
|
return removed;
|
|
2582
3751
|
}
|
|
2583
3752
|
/**
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
3753
|
+
* Incoming edges of a vertex.
|
|
3754
|
+
* @param vertexOrKey - Vertex or key.
|
|
3755
|
+
* @returns Array of incoming edges.
|
|
3756
|
+
* @remarks Time O(deg_in), Space O(deg_in)
|
|
3757
|
+
|
|
3758
|
+
|
|
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
|
+
* @example
|
|
3787
|
+
* // Get incoming edges
|
|
3788
|
+
* const g = new DirectedGraph();
|
|
3789
|
+
* g.addVertex('A');
|
|
3790
|
+
* g.addVertex('B');
|
|
3791
|
+
* g.addVertex('C');
|
|
3792
|
+
* g.addEdge('A', 'C');
|
|
3793
|
+
* g.addEdge('B', 'C');
|
|
3794
|
+
* console.log(g.incomingEdgesOf('C').length); // 2;
|
|
3795
|
+
*/
|
|
2589
3796
|
incomingEdgesOf(vertexOrKey) {
|
|
2590
3797
|
const target = this._getVertex(vertexOrKey);
|
|
2591
3798
|
if (target) {
|
|
@@ -2594,11 +3801,49 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2594
3801
|
return [];
|
|
2595
3802
|
}
|
|
2596
3803
|
/**
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
3804
|
+
* Outgoing edges of a vertex.
|
|
3805
|
+
* @param vertexOrKey - Vertex or key.
|
|
3806
|
+
* @returns Array of outgoing edges.
|
|
3807
|
+
* @remarks Time O(deg_out), Space O(deg_out)
|
|
3808
|
+
|
|
3809
|
+
|
|
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
|
+
* @example
|
|
3838
|
+
* // Get outgoing edges
|
|
3839
|
+
* const g = new DirectedGraph();
|
|
3840
|
+
* g.addVertex('A');
|
|
3841
|
+
* g.addVertex('B');
|
|
3842
|
+
* g.addVertex('C');
|
|
3843
|
+
* g.addEdge('A', 'B');
|
|
3844
|
+
* g.addEdge('A', 'C');
|
|
3845
|
+
* console.log(g.outgoingEdgesOf('A').length); // 2;
|
|
3846
|
+
*/
|
|
2602
3847
|
outgoingEdgesOf(vertexOrKey) {
|
|
2603
3848
|
const target = this._getVertex(vertexOrKey);
|
|
2604
3849
|
if (target) {
|
|
@@ -2657,11 +3902,65 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2657
3902
|
return destinations;
|
|
2658
3903
|
}
|
|
2659
3904
|
/**
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
3905
|
+
* Topological sort if DAG; returns `undefined` if a cycle exists.
|
|
3906
|
+
* @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
|
|
3907
|
+
* @returns Array of keys/vertices, or `undefined` when cycle is found.
|
|
3908
|
+
* @remarks Time O(V + E), Space O(V)
|
|
3909
|
+
|
|
3910
|
+
|
|
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
|
+
* @example
|
|
3942
|
+
* // DirectedGraph topologicalSort for task scheduling
|
|
3943
|
+
* const graph = new DirectedGraph<string>();
|
|
3944
|
+
*
|
|
3945
|
+
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
3946
|
+
* graph.addVertex('Design');
|
|
3947
|
+
* graph.addVertex('Implement');
|
|
3948
|
+
* graph.addVertex('Test');
|
|
3949
|
+
* graph.addVertex('Deploy');
|
|
3950
|
+
*
|
|
3951
|
+
* // Add dependency edges
|
|
3952
|
+
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
3953
|
+
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
3954
|
+
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
3955
|
+
*
|
|
3956
|
+
* // Topological sort gives valid execution order
|
|
3957
|
+
* const executionOrder = graph.topologicalSort();
|
|
3958
|
+
* console.log(executionOrder); // defined;
|
|
3959
|
+
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
3960
|
+
*
|
|
3961
|
+
* // All vertices should be included
|
|
3962
|
+
* console.log(executionOrder?.length); // 4;
|
|
3963
|
+
*/
|
|
2665
3964
|
topologicalSort(propertyName) {
|
|
2666
3965
|
propertyName = propertyName != null ? propertyName : "key";
|
|
2667
3966
|
const statusMap = /* @__PURE__ */ new Map();
|
|
@@ -2693,6 +3992,45 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2693
3992
|
if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
|
|
2694
3993
|
return sorted.reverse();
|
|
2695
3994
|
}
|
|
3995
|
+
/**
|
|
3996
|
+
* Get all edges
|
|
3997
|
+
|
|
3998
|
+
|
|
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
|
+
* @example
|
|
4027
|
+
* // Get all edges
|
|
4028
|
+
* const g = new DirectedGraph();
|
|
4029
|
+
* g.addVertex('A');
|
|
4030
|
+
* g.addVertex('B');
|
|
4031
|
+
* g.addEdge('A', 'B', 3);
|
|
4032
|
+
* console.log(g.edgeSet().length); // 1;
|
|
4033
|
+
*/
|
|
2696
4034
|
edgeSet() {
|
|
2697
4035
|
let edgeMap = [];
|
|
2698
4036
|
this._outEdgeMap.forEach((outEdges) => {
|
|
@@ -2700,6 +4038,49 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2700
4038
|
});
|
|
2701
4039
|
return edgeMap;
|
|
2702
4040
|
}
|
|
4041
|
+
/**
|
|
4042
|
+
* Get outgoing neighbors
|
|
4043
|
+
|
|
4044
|
+
|
|
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
|
+
* @example
|
|
4074
|
+
* // Get outgoing neighbors
|
|
4075
|
+
* const g = new DirectedGraph();
|
|
4076
|
+
* g.addVertex('A');
|
|
4077
|
+
* g.addVertex('B');
|
|
4078
|
+
* g.addVertex('C');
|
|
4079
|
+
* g.addEdge('A', 'B');
|
|
4080
|
+
* g.addEdge('A', 'C');
|
|
4081
|
+
* const neighbors = g.getNeighbors('A');
|
|
4082
|
+
* console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
|
|
4083
|
+
*/
|
|
2703
4084
|
getNeighbors(vertexOrKey) {
|
|
2704
4085
|
const neighbors = [];
|
|
2705
4086
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -2757,10 +4138,52 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2757
4138
|
return super.clone();
|
|
2758
4139
|
}
|
|
2759
4140
|
/**
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
4141
|
+
* Tarjan's algorithm for strongly connected components.
|
|
4142
|
+
* @returns `{ dfnMap, lowMap, SCCs }`.
|
|
4143
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
4144
|
+
|
|
4145
|
+
|
|
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
|
+
* @example
|
|
4174
|
+
* // Find strongly connected components
|
|
4175
|
+
* const g = new DirectedGraph();
|
|
4176
|
+
* g.addVertex('A');
|
|
4177
|
+
* g.addVertex('B');
|
|
4178
|
+
* g.addVertex('C');
|
|
4179
|
+
* g.addEdge('A', 'B');
|
|
4180
|
+
* g.addEdge('B', 'C');
|
|
4181
|
+
* g.addEdge('C', 'A');
|
|
4182
|
+
* const { SCCs } = g.tarjan();
|
|
4183
|
+
* // A→B→C→A forms one SCC with 3 members
|
|
4184
|
+
* const sccArrays = [...SCCs.values()];
|
|
4185
|
+
* console.log(sccArrays.some(scc => scc.length === 3)); // true;
|
|
4186
|
+
*/
|
|
2764
4187
|
tarjan() {
|
|
2765
4188
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
2766
4189
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -2818,10 +4241,50 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2818
4241
|
return this.tarjan().lowMap;
|
|
2819
4242
|
}
|
|
2820
4243
|
/**
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
4244
|
+
* Strongly connected components computed by `tarjan()`.
|
|
4245
|
+
* @returns Map from SCC id to vertices.
|
|
4246
|
+
* @remarks Time O(#SCC + V), Space O(V)
|
|
4247
|
+
|
|
4248
|
+
|
|
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
|
+
* @example
|
|
4277
|
+
* // Get strongly connected components
|
|
4278
|
+
* const g = new DirectedGraph();
|
|
4279
|
+
* g.addVertex(1);
|
|
4280
|
+
* g.addVertex(2);
|
|
4281
|
+
* g.addVertex(3);
|
|
4282
|
+
* g.addEdge(1, 2);
|
|
4283
|
+
* g.addEdge(2, 3);
|
|
4284
|
+
* g.addEdge(3, 1);
|
|
4285
|
+
* const sccs = g.getSCCs(); // Map<number, VO[]>
|
|
4286
|
+
* console.log(sccs.size); // >= 1;
|
|
4287
|
+
*/
|
|
2825
4288
|
getSCCs() {
|
|
2826
4289
|
return this.tarjan().SCCs;
|
|
2827
4290
|
}
|
|
@@ -2943,12 +4406,48 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2943
4406
|
return new UndirectedEdge(v1, v2, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
|
|
2944
4407
|
}
|
|
2945
4408
|
/**
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
4409
|
+
* Get an undirected edge between two vertices, if present.
|
|
4410
|
+
* @param v1 - One vertex or key.
|
|
4411
|
+
* @param v2 - The other vertex or key.
|
|
4412
|
+
* @returns Edge instance or `undefined`.
|
|
4413
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
4414
|
+
|
|
4415
|
+
|
|
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
|
+
* @example
|
|
4444
|
+
* // Get edge between vertices
|
|
4445
|
+
* const g = new UndirectedGraph();
|
|
4446
|
+
* g.addVertex('A');
|
|
4447
|
+
* g.addVertex('B');
|
|
4448
|
+
* g.addEdge('A', 'B', 7);
|
|
4449
|
+
* console.log(g.getEdge('A', 'B')?.weight); // 7;
|
|
4450
|
+
*/
|
|
2952
4451
|
getEdge(v1, v2) {
|
|
2953
4452
|
var _a;
|
|
2954
4453
|
let edgeMap = [];
|
|
@@ -2986,12 +4485,71 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2986
4485
|
return removed;
|
|
2987
4486
|
}
|
|
2988
4487
|
/**
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
4488
|
+
* Delete an edge by instance or by a pair of keys.
|
|
4489
|
+
* @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
|
|
4490
|
+
* @param otherSideVertexKey - Required second endpoint when deleting by pair.
|
|
4491
|
+
* @returns Removed edge or `undefined`.
|
|
4492
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
4493
|
+
|
|
4494
|
+
|
|
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
|
+
* @example
|
|
4526
|
+
* // UndirectedGraph deleteEdge and vertex operations
|
|
4527
|
+
* const graph = new UndirectedGraph<string>();
|
|
4528
|
+
*
|
|
4529
|
+
* // Build a simple undirected graph
|
|
4530
|
+
* graph.addVertex('X');
|
|
4531
|
+
* graph.addVertex('Y');
|
|
4532
|
+
* graph.addVertex('Z');
|
|
4533
|
+
* graph.addEdge('X', 'Y', 1);
|
|
4534
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
4535
|
+
* graph.addEdge('X', 'Z', 3);
|
|
4536
|
+
*
|
|
4537
|
+
* // Delete an edge
|
|
4538
|
+
* graph.deleteEdge('X', 'Y');
|
|
4539
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
4540
|
+
*
|
|
4541
|
+
* // Bidirectional deletion confirmed
|
|
4542
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
4543
|
+
*
|
|
4544
|
+
* // Other edges should remain
|
|
4545
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
4546
|
+
* console.log(graph.hasEdge('Z', 'Y')); // true;
|
|
4547
|
+
*
|
|
4548
|
+
* // Delete a vertex
|
|
4549
|
+
* graph.deleteVertex('Y');
|
|
4550
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
4551
|
+
* console.log(graph.size); // 2;
|
|
4552
|
+
*/
|
|
2995
4553
|
deleteEdge(edgeOrOneSideVertexKey, otherSideVertexKey) {
|
|
2996
4554
|
let oneSide, otherSide;
|
|
2997
4555
|
if (this.isVertexKey(edgeOrOneSideVertexKey)) {
|
|
@@ -3012,11 +4570,48 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3012
4570
|
}
|
|
3013
4571
|
}
|
|
3014
4572
|
/**
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
4573
|
+
* Delete a vertex and remove it from all neighbor lists.
|
|
4574
|
+
* @param vertexOrKey - Vertex or key.
|
|
4575
|
+
* @returns `true` if removed; otherwise `false`.
|
|
4576
|
+
* @remarks Time O(deg), Space O(1)
|
|
4577
|
+
|
|
4578
|
+
|
|
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
|
+
* @example
|
|
4607
|
+
* // Remove vertex and edges
|
|
4608
|
+
* const g = new UndirectedGraph();
|
|
4609
|
+
* g.addVertex('A');
|
|
4610
|
+
* g.addVertex('B');
|
|
4611
|
+
* g.addEdge('A', 'B');
|
|
4612
|
+
* g.deleteVertex('A');
|
|
4613
|
+
* console.log(g.hasVertex('A')); // false;
|
|
4614
|
+
*/
|
|
3020
4615
|
deleteVertex(vertexOrKey) {
|
|
3021
4616
|
let vertexKey;
|
|
3022
4617
|
let vertex;
|
|
@@ -3072,10 +4667,46 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3072
4667
|
}
|
|
3073
4668
|
}
|
|
3074
4669
|
/**
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
4670
|
+
* Unique set of undirected edges across endpoints.
|
|
4671
|
+
* @returns Array of edges.
|
|
4672
|
+
* @remarks Time O(E), Space O(E)
|
|
4673
|
+
|
|
4674
|
+
|
|
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
|
+
* @example
|
|
4703
|
+
* // Get all edges
|
|
4704
|
+
* const g = new UndirectedGraph();
|
|
4705
|
+
* g.addVertex('A');
|
|
4706
|
+
* g.addVertex('B');
|
|
4707
|
+
* g.addEdge('A', 'B');
|
|
4708
|
+
* console.log(g.edgeSet().length); // 1;
|
|
4709
|
+
*/
|
|
3079
4710
|
edgeSet() {
|
|
3080
4711
|
const edgeSet = /* @__PURE__ */ new Set();
|
|
3081
4712
|
this._edgeMap.forEach((edgeMap) => {
|
|
@@ -3085,6 +4716,73 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3085
4716
|
});
|
|
3086
4717
|
return [...edgeSet];
|
|
3087
4718
|
}
|
|
4719
|
+
/**
|
|
4720
|
+
* UndirectedGraph connectivity and neighbors
|
|
4721
|
+
|
|
4722
|
+
|
|
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
|
+
* @example
|
|
4754
|
+
* // UndirectedGraph connectivity and neighbors
|
|
4755
|
+
* const graph = new UndirectedGraph<string>();
|
|
4756
|
+
*
|
|
4757
|
+
* // Build a friendship network
|
|
4758
|
+
* const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
|
|
4759
|
+
* for (const person of people) {
|
|
4760
|
+
* graph.addVertex(person);
|
|
4761
|
+
* }
|
|
4762
|
+
*
|
|
4763
|
+
* // Add friendships (undirected edges)
|
|
4764
|
+
* graph.addEdge('Alice', 'Bob', 1);
|
|
4765
|
+
* graph.addEdge('Alice', 'Charlie', 1);
|
|
4766
|
+
* graph.addEdge('Bob', 'Diana', 1);
|
|
4767
|
+
* graph.addEdge('Charlie', 'Eve', 1);
|
|
4768
|
+
* graph.addEdge('Diana', 'Eve', 1);
|
|
4769
|
+
*
|
|
4770
|
+
* // Get friends of each person
|
|
4771
|
+
* const aliceFriends = graph.getNeighbors('Alice');
|
|
4772
|
+
* console.log(aliceFriends[0].key); // 'Bob';
|
|
4773
|
+
* console.log(aliceFriends[1].key); // 'Charlie';
|
|
4774
|
+
* console.log(aliceFriends.length); // 2;
|
|
4775
|
+
*
|
|
4776
|
+
* const dianaFriends = graph.getNeighbors('Diana');
|
|
4777
|
+
* console.log(dianaFriends[0].key); // 'Bob';
|
|
4778
|
+
* console.log(dianaFriends[1].key); // 'Eve';
|
|
4779
|
+
* console.log(dianaFriends.length); // 2;
|
|
4780
|
+
*
|
|
4781
|
+
* // Verify bidirectional friendship
|
|
4782
|
+
* const bobFriends = graph.getNeighbors('Bob');
|
|
4783
|
+
* console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
|
|
4784
|
+
* console.log(bobFriends[1].key); // 'Diana';
|
|
4785
|
+
*/
|
|
3088
4786
|
getNeighbors(vertexOrKey) {
|
|
3089
4787
|
const neighbors = [];
|
|
3090
4788
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -3141,10 +4839,49 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3141
4839
|
return super.clone();
|
|
3142
4840
|
}
|
|
3143
4841
|
/**
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
4842
|
+
* Tarjan-based bridge and articulation point detection.
|
|
4843
|
+
* @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
|
|
4844
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
4845
|
+
|
|
4846
|
+
|
|
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
|
+
* @example
|
|
4875
|
+
* // Find articulation points and bridges
|
|
4876
|
+
* const g = new UndirectedGraph();
|
|
4877
|
+
* g.addVertex('A');
|
|
4878
|
+
* g.addVertex('B');
|
|
4879
|
+
* g.addVertex('C');
|
|
4880
|
+
* g.addEdge('A', 'B');
|
|
4881
|
+
* g.addEdge('B', 'C');
|
|
4882
|
+
* const result = g.tarjan();
|
|
4883
|
+
* console.log(result); // defined;
|
|
4884
|
+
*/
|
|
3148
4885
|
tarjan() {
|
|
3149
4886
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
3150
4887
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -3244,11 +4981,51 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3244
4981
|
return components;
|
|
3245
4982
|
}
|
|
3246
4983
|
/**
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
4984
|
+
* Detect whether the graph contains a cycle.
|
|
4985
|
+
* Uses DFS with parent tracking.
|
|
4986
|
+
* @returns `true` if a cycle exists, `false` otherwise.
|
|
4987
|
+
* @remarks Time O(V + E), Space O(V)
|
|
4988
|
+
|
|
4989
|
+
|
|
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
|
+
* @example
|
|
5018
|
+
* // Detect cycle
|
|
5019
|
+
* const g = new UndirectedGraph();
|
|
5020
|
+
* g.addVertex('A');
|
|
5021
|
+
* g.addVertex('B');
|
|
5022
|
+
* g.addVertex('C');
|
|
5023
|
+
* g.addEdge('A', 'B');
|
|
5024
|
+
* g.addEdge('B', 'C');
|
|
5025
|
+
* console.log(g.hasCycle()); // false;
|
|
5026
|
+
* g.addEdge('C', 'A');
|
|
5027
|
+
* console.log(g.hasCycle()); // true;
|
|
5028
|
+
*/
|
|
3252
5029
|
hasCycle() {
|
|
3253
5030
|
const visited = /* @__PURE__ */ new Set();
|
|
3254
5031
|
const dfs = /* @__PURE__ */ __name((vertex, parent) => {
|
|
@@ -3270,18 +5047,97 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3270
5047
|
return false;
|
|
3271
5048
|
}
|
|
3272
5049
|
/**
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
5050
|
+
* Get bridges discovered by `tarjan()`.
|
|
5051
|
+
* @returns Array of edges that are bridges.
|
|
5052
|
+
* @remarks Time O(B), Space O(1)
|
|
5053
|
+
|
|
5054
|
+
|
|
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
|
+
* @example
|
|
5083
|
+
* // Find bridge edges
|
|
5084
|
+
* const g = new UndirectedGraph();
|
|
5085
|
+
* g.addVertex('A');
|
|
5086
|
+
* g.addVertex('B');
|
|
5087
|
+
* g.addVertex('C');
|
|
5088
|
+
* g.addEdge('A', 'B');
|
|
5089
|
+
* g.addEdge('B', 'C');
|
|
5090
|
+
* const bridges = g.getBridges();
|
|
5091
|
+
* console.log(bridges.length); // 2;
|
|
5092
|
+
*/
|
|
3277
5093
|
getBridges() {
|
|
3278
5094
|
return this.tarjan().bridges;
|
|
3279
5095
|
}
|
|
3280
5096
|
/**
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
5097
|
+
* Get articulation points discovered by `tarjan()`.
|
|
5098
|
+
* @returns Array of cut vertices.
|
|
5099
|
+
* @remarks Time O(C), Space O(1)
|
|
5100
|
+
|
|
5101
|
+
|
|
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
|
+
* @example
|
|
5130
|
+
* // Find articulation points
|
|
5131
|
+
* const g = new UndirectedGraph();
|
|
5132
|
+
* g.addVertex('A');
|
|
5133
|
+
* g.addVertex('B');
|
|
5134
|
+
* g.addVertex('C');
|
|
5135
|
+
* g.addEdge('A', 'B');
|
|
5136
|
+
* g.addEdge('B', 'C');
|
|
5137
|
+
* const cuts = g.getCutVertices();
|
|
5138
|
+
* console.log(cuts.length); // 1;
|
|
5139
|
+
* console.log(cuts[0].key); // 'B';
|
|
5140
|
+
*/
|
|
3285
5141
|
getCutVertices() {
|
|
3286
5142
|
return this.tarjan().cutVertices;
|
|
3287
5143
|
}
|