graph-typed 2.4.5 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +1112 -201
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +1112 -201
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1112 -201
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +1112 -201
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +429 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +212 -32
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/directed-graph.d.ts +219 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +204 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +272 -65
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/umd/graph-typed.js +1112 -201
- package/dist/umd/graph-typed.js.map +1 -1
- package/dist/umd/graph-typed.min.js +2 -2
- package/dist/umd/graph-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +302 -247
- package/src/data-structures/binary-tree/binary-tree.ts +429 -79
- package/src/data-structures/binary-tree/bst.ts +335 -34
- package/src/data-structures/binary-tree/red-black-tree.ts +290 -97
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1284 -6
- package/src/data-structures/binary-tree/tree-multi-map.ts +1094 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +858 -65
- package/src/data-structures/binary-tree/tree-set.ts +1136 -9
- package/src/data-structures/graph/directed-graph.ts +219 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +204 -59
- package/src/data-structures/hash/hash-map.ts +230 -77
- package/src/data-structures/heap/heap.ts +287 -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 +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +416 -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 +272 -65
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +213 -43
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
package/dist/umd/graph-typed.js
CHANGED
|
@@ -308,7 +308,7 @@ var graphTyped = (() => {
|
|
|
308
308
|
if (options) {
|
|
309
309
|
const { toElementFn } = options;
|
|
310
310
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
311
|
-
else if (toElementFn) throw new TypeError(
|
|
311
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
312
312
|
}
|
|
313
313
|
}
|
|
314
314
|
/**
|
|
@@ -464,7 +464,7 @@ var graphTyped = (() => {
|
|
|
464
464
|
acc = initialValue;
|
|
465
465
|
} else {
|
|
466
466
|
const first = iter.next();
|
|
467
|
-
if (first.done) throw new TypeError(
|
|
467
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
468
468
|
acc = first.value;
|
|
469
469
|
index = 1;
|
|
470
470
|
}
|
|
@@ -543,10 +543,30 @@ var graphTyped = (() => {
|
|
|
543
543
|
return this._elements;
|
|
544
544
|
}
|
|
545
545
|
/**
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
546
|
+
* Get the number of elements.
|
|
547
|
+
* @remarks Time O(1), Space O(1)
|
|
548
|
+
* @returns Heap size.
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
* @example
|
|
561
|
+
* // Track heap capacity
|
|
562
|
+
* const heap = new Heap<number>();
|
|
563
|
+
* console.log(heap.size); // 0;
|
|
564
|
+
* heap.add(10);
|
|
565
|
+
* heap.add(20);
|
|
566
|
+
* console.log(heap.size); // 2;
|
|
567
|
+
* heap.poll();
|
|
568
|
+
* console.log(heap.size); // 1;
|
|
569
|
+
*/
|
|
550
570
|
get size() {
|
|
551
571
|
return this.elements.length;
|
|
552
572
|
}
|
|
@@ -585,21 +605,61 @@ var graphTyped = (() => {
|
|
|
585
605
|
return new _Heap(elements, options);
|
|
586
606
|
}
|
|
587
607
|
/**
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
608
|
+
* Insert an element.
|
|
609
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
610
|
+
* @param element - Element to insert.
|
|
611
|
+
* @returns True.
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
* @example
|
|
624
|
+
* // basic Heap creation and add operation
|
|
625
|
+
* // Create a min heap (default)
|
|
626
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
627
|
+
*
|
|
628
|
+
* // Verify size
|
|
629
|
+
* console.log(minHeap.size); // 6;
|
|
630
|
+
*
|
|
631
|
+
* // Add new element
|
|
632
|
+
* minHeap.add(4);
|
|
633
|
+
* console.log(minHeap.size); // 7;
|
|
634
|
+
*
|
|
635
|
+
* // Min heap property: smallest element at root
|
|
636
|
+
* const min = minHeap.peek();
|
|
637
|
+
* console.log(min); // 1;
|
|
638
|
+
*/
|
|
593
639
|
add(element) {
|
|
594
640
|
this._elements.push(element);
|
|
595
641
|
return this._bubbleUp(this.elements.length - 1);
|
|
596
642
|
}
|
|
597
643
|
/**
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
644
|
+
* Insert many elements from an iterable.
|
|
645
|
+
* @remarks Time O(N log N), Space O(1)
|
|
646
|
+
* @param elements - Iterable of elements or raw values.
|
|
647
|
+
* @returns Array of per-element success flags.
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
* @example
|
|
657
|
+
* // Add multiple elements
|
|
658
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
659
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
660
|
+
* console.log(heap.peek()); // 1;
|
|
661
|
+
* console.log(heap.size); // 4;
|
|
662
|
+
*/
|
|
603
663
|
addMany(elements) {
|
|
604
664
|
const flags = [];
|
|
605
665
|
for (const el of elements) {
|
|
@@ -614,10 +674,46 @@ var graphTyped = (() => {
|
|
|
614
674
|
return flags;
|
|
615
675
|
}
|
|
616
676
|
/**
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
677
|
+
* Remove and return the top element.
|
|
678
|
+
* @remarks Time O(log N), Space O(1)
|
|
679
|
+
* @returns Top element or undefined.
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
* @example
|
|
692
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
693
|
+
* interface Task {
|
|
694
|
+
* id: number;
|
|
695
|
+
* priority: number;
|
|
696
|
+
* name: string;
|
|
697
|
+
* }
|
|
698
|
+
*
|
|
699
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
700
|
+
* const tasks: Task[] = [
|
|
701
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
702
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
703
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
704
|
+
* ];
|
|
705
|
+
*
|
|
706
|
+
* const maxHeap = new Heap(tasks, {
|
|
707
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
708
|
+
* });
|
|
709
|
+
*
|
|
710
|
+
* console.log(maxHeap.size); // 3;
|
|
711
|
+
*
|
|
712
|
+
* // Peek returns highest priority task
|
|
713
|
+
* const topTask = maxHeap.peek();
|
|
714
|
+
* console.log(topTask?.priority); // 8;
|
|
715
|
+
* console.log(topTask?.name); // 'Alert';
|
|
716
|
+
*/
|
|
621
717
|
poll() {
|
|
622
718
|
if (this.elements.length === 0) return;
|
|
623
719
|
const value = this.elements[0];
|
|
@@ -629,26 +725,125 @@ var graphTyped = (() => {
|
|
|
629
725
|
return value;
|
|
630
726
|
}
|
|
631
727
|
/**
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
728
|
+
* Get the current top element without removing it.
|
|
729
|
+
* @remarks Time O(1), Space O(1)
|
|
730
|
+
* @returns Top element or undefined.
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
* @example
|
|
743
|
+
* // Heap for event processing with priority
|
|
744
|
+
* interface Event {
|
|
745
|
+
* id: number;
|
|
746
|
+
* type: 'critical' | 'warning' | 'info';
|
|
747
|
+
* timestamp: number;
|
|
748
|
+
* message: string;
|
|
749
|
+
* }
|
|
750
|
+
*
|
|
751
|
+
* // Custom priority: critical > warning > info
|
|
752
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
753
|
+
*
|
|
754
|
+
* const eventHeap = new Heap<Event>([], {
|
|
755
|
+
* comparator: (a: Event, b: Event) => {
|
|
756
|
+
* const priorityA = priorityMap[a.type];
|
|
757
|
+
* const priorityB = priorityMap[b.type];
|
|
758
|
+
* return priorityB - priorityA; // Higher priority first
|
|
759
|
+
* }
|
|
760
|
+
* });
|
|
761
|
+
*
|
|
762
|
+
* // Add events in random order
|
|
763
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
764
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
765
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
766
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
767
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
768
|
+
*
|
|
769
|
+
* console.log(eventHeap.size); // 5;
|
|
770
|
+
*
|
|
771
|
+
* // Process events by priority (critical first)
|
|
772
|
+
* const processedOrder: Event[] = [];
|
|
773
|
+
* while (eventHeap.size > 0) {
|
|
774
|
+
* const event = eventHeap.poll();
|
|
775
|
+
* if (event) {
|
|
776
|
+
* processedOrder.push(event);
|
|
777
|
+
* }
|
|
778
|
+
* }
|
|
779
|
+
*
|
|
780
|
+
* // Verify critical events came first
|
|
781
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
782
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
783
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
784
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
785
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
786
|
+
*
|
|
787
|
+
* // Verify O(log n) operations
|
|
788
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
789
|
+
*
|
|
790
|
+
* // Add - O(log n)
|
|
791
|
+
* newHeap.add(2);
|
|
792
|
+
* console.log(newHeap.size); // 5;
|
|
793
|
+
*
|
|
794
|
+
* // Poll - O(log n)
|
|
795
|
+
* const removed = newHeap.poll();
|
|
796
|
+
* console.log(removed); // 1;
|
|
797
|
+
*
|
|
798
|
+
* // Peek - O(1)
|
|
799
|
+
* const top = newHeap.peek();
|
|
800
|
+
* console.log(top); // 2;
|
|
801
|
+
*/
|
|
636
802
|
peek() {
|
|
637
803
|
return this.elements[0];
|
|
638
804
|
}
|
|
639
805
|
/**
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
806
|
+
* Check whether the heap is empty.
|
|
807
|
+
* @remarks Time O(1), Space O(1)
|
|
808
|
+
* @returns True if size is 0.
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
* @example
|
|
819
|
+
* // Check if heap is empty
|
|
820
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
821
|
+
* console.log(heap.isEmpty()); // true;
|
|
822
|
+
* heap.add(1);
|
|
823
|
+
* console.log(heap.isEmpty()); // false;
|
|
824
|
+
*/
|
|
644
825
|
isEmpty() {
|
|
645
826
|
return this.size === 0;
|
|
646
827
|
}
|
|
647
828
|
/**
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
829
|
+
* Remove all elements.
|
|
830
|
+
* @remarks Time O(1), Space O(1)
|
|
831
|
+
* @returns void
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
* @example
|
|
842
|
+
* // Remove all elements
|
|
843
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
844
|
+
* heap.clear();
|
|
845
|
+
* console.log(heap.isEmpty()); // true;
|
|
846
|
+
*/
|
|
652
847
|
clear() {
|
|
653
848
|
this._elements = [];
|
|
654
849
|
}
|
|
@@ -663,21 +858,41 @@ var graphTyped = (() => {
|
|
|
663
858
|
return this.fix();
|
|
664
859
|
}
|
|
665
860
|
/**
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
861
|
+
* Check if an equal element exists in the heap.
|
|
862
|
+
* @remarks Time O(N), Space O(1)
|
|
863
|
+
* @param element - Element to search for.
|
|
864
|
+
* @returns True if found.
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
* @example
|
|
868
|
+
* // Check element existence
|
|
869
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
870
|
+
* console.log(heap.has(1)); // true;
|
|
871
|
+
* console.log(heap.has(99)); // false;
|
|
872
|
+
*/
|
|
671
873
|
has(element) {
|
|
672
874
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
673
875
|
return false;
|
|
674
876
|
}
|
|
675
877
|
/**
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
878
|
+
* Delete one occurrence of an element.
|
|
879
|
+
* @remarks Time O(N), Space O(1)
|
|
880
|
+
* @param element - Element to delete.
|
|
881
|
+
* @returns True if an element was removed.
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
* @example
|
|
891
|
+
* // Remove specific element
|
|
892
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
893
|
+
* heap.delete(4);
|
|
894
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
895
|
+
*/
|
|
681
896
|
delete(element) {
|
|
682
897
|
let index = -1;
|
|
683
898
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -735,11 +950,18 @@ var graphTyped = (() => {
|
|
|
735
950
|
return this;
|
|
736
951
|
}
|
|
737
952
|
/**
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
953
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
954
|
+
* @remarks Time O(N), Space O(H)
|
|
955
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
956
|
+
* @returns Array of visited elements.
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
* @example
|
|
960
|
+
* // Depth-first traversal
|
|
961
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
962
|
+
* const result = heap.dfs('IN');
|
|
963
|
+
* console.log(result.length); // 3;
|
|
964
|
+
*/
|
|
743
965
|
dfs(order = "PRE") {
|
|
744
966
|
const result = [];
|
|
745
967
|
const _dfs = (index) => {
|
|
@@ -776,10 +998,26 @@ var graphTyped = (() => {
|
|
|
776
998
|
return results;
|
|
777
999
|
}
|
|
778
1000
|
/**
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
1001
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
1002
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1003
|
+
* @returns Sorted array of elements.
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
* @example
|
|
1016
|
+
* // Sort elements using heap
|
|
1017
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
1018
|
+
* const sorted = heap.sort();
|
|
1019
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
1020
|
+
*/
|
|
783
1021
|
sort() {
|
|
784
1022
|
const visited = [];
|
|
785
1023
|
const cloned = this._createInstance();
|
|
@@ -791,22 +1029,52 @@ var graphTyped = (() => {
|
|
|
791
1029
|
return visited;
|
|
792
1030
|
}
|
|
793
1031
|
/**
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
1032
|
+
* Deep clone this heap.
|
|
1033
|
+
* @remarks Time O(N), Space O(N)
|
|
1034
|
+
* @returns A new heap with the same elements.
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
* @example
|
|
1045
|
+
* // Create independent copy
|
|
1046
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
1047
|
+
* const copy = heap.clone();
|
|
1048
|
+
* copy.poll();
|
|
1049
|
+
* console.log(heap.size); // 3;
|
|
1050
|
+
* console.log(copy.size); // 2;
|
|
1051
|
+
*/
|
|
798
1052
|
clone() {
|
|
799
1053
|
const next = this._createInstance();
|
|
800
1054
|
for (const x of this.elements) next.add(x);
|
|
801
1055
|
return next;
|
|
802
1056
|
}
|
|
803
1057
|
/**
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
1058
|
+
* Filter elements into a new heap of the same class.
|
|
1059
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1060
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
1061
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1062
|
+
* @returns A new heap with the kept elements.
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
* @example
|
|
1073
|
+
* // Filter elements
|
|
1074
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
1075
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
1076
|
+
* console.log(evens.size); // 2;
|
|
1077
|
+
*/
|
|
810
1078
|
filter(callback, thisArg) {
|
|
811
1079
|
const out = this._createInstance();
|
|
812
1080
|
let i = 0;
|
|
@@ -820,15 +1088,28 @@ var graphTyped = (() => {
|
|
|
820
1088
|
return out;
|
|
821
1089
|
}
|
|
822
1090
|
/**
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
1091
|
+
* Map elements into a new heap of possibly different element type.
|
|
1092
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1093
|
+
* @template EM
|
|
1094
|
+
* @template RM
|
|
1095
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
1096
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
1097
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1098
|
+
* @returns A new heap with mapped elements.
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
|
|
1107
|
+
* @example
|
|
1108
|
+
* // Transform elements
|
|
1109
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1110
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
1111
|
+
* console.log(doubled.peek()); // 2;
|
|
1112
|
+
*/
|
|
832
1113
|
map(callback, options, thisArg) {
|
|
833
1114
|
const { comparator, toElementFn, ...rest } = options != null ? options : {};
|
|
834
1115
|
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
@@ -1176,18 +1457,52 @@ var graphTyped = (() => {
|
|
|
1176
1457
|
this._autoCompactRatio = value;
|
|
1177
1458
|
}
|
|
1178
1459
|
/**
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1460
|
+
* Get the number of elements currently in the queue.
|
|
1461
|
+
* @remarks Time O(1), Space O(1)
|
|
1462
|
+
* @returns Current length.
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
|
|
1470
|
+
|
|
1471
|
+
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
* @example
|
|
1475
|
+
* // Track queue length
|
|
1476
|
+
* const q = new Queue<number>();
|
|
1477
|
+
* console.log(q.length); // 0;
|
|
1478
|
+
* q.push(1);
|
|
1479
|
+
* q.push(2);
|
|
1480
|
+
* console.log(q.length); // 2;
|
|
1481
|
+
*/
|
|
1183
1482
|
get length() {
|
|
1184
1483
|
return this.elements.length - this._offset;
|
|
1185
1484
|
}
|
|
1186
1485
|
/**
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1486
|
+
* Get the first element (front) without removing it.
|
|
1487
|
+
* @remarks Time O(1), Space O(1)
|
|
1488
|
+
* @returns Front element or undefined.
|
|
1489
|
+
|
|
1490
|
+
|
|
1491
|
+
|
|
1492
|
+
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
* @example
|
|
1501
|
+
* // View the front element
|
|
1502
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
1503
|
+
* console.log(q.first); // 'first';
|
|
1504
|
+
* console.log(q.length); // 3;
|
|
1505
|
+
*/
|
|
1191
1506
|
get first() {
|
|
1192
1507
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
1193
1508
|
}
|
|
@@ -1210,19 +1525,69 @@ var graphTyped = (() => {
|
|
|
1210
1525
|
return new _Queue(elements);
|
|
1211
1526
|
}
|
|
1212
1527
|
/**
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1528
|
+
* Check whether the queue is empty.
|
|
1529
|
+
* @remarks Time O(1), Space O(1)
|
|
1530
|
+
* @returns True if length is 0.
|
|
1531
|
+
|
|
1532
|
+
|
|
1533
|
+
|
|
1534
|
+
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
* @example
|
|
1543
|
+
* // Queue for...of iteration and isEmpty check
|
|
1544
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
1545
|
+
*
|
|
1546
|
+
* const elements: string[] = [];
|
|
1547
|
+
* for (const item of queue) {
|
|
1548
|
+
* elements.push(item);
|
|
1549
|
+
* }
|
|
1550
|
+
*
|
|
1551
|
+
* // Verify all elements are iterated in order
|
|
1552
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
1553
|
+
*
|
|
1554
|
+
* // Process all elements
|
|
1555
|
+
* while (queue.length > 0) {
|
|
1556
|
+
* queue.shift();
|
|
1557
|
+
* }
|
|
1558
|
+
*
|
|
1559
|
+
* console.log(queue.length); // 0;
|
|
1560
|
+
*/
|
|
1217
1561
|
isEmpty() {
|
|
1218
1562
|
return this.length === 0;
|
|
1219
1563
|
}
|
|
1220
1564
|
/**
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1565
|
+
* Enqueue one element at the back.
|
|
1566
|
+
* @remarks Time O(1), Space O(1)
|
|
1567
|
+
* @param element - Element to enqueue.
|
|
1568
|
+
* @returns True on success.
|
|
1569
|
+
|
|
1570
|
+
|
|
1571
|
+
|
|
1572
|
+
|
|
1573
|
+
|
|
1574
|
+
|
|
1575
|
+
|
|
1576
|
+
|
|
1577
|
+
|
|
1578
|
+
|
|
1579
|
+
|
|
1580
|
+
* @example
|
|
1581
|
+
* // basic Queue creation and push operation
|
|
1582
|
+
* // Create a simple Queue with initial values
|
|
1583
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
1584
|
+
*
|
|
1585
|
+
* // Verify the queue maintains insertion order
|
|
1586
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
1587
|
+
*
|
|
1588
|
+
* // Check length
|
|
1589
|
+
* console.log(queue.length); // 5;
|
|
1590
|
+
*/
|
|
1226
1591
|
push(element) {
|
|
1227
1592
|
this.elements.push(element);
|
|
1228
1593
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -1243,10 +1608,35 @@ var graphTyped = (() => {
|
|
|
1243
1608
|
return ans;
|
|
1244
1609
|
}
|
|
1245
1610
|
/**
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1611
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1612
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1613
|
+
* @returns Removed element or undefined.
|
|
1614
|
+
|
|
1615
|
+
|
|
1616
|
+
|
|
1617
|
+
|
|
1618
|
+
|
|
1619
|
+
|
|
1620
|
+
|
|
1621
|
+
|
|
1622
|
+
|
|
1623
|
+
|
|
1624
|
+
|
|
1625
|
+
* @example
|
|
1626
|
+
* // Queue shift and peek operations
|
|
1627
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
1628
|
+
*
|
|
1629
|
+
* // Peek at the front element without removing it
|
|
1630
|
+
* console.log(queue.first); // 10;
|
|
1631
|
+
*
|
|
1632
|
+
* // Remove and get the first element (FIFO)
|
|
1633
|
+
* const first = queue.shift();
|
|
1634
|
+
* console.log(first); // 10;
|
|
1635
|
+
*
|
|
1636
|
+
* // Verify remaining elements and length decreased
|
|
1637
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
1638
|
+
* console.log(queue.length); // 3;
|
|
1639
|
+
*/
|
|
1250
1640
|
shift() {
|
|
1251
1641
|
if (this.length === 0) return void 0;
|
|
1252
1642
|
const first = this.first;
|
|
@@ -1255,11 +1645,24 @@ var graphTyped = (() => {
|
|
|
1255
1645
|
return first;
|
|
1256
1646
|
}
|
|
1257
1647
|
/**
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1648
|
+
* Delete the first occurrence of a specific element.
|
|
1649
|
+
* @remarks Time O(N), Space O(1)
|
|
1650
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
1651
|
+
* @returns True if an element was removed.
|
|
1652
|
+
|
|
1653
|
+
|
|
1654
|
+
|
|
1655
|
+
|
|
1656
|
+
|
|
1657
|
+
|
|
1658
|
+
|
|
1659
|
+
|
|
1660
|
+
* @example
|
|
1661
|
+
* // Remove specific element
|
|
1662
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
1663
|
+
* q.delete(2);
|
|
1664
|
+
* console.log(q.length); // 3;
|
|
1665
|
+
*/
|
|
1263
1666
|
delete(element) {
|
|
1264
1667
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
1265
1668
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -1270,11 +1673,24 @@ var graphTyped = (() => {
|
|
|
1270
1673
|
return false;
|
|
1271
1674
|
}
|
|
1272
1675
|
/**
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1676
|
+
* Get the element at a given logical index.
|
|
1677
|
+
* @remarks Time O(1), Space O(1)
|
|
1678
|
+
* @param index - Zero-based index from the front.
|
|
1679
|
+
* @returns Element or undefined.
|
|
1680
|
+
|
|
1681
|
+
|
|
1682
|
+
|
|
1683
|
+
|
|
1684
|
+
|
|
1685
|
+
|
|
1686
|
+
|
|
1687
|
+
|
|
1688
|
+
* @example
|
|
1689
|
+
* // Access element by index
|
|
1690
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
1691
|
+
* console.log(q.at(0)); // 'a';
|
|
1692
|
+
* console.log(q.at(2)); // 'c';
|
|
1693
|
+
*/
|
|
1278
1694
|
at(index) {
|
|
1279
1695
|
if (index < 0 || index >= this.length) return void 0;
|
|
1280
1696
|
return this._elements[this._offset + index];
|
|
@@ -1326,19 +1742,48 @@ var graphTyped = (() => {
|
|
|
1326
1742
|
return this;
|
|
1327
1743
|
}
|
|
1328
1744
|
/**
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1745
|
+
* Remove all elements and reset offset.
|
|
1746
|
+
* @remarks Time O(1), Space O(1)
|
|
1747
|
+
* @returns void
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
* @example
|
|
1758
|
+
* // Remove all elements
|
|
1759
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1760
|
+
* q.clear();
|
|
1761
|
+
* console.log(q.length); // 0;
|
|
1762
|
+
*/
|
|
1333
1763
|
clear() {
|
|
1334
1764
|
this._elements = [];
|
|
1335
1765
|
this._offset = 0;
|
|
1336
1766
|
}
|
|
1337
1767
|
/**
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1768
|
+
* Compact storage by discarding consumed head elements.
|
|
1769
|
+
* @remarks Time O(N), Space O(N)
|
|
1770
|
+
* @returns True when compaction performed.
|
|
1771
|
+
|
|
1772
|
+
|
|
1773
|
+
|
|
1774
|
+
|
|
1775
|
+
|
|
1776
|
+
|
|
1777
|
+
|
|
1778
|
+
|
|
1779
|
+
* @example
|
|
1780
|
+
* // Reclaim unused memory
|
|
1781
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1782
|
+
* q.shift();
|
|
1783
|
+
* q.shift();
|
|
1784
|
+
* q.compact();
|
|
1785
|
+
* console.log(q.length); // 3;
|
|
1786
|
+
*/
|
|
1342
1787
|
compact() {
|
|
1343
1788
|
this._elements = this.elements.slice(this._offset);
|
|
1344
1789
|
this._offset = 0;
|
|
@@ -1364,10 +1809,26 @@ var graphTyped = (() => {
|
|
|
1364
1809
|
return removed;
|
|
1365
1810
|
}
|
|
1366
1811
|
/**
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1812
|
+
* Deep clone this queue and its parameters.
|
|
1813
|
+
* @remarks Time O(N), Space O(N)
|
|
1814
|
+
* @returns A new queue with the same content and options.
|
|
1815
|
+
|
|
1816
|
+
|
|
1817
|
+
|
|
1818
|
+
|
|
1819
|
+
|
|
1820
|
+
|
|
1821
|
+
|
|
1822
|
+
|
|
1823
|
+
|
|
1824
|
+
* @example
|
|
1825
|
+
* // Create independent copy
|
|
1826
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1827
|
+
* const copy = q.clone();
|
|
1828
|
+
* copy.shift();
|
|
1829
|
+
* console.log(q.length); // 3;
|
|
1830
|
+
* console.log(copy.length); // 2;
|
|
1831
|
+
*/
|
|
1371
1832
|
clone() {
|
|
1372
1833
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1373
1834
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1375,12 +1836,26 @@ var graphTyped = (() => {
|
|
|
1375
1836
|
return out;
|
|
1376
1837
|
}
|
|
1377
1838
|
/**
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1839
|
+
* Filter elements into a new queue of the same class.
|
|
1840
|
+
* @remarks Time O(N), Space O(N)
|
|
1841
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
1842
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
1843
|
+
* @returns A new queue with kept elements.
|
|
1844
|
+
|
|
1845
|
+
|
|
1846
|
+
|
|
1847
|
+
|
|
1848
|
+
|
|
1849
|
+
|
|
1850
|
+
|
|
1851
|
+
|
|
1852
|
+
|
|
1853
|
+
* @example
|
|
1854
|
+
* // Filter elements
|
|
1855
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1856
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
1857
|
+
* console.log(evens.length); // 2;
|
|
1858
|
+
*/
|
|
1384
1859
|
filter(predicate, thisArg) {
|
|
1385
1860
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1386
1861
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1392,15 +1867,28 @@ var graphTyped = (() => {
|
|
|
1392
1867
|
return out;
|
|
1393
1868
|
}
|
|
1394
1869
|
/**
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1870
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
1871
|
+
* @remarks Time O(N), Space O(N)
|
|
1872
|
+
* @template EM
|
|
1873
|
+
* @template RM
|
|
1874
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
1875
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
1876
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1877
|
+
* @returns A new Queue with mapped elements.
|
|
1878
|
+
|
|
1879
|
+
|
|
1880
|
+
|
|
1881
|
+
|
|
1882
|
+
|
|
1883
|
+
|
|
1884
|
+
|
|
1885
|
+
|
|
1886
|
+
* @example
|
|
1887
|
+
* // Transform elements
|
|
1888
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1889
|
+
* const doubled = q.map(x => x * 2);
|
|
1890
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
1891
|
+
*/
|
|
1404
1892
|
map(callback, options, thisArg) {
|
|
1405
1893
|
var _a, _b;
|
|
1406
1894
|
const out = new this.constructor([], {
|
|
@@ -2488,12 +2976,28 @@ var graphTyped = (() => {
|
|
|
2488
2976
|
return new DirectedEdge(src, dest, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
|
|
2489
2977
|
}
|
|
2490
2978
|
/**
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2979
|
+
* Get the unique edge from `src` to `dest`, if present.
|
|
2980
|
+
* @param srcOrKey - Source vertex or key.
|
|
2981
|
+
* @param destOrKey - Destination vertex or key.
|
|
2982
|
+
* @returns Edge instance or `undefined`.
|
|
2983
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
2984
|
+
|
|
2985
|
+
|
|
2986
|
+
|
|
2987
|
+
|
|
2988
|
+
|
|
2989
|
+
|
|
2990
|
+
|
|
2991
|
+
|
|
2992
|
+
* @example
|
|
2993
|
+
* // Get edge between vertices
|
|
2994
|
+
* const g = new DirectedGraph();
|
|
2995
|
+
* g.addVertex('A');
|
|
2996
|
+
* g.addVertex('B');
|
|
2997
|
+
* g.addEdge('A', 'B', 5);
|
|
2998
|
+
* const edge = g.getEdge('A', 'B');
|
|
2999
|
+
* console.log(edge?.weight); // 5;
|
|
3000
|
+
*/
|
|
2497
3001
|
getEdge(srcOrKey, destOrKey) {
|
|
2498
3002
|
let edgeMap = [];
|
|
2499
3003
|
if (srcOrKey !== void 0 && destOrKey !== void 0) {
|
|
@@ -2533,12 +3037,48 @@ var graphTyped = (() => {
|
|
|
2533
3037
|
return removed;
|
|
2534
3038
|
}
|
|
2535
3039
|
/**
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
3040
|
+
* Delete an edge by instance or by `(srcKey, destKey)`.
|
|
3041
|
+
* @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
|
|
3042
|
+
* @param destVertexKey - Optional destination vertex/key when deleting by pair.
|
|
3043
|
+
* @returns Removed edge or `undefined`.
|
|
3044
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3045
|
+
|
|
3046
|
+
|
|
3047
|
+
|
|
3048
|
+
|
|
3049
|
+
|
|
3050
|
+
|
|
3051
|
+
|
|
3052
|
+
|
|
3053
|
+
|
|
3054
|
+
|
|
3055
|
+
|
|
3056
|
+
* @example
|
|
3057
|
+
* // DirectedGraph deleteEdge and vertex operations
|
|
3058
|
+
* const graph = new DirectedGraph<string>();
|
|
3059
|
+
*
|
|
3060
|
+
* // Build a small graph
|
|
3061
|
+
* graph.addVertex('X');
|
|
3062
|
+
* graph.addVertex('Y');
|
|
3063
|
+
* graph.addVertex('Z');
|
|
3064
|
+
* graph.addEdge('X', 'Y', 1);
|
|
3065
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
3066
|
+
*
|
|
3067
|
+
* // Delete an edge
|
|
3068
|
+
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
3069
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
3070
|
+
*
|
|
3071
|
+
* // Edge in other direction should not exist
|
|
3072
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
3073
|
+
*
|
|
3074
|
+
* // Other edges should remain
|
|
3075
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
3076
|
+
*
|
|
3077
|
+
* // Delete a vertex
|
|
3078
|
+
* graph.deleteVertex('Y');
|
|
3079
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
3080
|
+
* console.log(graph.size); // 2;
|
|
3081
|
+
*/
|
|
2542
3082
|
deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
|
|
2543
3083
|
let removed = void 0;
|
|
2544
3084
|
let src, dest;
|
|
@@ -2565,6 +3105,26 @@ var graphTyped = (() => {
|
|
|
2565
3105
|
}
|
|
2566
3106
|
return removed;
|
|
2567
3107
|
}
|
|
3108
|
+
/**
|
|
3109
|
+
* Remove a vertex
|
|
3110
|
+
|
|
3111
|
+
|
|
3112
|
+
|
|
3113
|
+
|
|
3114
|
+
|
|
3115
|
+
|
|
3116
|
+
|
|
3117
|
+
|
|
3118
|
+
* @example
|
|
3119
|
+
* // Remove a vertex
|
|
3120
|
+
* const g = new DirectedGraph();
|
|
3121
|
+
* g.addVertex('A');
|
|
3122
|
+
* g.addVertex('B');
|
|
3123
|
+
* g.addEdge('A', 'B');
|
|
3124
|
+
* g.deleteVertex('A');
|
|
3125
|
+
* console.log(g.hasVertex('A')); // false;
|
|
3126
|
+
* console.log(g.hasEdge('A', 'B')); // false;
|
|
3127
|
+
*/
|
|
2568
3128
|
deleteVertex(vertexOrKey) {
|
|
2569
3129
|
let vertexKey;
|
|
2570
3130
|
let vertex;
|
|
@@ -2596,11 +3156,28 @@ var graphTyped = (() => {
|
|
|
2596
3156
|
return removed;
|
|
2597
3157
|
}
|
|
2598
3158
|
/**
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
3159
|
+
* Incoming edges of a vertex.
|
|
3160
|
+
* @param vertexOrKey - Vertex or key.
|
|
3161
|
+
* @returns Array of incoming edges.
|
|
3162
|
+
* @remarks Time O(deg_in), Space O(deg_in)
|
|
3163
|
+
|
|
3164
|
+
|
|
3165
|
+
|
|
3166
|
+
|
|
3167
|
+
|
|
3168
|
+
|
|
3169
|
+
|
|
3170
|
+
|
|
3171
|
+
* @example
|
|
3172
|
+
* // Get incoming edges
|
|
3173
|
+
* const g = new DirectedGraph();
|
|
3174
|
+
* g.addVertex('A');
|
|
3175
|
+
* g.addVertex('B');
|
|
3176
|
+
* g.addVertex('C');
|
|
3177
|
+
* g.addEdge('A', 'C');
|
|
3178
|
+
* g.addEdge('B', 'C');
|
|
3179
|
+
* console.log(g.incomingEdgesOf('C').length); // 2;
|
|
3180
|
+
*/
|
|
2604
3181
|
incomingEdgesOf(vertexOrKey) {
|
|
2605
3182
|
const target = this._getVertex(vertexOrKey);
|
|
2606
3183
|
if (target) {
|
|
@@ -2609,11 +3186,28 @@ var graphTyped = (() => {
|
|
|
2609
3186
|
return [];
|
|
2610
3187
|
}
|
|
2611
3188
|
/**
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
3189
|
+
* Outgoing edges of a vertex.
|
|
3190
|
+
* @param vertexOrKey - Vertex or key.
|
|
3191
|
+
* @returns Array of outgoing edges.
|
|
3192
|
+
* @remarks Time O(deg_out), Space O(deg_out)
|
|
3193
|
+
|
|
3194
|
+
|
|
3195
|
+
|
|
3196
|
+
|
|
3197
|
+
|
|
3198
|
+
|
|
3199
|
+
|
|
3200
|
+
|
|
3201
|
+
* @example
|
|
3202
|
+
* // Get outgoing edges
|
|
3203
|
+
* const g = new DirectedGraph();
|
|
3204
|
+
* g.addVertex('A');
|
|
3205
|
+
* g.addVertex('B');
|
|
3206
|
+
* g.addVertex('C');
|
|
3207
|
+
* g.addEdge('A', 'B');
|
|
3208
|
+
* g.addEdge('A', 'C');
|
|
3209
|
+
* console.log(g.outgoingEdgesOf('A').length); // 2;
|
|
3210
|
+
*/
|
|
2617
3211
|
outgoingEdgesOf(vertexOrKey) {
|
|
2618
3212
|
const target = this._getVertex(vertexOrKey);
|
|
2619
3213
|
if (target) {
|
|
@@ -2672,11 +3266,44 @@ var graphTyped = (() => {
|
|
|
2672
3266
|
return destinations;
|
|
2673
3267
|
}
|
|
2674
3268
|
/**
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
3269
|
+
* Topological sort if DAG; returns `undefined` if a cycle exists.
|
|
3270
|
+
* @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
|
|
3271
|
+
* @returns Array of keys/vertices, or `undefined` when cycle is found.
|
|
3272
|
+
* @remarks Time O(V + E), Space O(V)
|
|
3273
|
+
|
|
3274
|
+
|
|
3275
|
+
|
|
3276
|
+
|
|
3277
|
+
|
|
3278
|
+
|
|
3279
|
+
|
|
3280
|
+
|
|
3281
|
+
|
|
3282
|
+
|
|
3283
|
+
|
|
3284
|
+
* @example
|
|
3285
|
+
* // DirectedGraph topologicalSort for task scheduling
|
|
3286
|
+
* const graph = new DirectedGraph<string>();
|
|
3287
|
+
*
|
|
3288
|
+
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
3289
|
+
* graph.addVertex('Design');
|
|
3290
|
+
* graph.addVertex('Implement');
|
|
3291
|
+
* graph.addVertex('Test');
|
|
3292
|
+
* graph.addVertex('Deploy');
|
|
3293
|
+
*
|
|
3294
|
+
* // Add dependency edges
|
|
3295
|
+
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
3296
|
+
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
3297
|
+
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
3298
|
+
*
|
|
3299
|
+
* // Topological sort gives valid execution order
|
|
3300
|
+
* const executionOrder = graph.topologicalSort();
|
|
3301
|
+
* console.log(executionOrder); // defined;
|
|
3302
|
+
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
3303
|
+
*
|
|
3304
|
+
* // All vertices should be included
|
|
3305
|
+
* console.log(executionOrder?.length); // 4;
|
|
3306
|
+
*/
|
|
2680
3307
|
topologicalSort(propertyName) {
|
|
2681
3308
|
propertyName = propertyName != null ? propertyName : "key";
|
|
2682
3309
|
const statusMap = /* @__PURE__ */ new Map();
|
|
@@ -2708,6 +3335,24 @@ var graphTyped = (() => {
|
|
|
2708
3335
|
if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
|
|
2709
3336
|
return sorted.reverse();
|
|
2710
3337
|
}
|
|
3338
|
+
/**
|
|
3339
|
+
* Get all edges
|
|
3340
|
+
|
|
3341
|
+
|
|
3342
|
+
|
|
3343
|
+
|
|
3344
|
+
|
|
3345
|
+
|
|
3346
|
+
|
|
3347
|
+
|
|
3348
|
+
* @example
|
|
3349
|
+
* // Get all edges
|
|
3350
|
+
* const g = new DirectedGraph();
|
|
3351
|
+
* g.addVertex('A');
|
|
3352
|
+
* g.addVertex('B');
|
|
3353
|
+
* g.addEdge('A', 'B', 3);
|
|
3354
|
+
* console.log(g.edgeSet().length); // 1;
|
|
3355
|
+
*/
|
|
2711
3356
|
edgeSet() {
|
|
2712
3357
|
let edgeMap = [];
|
|
2713
3358
|
this._outEdgeMap.forEach((outEdges) => {
|
|
@@ -2715,6 +3360,28 @@ var graphTyped = (() => {
|
|
|
2715
3360
|
});
|
|
2716
3361
|
return edgeMap;
|
|
2717
3362
|
}
|
|
3363
|
+
/**
|
|
3364
|
+
* Get outgoing neighbors
|
|
3365
|
+
|
|
3366
|
+
|
|
3367
|
+
|
|
3368
|
+
|
|
3369
|
+
|
|
3370
|
+
|
|
3371
|
+
|
|
3372
|
+
|
|
3373
|
+
|
|
3374
|
+
* @example
|
|
3375
|
+
* // Get outgoing neighbors
|
|
3376
|
+
* const g = new DirectedGraph();
|
|
3377
|
+
* g.addVertex('A');
|
|
3378
|
+
* g.addVertex('B');
|
|
3379
|
+
* g.addVertex('C');
|
|
3380
|
+
* g.addEdge('A', 'B');
|
|
3381
|
+
* g.addEdge('A', 'C');
|
|
3382
|
+
* const neighbors = g.getNeighbors('A');
|
|
3383
|
+
* console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
|
|
3384
|
+
*/
|
|
2718
3385
|
getNeighbors(vertexOrKey) {
|
|
2719
3386
|
const neighbors = [];
|
|
2720
3387
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -2772,10 +3439,31 @@ var graphTyped = (() => {
|
|
|
2772
3439
|
return super.clone();
|
|
2773
3440
|
}
|
|
2774
3441
|
/**
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
3442
|
+
* Tarjan's algorithm for strongly connected components.
|
|
3443
|
+
* @returns `{ dfnMap, lowMap, SCCs }`.
|
|
3444
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
3445
|
+
|
|
3446
|
+
|
|
3447
|
+
|
|
3448
|
+
|
|
3449
|
+
|
|
3450
|
+
|
|
3451
|
+
|
|
3452
|
+
|
|
3453
|
+
* @example
|
|
3454
|
+
* // Find strongly connected components
|
|
3455
|
+
* const g = new DirectedGraph();
|
|
3456
|
+
* g.addVertex('A');
|
|
3457
|
+
* g.addVertex('B');
|
|
3458
|
+
* g.addVertex('C');
|
|
3459
|
+
* g.addEdge('A', 'B');
|
|
3460
|
+
* g.addEdge('B', 'C');
|
|
3461
|
+
* g.addEdge('C', 'A');
|
|
3462
|
+
* const { SCCs } = g.tarjan();
|
|
3463
|
+
* // A→B→C→A forms one SCC with 3 members
|
|
3464
|
+
* const sccArrays = [...SCCs.values()];
|
|
3465
|
+
* console.log(sccArrays.some(scc => scc.length === 3)); // true;
|
|
3466
|
+
*/
|
|
2779
3467
|
tarjan() {
|
|
2780
3468
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
2781
3469
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -2833,10 +3521,29 @@ var graphTyped = (() => {
|
|
|
2833
3521
|
return this.tarjan().lowMap;
|
|
2834
3522
|
}
|
|
2835
3523
|
/**
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
3524
|
+
* Strongly connected components computed by `tarjan()`.
|
|
3525
|
+
* @returns Map from SCC id to vertices.
|
|
3526
|
+
* @remarks Time O(#SCC + V), Space O(V)
|
|
3527
|
+
|
|
3528
|
+
|
|
3529
|
+
|
|
3530
|
+
|
|
3531
|
+
|
|
3532
|
+
|
|
3533
|
+
|
|
3534
|
+
|
|
3535
|
+
* @example
|
|
3536
|
+
* // Get strongly connected components
|
|
3537
|
+
* const g = new DirectedGraph();
|
|
3538
|
+
* g.addVertex(1);
|
|
3539
|
+
* g.addVertex(2);
|
|
3540
|
+
* g.addVertex(3);
|
|
3541
|
+
* g.addEdge(1, 2);
|
|
3542
|
+
* g.addEdge(2, 3);
|
|
3543
|
+
* g.addEdge(3, 1);
|
|
3544
|
+
* const sccs = g.getSCCs(); // Map<number, VO[]>
|
|
3545
|
+
* console.log(sccs.size); // >= 1;
|
|
3546
|
+
*/
|
|
2840
3547
|
getSCCs() {
|
|
2841
3548
|
return this.tarjan().SCCs;
|
|
2842
3549
|
}
|
|
@@ -2952,12 +3659,27 @@ var graphTyped = (() => {
|
|
|
2952
3659
|
return new UndirectedEdge(v1, v2, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
|
|
2953
3660
|
}
|
|
2954
3661
|
/**
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
3662
|
+
* Get an undirected edge between two vertices, if present.
|
|
3663
|
+
* @param v1 - One vertex or key.
|
|
3664
|
+
* @param v2 - The other vertex or key.
|
|
3665
|
+
* @returns Edge instance or `undefined`.
|
|
3666
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3667
|
+
|
|
3668
|
+
|
|
3669
|
+
|
|
3670
|
+
|
|
3671
|
+
|
|
3672
|
+
|
|
3673
|
+
|
|
3674
|
+
|
|
3675
|
+
* @example
|
|
3676
|
+
* // Get edge between vertices
|
|
3677
|
+
* const g = new UndirectedGraph();
|
|
3678
|
+
* g.addVertex('A');
|
|
3679
|
+
* g.addVertex('B');
|
|
3680
|
+
* g.addEdge('A', 'B', 7);
|
|
3681
|
+
* console.log(g.getEdge('A', 'B')?.weight); // 7;
|
|
3682
|
+
*/
|
|
2961
3683
|
getEdge(v1, v2) {
|
|
2962
3684
|
var _a;
|
|
2963
3685
|
let edgeMap = [];
|
|
@@ -2995,12 +3717,50 @@ var graphTyped = (() => {
|
|
|
2995
3717
|
return removed;
|
|
2996
3718
|
}
|
|
2997
3719
|
/**
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3720
|
+
* Delete an edge by instance or by a pair of keys.
|
|
3721
|
+
* @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
|
|
3722
|
+
* @param otherSideVertexKey - Required second endpoint when deleting by pair.
|
|
3723
|
+
* @returns Removed edge or `undefined`.
|
|
3724
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3725
|
+
|
|
3726
|
+
|
|
3727
|
+
|
|
3728
|
+
|
|
3729
|
+
|
|
3730
|
+
|
|
3731
|
+
|
|
3732
|
+
|
|
3733
|
+
|
|
3734
|
+
|
|
3735
|
+
|
|
3736
|
+
* @example
|
|
3737
|
+
* // UndirectedGraph deleteEdge and vertex operations
|
|
3738
|
+
* const graph = new UndirectedGraph<string>();
|
|
3739
|
+
*
|
|
3740
|
+
* // Build a simple undirected graph
|
|
3741
|
+
* graph.addVertex('X');
|
|
3742
|
+
* graph.addVertex('Y');
|
|
3743
|
+
* graph.addVertex('Z');
|
|
3744
|
+
* graph.addEdge('X', 'Y', 1);
|
|
3745
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
3746
|
+
* graph.addEdge('X', 'Z', 3);
|
|
3747
|
+
*
|
|
3748
|
+
* // Delete an edge
|
|
3749
|
+
* graph.deleteEdge('X', 'Y');
|
|
3750
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
3751
|
+
*
|
|
3752
|
+
* // Bidirectional deletion confirmed
|
|
3753
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
3754
|
+
*
|
|
3755
|
+
* // Other edges should remain
|
|
3756
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
3757
|
+
* console.log(graph.hasEdge('Z', 'Y')); // true;
|
|
3758
|
+
*
|
|
3759
|
+
* // Delete a vertex
|
|
3760
|
+
* graph.deleteVertex('Y');
|
|
3761
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
3762
|
+
* console.log(graph.size); // 2;
|
|
3763
|
+
*/
|
|
3004
3764
|
deleteEdge(edgeOrOneSideVertexKey, otherSideVertexKey) {
|
|
3005
3765
|
let oneSide, otherSide;
|
|
3006
3766
|
if (this.isVertexKey(edgeOrOneSideVertexKey)) {
|
|
@@ -3021,11 +3781,27 @@ var graphTyped = (() => {
|
|
|
3021
3781
|
}
|
|
3022
3782
|
}
|
|
3023
3783
|
/**
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3784
|
+
* Delete a vertex and remove it from all neighbor lists.
|
|
3785
|
+
* @param vertexOrKey - Vertex or key.
|
|
3786
|
+
* @returns `true` if removed; otherwise `false`.
|
|
3787
|
+
* @remarks Time O(deg), Space O(1)
|
|
3788
|
+
|
|
3789
|
+
|
|
3790
|
+
|
|
3791
|
+
|
|
3792
|
+
|
|
3793
|
+
|
|
3794
|
+
|
|
3795
|
+
|
|
3796
|
+
* @example
|
|
3797
|
+
* // Remove vertex and edges
|
|
3798
|
+
* const g = new UndirectedGraph();
|
|
3799
|
+
* g.addVertex('A');
|
|
3800
|
+
* g.addVertex('B');
|
|
3801
|
+
* g.addEdge('A', 'B');
|
|
3802
|
+
* g.deleteVertex('A');
|
|
3803
|
+
* console.log(g.hasVertex('A')); // false;
|
|
3804
|
+
*/
|
|
3029
3805
|
deleteVertex(vertexOrKey) {
|
|
3030
3806
|
let vertexKey;
|
|
3031
3807
|
let vertex;
|
|
@@ -3081,10 +3857,25 @@ var graphTyped = (() => {
|
|
|
3081
3857
|
}
|
|
3082
3858
|
}
|
|
3083
3859
|
/**
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3860
|
+
* Unique set of undirected edges across endpoints.
|
|
3861
|
+
* @returns Array of edges.
|
|
3862
|
+
* @remarks Time O(E), Space O(E)
|
|
3863
|
+
|
|
3864
|
+
|
|
3865
|
+
|
|
3866
|
+
|
|
3867
|
+
|
|
3868
|
+
|
|
3869
|
+
|
|
3870
|
+
|
|
3871
|
+
* @example
|
|
3872
|
+
* // Get all edges
|
|
3873
|
+
* const g = new UndirectedGraph();
|
|
3874
|
+
* g.addVertex('A');
|
|
3875
|
+
* g.addVertex('B');
|
|
3876
|
+
* g.addEdge('A', 'B');
|
|
3877
|
+
* console.log(g.edgeSet().length); // 1;
|
|
3878
|
+
*/
|
|
3088
3879
|
edgeSet() {
|
|
3089
3880
|
const edgeSet = /* @__PURE__ */ new Set();
|
|
3090
3881
|
this._edgeMap.forEach((edgeMap) => {
|
|
@@ -3094,6 +3885,52 @@ var graphTyped = (() => {
|
|
|
3094
3885
|
});
|
|
3095
3886
|
return [...edgeSet];
|
|
3096
3887
|
}
|
|
3888
|
+
/**
|
|
3889
|
+
* UndirectedGraph connectivity and neighbors
|
|
3890
|
+
|
|
3891
|
+
|
|
3892
|
+
|
|
3893
|
+
|
|
3894
|
+
|
|
3895
|
+
|
|
3896
|
+
|
|
3897
|
+
|
|
3898
|
+
|
|
3899
|
+
|
|
3900
|
+
|
|
3901
|
+
* @example
|
|
3902
|
+
* // UndirectedGraph connectivity and neighbors
|
|
3903
|
+
* const graph = new UndirectedGraph<string>();
|
|
3904
|
+
*
|
|
3905
|
+
* // Build a friendship network
|
|
3906
|
+
* const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
|
|
3907
|
+
* for (const person of people) {
|
|
3908
|
+
* graph.addVertex(person);
|
|
3909
|
+
* }
|
|
3910
|
+
*
|
|
3911
|
+
* // Add friendships (undirected edges)
|
|
3912
|
+
* graph.addEdge('Alice', 'Bob', 1);
|
|
3913
|
+
* graph.addEdge('Alice', 'Charlie', 1);
|
|
3914
|
+
* graph.addEdge('Bob', 'Diana', 1);
|
|
3915
|
+
* graph.addEdge('Charlie', 'Eve', 1);
|
|
3916
|
+
* graph.addEdge('Diana', 'Eve', 1);
|
|
3917
|
+
*
|
|
3918
|
+
* // Get friends of each person
|
|
3919
|
+
* const aliceFriends = graph.getNeighbors('Alice');
|
|
3920
|
+
* console.log(aliceFriends[0].key); // 'Bob';
|
|
3921
|
+
* console.log(aliceFriends[1].key); // 'Charlie';
|
|
3922
|
+
* console.log(aliceFriends.length); // 2;
|
|
3923
|
+
*
|
|
3924
|
+
* const dianaFriends = graph.getNeighbors('Diana');
|
|
3925
|
+
* console.log(dianaFriends[0].key); // 'Bob';
|
|
3926
|
+
* console.log(dianaFriends[1].key); // 'Eve';
|
|
3927
|
+
* console.log(dianaFriends.length); // 2;
|
|
3928
|
+
*
|
|
3929
|
+
* // Verify bidirectional friendship
|
|
3930
|
+
* const bobFriends = graph.getNeighbors('Bob');
|
|
3931
|
+
* console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
|
|
3932
|
+
* console.log(bobFriends[1].key); // 'Diana';
|
|
3933
|
+
*/
|
|
3097
3934
|
getNeighbors(vertexOrKey) {
|
|
3098
3935
|
const neighbors = [];
|
|
3099
3936
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -3150,10 +3987,28 @@ var graphTyped = (() => {
|
|
|
3150
3987
|
return super.clone();
|
|
3151
3988
|
}
|
|
3152
3989
|
/**
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3990
|
+
* Tarjan-based bridge and articulation point detection.
|
|
3991
|
+
* @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
|
|
3992
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
3993
|
+
|
|
3994
|
+
|
|
3995
|
+
|
|
3996
|
+
|
|
3997
|
+
|
|
3998
|
+
|
|
3999
|
+
|
|
4000
|
+
|
|
4001
|
+
* @example
|
|
4002
|
+
* // Find articulation points and bridges
|
|
4003
|
+
* const g = new UndirectedGraph();
|
|
4004
|
+
* g.addVertex('A');
|
|
4005
|
+
* g.addVertex('B');
|
|
4006
|
+
* g.addVertex('C');
|
|
4007
|
+
* g.addEdge('A', 'B');
|
|
4008
|
+
* g.addEdge('B', 'C');
|
|
4009
|
+
* const result = g.tarjan();
|
|
4010
|
+
* console.log(result); // defined;
|
|
4011
|
+
*/
|
|
3157
4012
|
tarjan() {
|
|
3158
4013
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
3159
4014
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -3253,11 +4108,30 @@ var graphTyped = (() => {
|
|
|
3253
4108
|
return components;
|
|
3254
4109
|
}
|
|
3255
4110
|
/**
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
4111
|
+
* Detect whether the graph contains a cycle.
|
|
4112
|
+
* Uses DFS with parent tracking.
|
|
4113
|
+
* @returns `true` if a cycle exists, `false` otherwise.
|
|
4114
|
+
* @remarks Time O(V + E), Space O(V)
|
|
4115
|
+
|
|
4116
|
+
|
|
4117
|
+
|
|
4118
|
+
|
|
4119
|
+
|
|
4120
|
+
|
|
4121
|
+
|
|
4122
|
+
|
|
4123
|
+
* @example
|
|
4124
|
+
* // Detect cycle
|
|
4125
|
+
* const g = new UndirectedGraph();
|
|
4126
|
+
* g.addVertex('A');
|
|
4127
|
+
* g.addVertex('B');
|
|
4128
|
+
* g.addVertex('C');
|
|
4129
|
+
* g.addEdge('A', 'B');
|
|
4130
|
+
* g.addEdge('B', 'C');
|
|
4131
|
+
* console.log(g.hasCycle()); // false;
|
|
4132
|
+
* g.addEdge('C', 'A');
|
|
4133
|
+
* console.log(g.hasCycle()); // true;
|
|
4134
|
+
*/
|
|
3261
4135
|
hasCycle() {
|
|
3262
4136
|
const visited = /* @__PURE__ */ new Set();
|
|
3263
4137
|
const dfs = (vertex, parent) => {
|
|
@@ -3279,18 +4153,55 @@ var graphTyped = (() => {
|
|
|
3279
4153
|
return false;
|
|
3280
4154
|
}
|
|
3281
4155
|
/**
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
4156
|
+
* Get bridges discovered by `tarjan()`.
|
|
4157
|
+
* @returns Array of edges that are bridges.
|
|
4158
|
+
* @remarks Time O(B), Space O(1)
|
|
4159
|
+
|
|
4160
|
+
|
|
4161
|
+
|
|
4162
|
+
|
|
4163
|
+
|
|
4164
|
+
|
|
4165
|
+
|
|
4166
|
+
|
|
4167
|
+
* @example
|
|
4168
|
+
* // Find bridge edges
|
|
4169
|
+
* const g = new UndirectedGraph();
|
|
4170
|
+
* g.addVertex('A');
|
|
4171
|
+
* g.addVertex('B');
|
|
4172
|
+
* g.addVertex('C');
|
|
4173
|
+
* g.addEdge('A', 'B');
|
|
4174
|
+
* g.addEdge('B', 'C');
|
|
4175
|
+
* const bridges = g.getBridges();
|
|
4176
|
+
* console.log(bridges.length); // 2;
|
|
4177
|
+
*/
|
|
3286
4178
|
getBridges() {
|
|
3287
4179
|
return this.tarjan().bridges;
|
|
3288
4180
|
}
|
|
3289
4181
|
/**
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
4182
|
+
* Get articulation points discovered by `tarjan()`.
|
|
4183
|
+
* @returns Array of cut vertices.
|
|
4184
|
+
* @remarks Time O(C), Space O(1)
|
|
4185
|
+
|
|
4186
|
+
|
|
4187
|
+
|
|
4188
|
+
|
|
4189
|
+
|
|
4190
|
+
|
|
4191
|
+
|
|
4192
|
+
|
|
4193
|
+
* @example
|
|
4194
|
+
* // Find articulation points
|
|
4195
|
+
* const g = new UndirectedGraph();
|
|
4196
|
+
* g.addVertex('A');
|
|
4197
|
+
* g.addVertex('B');
|
|
4198
|
+
* g.addVertex('C');
|
|
4199
|
+
* g.addEdge('A', 'B');
|
|
4200
|
+
* g.addEdge('B', 'C');
|
|
4201
|
+
* const cuts = g.getCutVertices();
|
|
4202
|
+
* console.log(cuts.length); // 1;
|
|
4203
|
+
* console.log(cuts[0].key); // 'B';
|
|
4204
|
+
*/
|
|
3294
4205
|
getCutVertices() {
|
|
3295
4206
|
return this.tarjan().cutVertices;
|
|
3296
4207
|
}
|