directed-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/README.md +0 -51
- package/dist/cjs/index.cjs +870 -163
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +870 -163
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +870 -163
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +870 -163
- 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/directed-graph-typed.js +870 -163
- package/dist/umd/directed-graph-typed.js.map +1 -1
- package/dist/umd/directed-graph-typed.min.js +3 -3
- package/dist/umd/directed-graph-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/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
|
@@ -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
|
}
|
|
@@ -512,10 +512,30 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
512
512
|
return this._elements;
|
|
513
513
|
}
|
|
514
514
|
/**
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
515
|
+
* Get the number of elements.
|
|
516
|
+
* @remarks Time O(1), Space O(1)
|
|
517
|
+
* @returns Heap size.
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
* @example
|
|
530
|
+
* // Track heap capacity
|
|
531
|
+
* const heap = new Heap<number>();
|
|
532
|
+
* console.log(heap.size); // 0;
|
|
533
|
+
* heap.add(10);
|
|
534
|
+
* heap.add(20);
|
|
535
|
+
* console.log(heap.size); // 2;
|
|
536
|
+
* heap.poll();
|
|
537
|
+
* console.log(heap.size); // 1;
|
|
538
|
+
*/
|
|
519
539
|
get size() {
|
|
520
540
|
return this.elements.length;
|
|
521
541
|
}
|
|
@@ -554,21 +574,61 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
554
574
|
return new _Heap(elements, options);
|
|
555
575
|
}
|
|
556
576
|
/**
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
577
|
+
* Insert an element.
|
|
578
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
579
|
+
* @param element - Element to insert.
|
|
580
|
+
* @returns True.
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
* @example
|
|
593
|
+
* // basic Heap creation and add operation
|
|
594
|
+
* // Create a min heap (default)
|
|
595
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
596
|
+
*
|
|
597
|
+
* // Verify size
|
|
598
|
+
* console.log(minHeap.size); // 6;
|
|
599
|
+
*
|
|
600
|
+
* // Add new element
|
|
601
|
+
* minHeap.add(4);
|
|
602
|
+
* console.log(minHeap.size); // 7;
|
|
603
|
+
*
|
|
604
|
+
* // Min heap property: smallest element at root
|
|
605
|
+
* const min = minHeap.peek();
|
|
606
|
+
* console.log(min); // 1;
|
|
607
|
+
*/
|
|
562
608
|
add(element) {
|
|
563
609
|
this._elements.push(element);
|
|
564
610
|
return this._bubbleUp(this.elements.length - 1);
|
|
565
611
|
}
|
|
566
612
|
/**
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
613
|
+
* Insert many elements from an iterable.
|
|
614
|
+
* @remarks Time O(N log N), Space O(1)
|
|
615
|
+
* @param elements - Iterable of elements or raw values.
|
|
616
|
+
* @returns Array of per-element success flags.
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
* @example
|
|
626
|
+
* // Add multiple elements
|
|
627
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
628
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
629
|
+
* console.log(heap.peek()); // 1;
|
|
630
|
+
* console.log(heap.size); // 4;
|
|
631
|
+
*/
|
|
572
632
|
addMany(elements) {
|
|
573
633
|
const flags = [];
|
|
574
634
|
for (const el of elements) {
|
|
@@ -583,10 +643,46 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
583
643
|
return flags;
|
|
584
644
|
}
|
|
585
645
|
/**
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
646
|
+
* Remove and return the top element.
|
|
647
|
+
* @remarks Time O(log N), Space O(1)
|
|
648
|
+
* @returns Top element or undefined.
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
* @example
|
|
661
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
662
|
+
* interface Task {
|
|
663
|
+
* id: number;
|
|
664
|
+
* priority: number;
|
|
665
|
+
* name: string;
|
|
666
|
+
* }
|
|
667
|
+
*
|
|
668
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
669
|
+
* const tasks: Task[] = [
|
|
670
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
671
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
672
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
673
|
+
* ];
|
|
674
|
+
*
|
|
675
|
+
* const maxHeap = new Heap(tasks, {
|
|
676
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
677
|
+
* });
|
|
678
|
+
*
|
|
679
|
+
* console.log(maxHeap.size); // 3;
|
|
680
|
+
*
|
|
681
|
+
* // Peek returns highest priority task
|
|
682
|
+
* const topTask = maxHeap.peek();
|
|
683
|
+
* console.log(topTask?.priority); // 8;
|
|
684
|
+
* console.log(topTask?.name); // 'Alert';
|
|
685
|
+
*/
|
|
590
686
|
poll() {
|
|
591
687
|
if (this.elements.length === 0) return;
|
|
592
688
|
const value = this.elements[0];
|
|
@@ -598,26 +694,125 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
598
694
|
return value;
|
|
599
695
|
}
|
|
600
696
|
/**
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
697
|
+
* Get the current top element without removing it.
|
|
698
|
+
* @remarks Time O(1), Space O(1)
|
|
699
|
+
* @returns Top element or undefined.
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
* @example
|
|
712
|
+
* // Heap for event processing with priority
|
|
713
|
+
* interface Event {
|
|
714
|
+
* id: number;
|
|
715
|
+
* type: 'critical' | 'warning' | 'info';
|
|
716
|
+
* timestamp: number;
|
|
717
|
+
* message: string;
|
|
718
|
+
* }
|
|
719
|
+
*
|
|
720
|
+
* // Custom priority: critical > warning > info
|
|
721
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
722
|
+
*
|
|
723
|
+
* const eventHeap = new Heap<Event>([], {
|
|
724
|
+
* comparator: (a: Event, b: Event) => {
|
|
725
|
+
* const priorityA = priorityMap[a.type];
|
|
726
|
+
* const priorityB = priorityMap[b.type];
|
|
727
|
+
* return priorityB - priorityA; // Higher priority first
|
|
728
|
+
* }
|
|
729
|
+
* });
|
|
730
|
+
*
|
|
731
|
+
* // Add events in random order
|
|
732
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
733
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
734
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
735
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
736
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
737
|
+
*
|
|
738
|
+
* console.log(eventHeap.size); // 5;
|
|
739
|
+
*
|
|
740
|
+
* // Process events by priority (critical first)
|
|
741
|
+
* const processedOrder: Event[] = [];
|
|
742
|
+
* while (eventHeap.size > 0) {
|
|
743
|
+
* const event = eventHeap.poll();
|
|
744
|
+
* if (event) {
|
|
745
|
+
* processedOrder.push(event);
|
|
746
|
+
* }
|
|
747
|
+
* }
|
|
748
|
+
*
|
|
749
|
+
* // Verify critical events came first
|
|
750
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
751
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
752
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
753
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
754
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
755
|
+
*
|
|
756
|
+
* // Verify O(log n) operations
|
|
757
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
758
|
+
*
|
|
759
|
+
* // Add - O(log n)
|
|
760
|
+
* newHeap.add(2);
|
|
761
|
+
* console.log(newHeap.size); // 5;
|
|
762
|
+
*
|
|
763
|
+
* // Poll - O(log n)
|
|
764
|
+
* const removed = newHeap.poll();
|
|
765
|
+
* console.log(removed); // 1;
|
|
766
|
+
*
|
|
767
|
+
* // Peek - O(1)
|
|
768
|
+
* const top = newHeap.peek();
|
|
769
|
+
* console.log(top); // 2;
|
|
770
|
+
*/
|
|
605
771
|
peek() {
|
|
606
772
|
return this.elements[0];
|
|
607
773
|
}
|
|
608
774
|
/**
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
775
|
+
* Check whether the heap is empty.
|
|
776
|
+
* @remarks Time O(1), Space O(1)
|
|
777
|
+
* @returns True if size is 0.
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
* @example
|
|
788
|
+
* // Check if heap is empty
|
|
789
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
790
|
+
* console.log(heap.isEmpty()); // true;
|
|
791
|
+
* heap.add(1);
|
|
792
|
+
* console.log(heap.isEmpty()); // false;
|
|
793
|
+
*/
|
|
613
794
|
isEmpty() {
|
|
614
795
|
return this.size === 0;
|
|
615
796
|
}
|
|
616
797
|
/**
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
798
|
+
* Remove all elements.
|
|
799
|
+
* @remarks Time O(1), Space O(1)
|
|
800
|
+
* @returns void
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
* @example
|
|
811
|
+
* // Remove all elements
|
|
812
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
813
|
+
* heap.clear();
|
|
814
|
+
* console.log(heap.isEmpty()); // true;
|
|
815
|
+
*/
|
|
621
816
|
clear() {
|
|
622
817
|
this._elements = [];
|
|
623
818
|
}
|
|
@@ -632,21 +827,41 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
632
827
|
return this.fix();
|
|
633
828
|
}
|
|
634
829
|
/**
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
830
|
+
* Check if an equal element exists in the heap.
|
|
831
|
+
* @remarks Time O(N), Space O(1)
|
|
832
|
+
* @param element - Element to search for.
|
|
833
|
+
* @returns True if found.
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
* @example
|
|
837
|
+
* // Check element existence
|
|
838
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
839
|
+
* console.log(heap.has(1)); // true;
|
|
840
|
+
* console.log(heap.has(99)); // false;
|
|
841
|
+
*/
|
|
640
842
|
has(element) {
|
|
641
843
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
642
844
|
return false;
|
|
643
845
|
}
|
|
644
846
|
/**
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
847
|
+
* Delete one occurrence of an element.
|
|
848
|
+
* @remarks Time O(N), Space O(1)
|
|
849
|
+
* @param element - Element to delete.
|
|
850
|
+
* @returns True if an element was removed.
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
* @example
|
|
860
|
+
* // Remove specific element
|
|
861
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
862
|
+
* heap.delete(4);
|
|
863
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
864
|
+
*/
|
|
650
865
|
delete(element) {
|
|
651
866
|
let index = -1;
|
|
652
867
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -704,11 +919,18 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
704
919
|
return this;
|
|
705
920
|
}
|
|
706
921
|
/**
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
922
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
923
|
+
* @remarks Time O(N), Space O(H)
|
|
924
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
925
|
+
* @returns Array of visited elements.
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
* @example
|
|
929
|
+
* // Depth-first traversal
|
|
930
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
931
|
+
* const result = heap.dfs('IN');
|
|
932
|
+
* console.log(result.length); // 3;
|
|
933
|
+
*/
|
|
712
934
|
dfs(order = "PRE") {
|
|
713
935
|
const result = [];
|
|
714
936
|
const _dfs = /* @__PURE__ */ __name((index) => {
|
|
@@ -745,10 +967,26 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
745
967
|
return results;
|
|
746
968
|
}
|
|
747
969
|
/**
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
970
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
971
|
+
* @remarks Time O(N log N), Space O(N)
|
|
972
|
+
* @returns Sorted array of elements.
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
* @example
|
|
985
|
+
* // Sort elements using heap
|
|
986
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
987
|
+
* const sorted = heap.sort();
|
|
988
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
989
|
+
*/
|
|
752
990
|
sort() {
|
|
753
991
|
const visited = [];
|
|
754
992
|
const cloned = this._createInstance();
|
|
@@ -760,22 +998,52 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
760
998
|
return visited;
|
|
761
999
|
}
|
|
762
1000
|
/**
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1001
|
+
* Deep clone this heap.
|
|
1002
|
+
* @remarks Time O(N), Space O(N)
|
|
1003
|
+
* @returns A new heap with the same elements.
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
* @example
|
|
1014
|
+
* // Create independent copy
|
|
1015
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
1016
|
+
* const copy = heap.clone();
|
|
1017
|
+
* copy.poll();
|
|
1018
|
+
* console.log(heap.size); // 3;
|
|
1019
|
+
* console.log(copy.size); // 2;
|
|
1020
|
+
*/
|
|
767
1021
|
clone() {
|
|
768
1022
|
const next = this._createInstance();
|
|
769
1023
|
for (const x of this.elements) next.add(x);
|
|
770
1024
|
return next;
|
|
771
1025
|
}
|
|
772
1026
|
/**
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
1027
|
+
* Filter elements into a new heap of the same class.
|
|
1028
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1029
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
1030
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1031
|
+
* @returns A new heap with the kept elements.
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
* @example
|
|
1042
|
+
* // Filter elements
|
|
1043
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
1044
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
1045
|
+
* console.log(evens.size); // 2;
|
|
1046
|
+
*/
|
|
779
1047
|
filter(callback, thisArg) {
|
|
780
1048
|
const out = this._createInstance();
|
|
781
1049
|
let i = 0;
|
|
@@ -789,15 +1057,28 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
789
1057
|
return out;
|
|
790
1058
|
}
|
|
791
1059
|
/**
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
1060
|
+
* Map elements into a new heap of possibly different element type.
|
|
1061
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1062
|
+
* @template EM
|
|
1063
|
+
* @template RM
|
|
1064
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
1065
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
1066
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1067
|
+
* @returns A new heap with mapped elements.
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
* @example
|
|
1077
|
+
* // Transform elements
|
|
1078
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1079
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
1080
|
+
* console.log(doubled.peek()); // 2;
|
|
1081
|
+
*/
|
|
801
1082
|
map(callback, options, thisArg) {
|
|
802
1083
|
const { comparator, toElementFn, ...rest } = options != null ? options : {};
|
|
803
1084
|
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
@@ -1149,18 +1430,52 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1149
1430
|
this._autoCompactRatio = value;
|
|
1150
1431
|
}
|
|
1151
1432
|
/**
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1433
|
+
* Get the number of elements currently in the queue.
|
|
1434
|
+
* @remarks Time O(1), Space O(1)
|
|
1435
|
+
* @returns Current length.
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
* @example
|
|
1448
|
+
* // Track queue length
|
|
1449
|
+
* const q = new Queue<number>();
|
|
1450
|
+
* console.log(q.length); // 0;
|
|
1451
|
+
* q.push(1);
|
|
1452
|
+
* q.push(2);
|
|
1453
|
+
* console.log(q.length); // 2;
|
|
1454
|
+
*/
|
|
1156
1455
|
get length() {
|
|
1157
1456
|
return this.elements.length - this._offset;
|
|
1158
1457
|
}
|
|
1159
1458
|
/**
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1459
|
+
* Get the first element (front) without removing it.
|
|
1460
|
+
* @remarks Time O(1), Space O(1)
|
|
1461
|
+
* @returns Front element or undefined.
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
|
|
1470
|
+
|
|
1471
|
+
|
|
1472
|
+
|
|
1473
|
+
* @example
|
|
1474
|
+
* // View the front element
|
|
1475
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
1476
|
+
* console.log(q.first); // 'first';
|
|
1477
|
+
* console.log(q.length); // 3;
|
|
1478
|
+
*/
|
|
1164
1479
|
get first() {
|
|
1165
1480
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
1166
1481
|
}
|
|
@@ -1183,19 +1498,69 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1183
1498
|
return new _Queue(elements);
|
|
1184
1499
|
}
|
|
1185
1500
|
/**
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1501
|
+
* Check whether the queue is empty.
|
|
1502
|
+
* @remarks Time O(1), Space O(1)
|
|
1503
|
+
* @returns True if length is 0.
|
|
1504
|
+
|
|
1505
|
+
|
|
1506
|
+
|
|
1507
|
+
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
|
|
1514
|
+
|
|
1515
|
+
* @example
|
|
1516
|
+
* // Queue for...of iteration and isEmpty check
|
|
1517
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
1518
|
+
*
|
|
1519
|
+
* const elements: string[] = [];
|
|
1520
|
+
* for (const item of queue) {
|
|
1521
|
+
* elements.push(item);
|
|
1522
|
+
* }
|
|
1523
|
+
*
|
|
1524
|
+
* // Verify all elements are iterated in order
|
|
1525
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
1526
|
+
*
|
|
1527
|
+
* // Process all elements
|
|
1528
|
+
* while (queue.length > 0) {
|
|
1529
|
+
* queue.shift();
|
|
1530
|
+
* }
|
|
1531
|
+
*
|
|
1532
|
+
* console.log(queue.length); // 0;
|
|
1533
|
+
*/
|
|
1190
1534
|
isEmpty() {
|
|
1191
1535
|
return this.length === 0;
|
|
1192
1536
|
}
|
|
1193
1537
|
/**
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1538
|
+
* Enqueue one element at the back.
|
|
1539
|
+
* @remarks Time O(1), Space O(1)
|
|
1540
|
+
* @param element - Element to enqueue.
|
|
1541
|
+
* @returns True on success.
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
* @example
|
|
1554
|
+
* // basic Queue creation and push operation
|
|
1555
|
+
* // Create a simple Queue with initial values
|
|
1556
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
1557
|
+
*
|
|
1558
|
+
* // Verify the queue maintains insertion order
|
|
1559
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
1560
|
+
*
|
|
1561
|
+
* // Check length
|
|
1562
|
+
* console.log(queue.length); // 5;
|
|
1563
|
+
*/
|
|
1199
1564
|
push(element) {
|
|
1200
1565
|
this.elements.push(element);
|
|
1201
1566
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -1216,10 +1581,35 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1216
1581
|
return ans;
|
|
1217
1582
|
}
|
|
1218
1583
|
/**
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1584
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1585
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1586
|
+
* @returns Removed element or undefined.
|
|
1587
|
+
|
|
1588
|
+
|
|
1589
|
+
|
|
1590
|
+
|
|
1591
|
+
|
|
1592
|
+
|
|
1593
|
+
|
|
1594
|
+
|
|
1595
|
+
|
|
1596
|
+
|
|
1597
|
+
|
|
1598
|
+
* @example
|
|
1599
|
+
* // Queue shift and peek operations
|
|
1600
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
1601
|
+
*
|
|
1602
|
+
* // Peek at the front element without removing it
|
|
1603
|
+
* console.log(queue.first); // 10;
|
|
1604
|
+
*
|
|
1605
|
+
* // Remove and get the first element (FIFO)
|
|
1606
|
+
* const first = queue.shift();
|
|
1607
|
+
* console.log(first); // 10;
|
|
1608
|
+
*
|
|
1609
|
+
* // Verify remaining elements and length decreased
|
|
1610
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
1611
|
+
* console.log(queue.length); // 3;
|
|
1612
|
+
*/
|
|
1223
1613
|
shift() {
|
|
1224
1614
|
if (this.length === 0) return void 0;
|
|
1225
1615
|
const first = this.first;
|
|
@@ -1228,11 +1618,24 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1228
1618
|
return first;
|
|
1229
1619
|
}
|
|
1230
1620
|
/**
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1621
|
+
* Delete the first occurrence of a specific element.
|
|
1622
|
+
* @remarks Time O(N), Space O(1)
|
|
1623
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
1624
|
+
* @returns True if an element was removed.
|
|
1625
|
+
|
|
1626
|
+
|
|
1627
|
+
|
|
1628
|
+
|
|
1629
|
+
|
|
1630
|
+
|
|
1631
|
+
|
|
1632
|
+
|
|
1633
|
+
* @example
|
|
1634
|
+
* // Remove specific element
|
|
1635
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
1636
|
+
* q.delete(2);
|
|
1637
|
+
* console.log(q.length); // 3;
|
|
1638
|
+
*/
|
|
1236
1639
|
delete(element) {
|
|
1237
1640
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
1238
1641
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -1243,11 +1646,24 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1243
1646
|
return false;
|
|
1244
1647
|
}
|
|
1245
1648
|
/**
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1649
|
+
* Get the element at a given logical index.
|
|
1650
|
+
* @remarks Time O(1), Space O(1)
|
|
1651
|
+
* @param index - Zero-based index from the front.
|
|
1652
|
+
* @returns Element or undefined.
|
|
1653
|
+
|
|
1654
|
+
|
|
1655
|
+
|
|
1656
|
+
|
|
1657
|
+
|
|
1658
|
+
|
|
1659
|
+
|
|
1660
|
+
|
|
1661
|
+
* @example
|
|
1662
|
+
* // Access element by index
|
|
1663
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
1664
|
+
* console.log(q.at(0)); // 'a';
|
|
1665
|
+
* console.log(q.at(2)); // 'c';
|
|
1666
|
+
*/
|
|
1251
1667
|
at(index) {
|
|
1252
1668
|
if (index < 0 || index >= this.length) return void 0;
|
|
1253
1669
|
return this._elements[this._offset + index];
|
|
@@ -1299,19 +1715,48 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1299
1715
|
return this;
|
|
1300
1716
|
}
|
|
1301
1717
|
/**
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1718
|
+
* Remove all elements and reset offset.
|
|
1719
|
+
* @remarks Time O(1), Space O(1)
|
|
1720
|
+
* @returns void
|
|
1721
|
+
|
|
1722
|
+
|
|
1723
|
+
|
|
1724
|
+
|
|
1725
|
+
|
|
1726
|
+
|
|
1727
|
+
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
* @example
|
|
1731
|
+
* // Remove all elements
|
|
1732
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1733
|
+
* q.clear();
|
|
1734
|
+
* console.log(q.length); // 0;
|
|
1735
|
+
*/
|
|
1306
1736
|
clear() {
|
|
1307
1737
|
this._elements = [];
|
|
1308
1738
|
this._offset = 0;
|
|
1309
1739
|
}
|
|
1310
1740
|
/**
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1741
|
+
* Compact storage by discarding consumed head elements.
|
|
1742
|
+
* @remarks Time O(N), Space O(N)
|
|
1743
|
+
* @returns True when compaction performed.
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
|
|
1747
|
+
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
* @example
|
|
1753
|
+
* // Reclaim unused memory
|
|
1754
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1755
|
+
* q.shift();
|
|
1756
|
+
* q.shift();
|
|
1757
|
+
* q.compact();
|
|
1758
|
+
* console.log(q.length); // 3;
|
|
1759
|
+
*/
|
|
1315
1760
|
compact() {
|
|
1316
1761
|
this._elements = this.elements.slice(this._offset);
|
|
1317
1762
|
this._offset = 0;
|
|
@@ -1337,10 +1782,26 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1337
1782
|
return removed;
|
|
1338
1783
|
}
|
|
1339
1784
|
/**
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1785
|
+
* Deep clone this queue and its parameters.
|
|
1786
|
+
* @remarks Time O(N), Space O(N)
|
|
1787
|
+
* @returns A new queue with the same content and options.
|
|
1788
|
+
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
|
|
1797
|
+
* @example
|
|
1798
|
+
* // Create independent copy
|
|
1799
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1800
|
+
* const copy = q.clone();
|
|
1801
|
+
* copy.shift();
|
|
1802
|
+
* console.log(q.length); // 3;
|
|
1803
|
+
* console.log(copy.length); // 2;
|
|
1804
|
+
*/
|
|
1344
1805
|
clone() {
|
|
1345
1806
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1346
1807
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1348,12 +1809,26 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1348
1809
|
return out;
|
|
1349
1810
|
}
|
|
1350
1811
|
/**
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1812
|
+
* Filter elements into a new queue of the same class.
|
|
1813
|
+
* @remarks Time O(N), Space O(N)
|
|
1814
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
1815
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
1816
|
+
* @returns A new queue with kept elements.
|
|
1817
|
+
|
|
1818
|
+
|
|
1819
|
+
|
|
1820
|
+
|
|
1821
|
+
|
|
1822
|
+
|
|
1823
|
+
|
|
1824
|
+
|
|
1825
|
+
|
|
1826
|
+
* @example
|
|
1827
|
+
* // Filter elements
|
|
1828
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1829
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
1830
|
+
* console.log(evens.length); // 2;
|
|
1831
|
+
*/
|
|
1357
1832
|
filter(predicate, thisArg) {
|
|
1358
1833
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1359
1834
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1365,15 +1840,28 @@ var _Queue = class _Queue extends LinearBase {
|
|
|
1365
1840
|
return out;
|
|
1366
1841
|
}
|
|
1367
1842
|
/**
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1843
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
1844
|
+
* @remarks Time O(N), Space O(N)
|
|
1845
|
+
* @template EM
|
|
1846
|
+
* @template RM
|
|
1847
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
1848
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
1849
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1850
|
+
* @returns A new Queue with mapped elements.
|
|
1851
|
+
|
|
1852
|
+
|
|
1853
|
+
|
|
1854
|
+
|
|
1855
|
+
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
* @example
|
|
1860
|
+
* // Transform elements
|
|
1861
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1862
|
+
* const doubled = q.map(x => x * 2);
|
|
1863
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
1864
|
+
*/
|
|
1377
1865
|
map(callback, options, thisArg) {
|
|
1378
1866
|
var _a, _b;
|
|
1379
1867
|
const out = new this.constructor([], {
|
|
@@ -2473,12 +2961,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2473
2961
|
return new DirectedEdge(src, dest, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
|
|
2474
2962
|
}
|
|
2475
2963
|
/**
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2964
|
+
* Get the unique edge from `src` to `dest`, if present.
|
|
2965
|
+
* @param srcOrKey - Source vertex or key.
|
|
2966
|
+
* @param destOrKey - Destination vertex or key.
|
|
2967
|
+
* @returns Edge instance or `undefined`.
|
|
2968
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
2969
|
+
|
|
2970
|
+
|
|
2971
|
+
|
|
2972
|
+
|
|
2973
|
+
|
|
2974
|
+
|
|
2975
|
+
|
|
2976
|
+
|
|
2977
|
+
* @example
|
|
2978
|
+
* // Get edge between vertices
|
|
2979
|
+
* const g = new DirectedGraph();
|
|
2980
|
+
* g.addVertex('A');
|
|
2981
|
+
* g.addVertex('B');
|
|
2982
|
+
* g.addEdge('A', 'B', 5);
|
|
2983
|
+
* const edge = g.getEdge('A', 'B');
|
|
2984
|
+
* console.log(edge?.weight); // 5;
|
|
2985
|
+
*/
|
|
2482
2986
|
getEdge(srcOrKey, destOrKey) {
|
|
2483
2987
|
let edgeMap = [];
|
|
2484
2988
|
if (srcOrKey !== void 0 && destOrKey !== void 0) {
|
|
@@ -2518,12 +3022,48 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2518
3022
|
return removed;
|
|
2519
3023
|
}
|
|
2520
3024
|
/**
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
3025
|
+
* Delete an edge by instance or by `(srcKey, destKey)`.
|
|
3026
|
+
* @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
|
|
3027
|
+
* @param destVertexKey - Optional destination vertex/key when deleting by pair.
|
|
3028
|
+
* @returns Removed edge or `undefined`.
|
|
3029
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3030
|
+
|
|
3031
|
+
|
|
3032
|
+
|
|
3033
|
+
|
|
3034
|
+
|
|
3035
|
+
|
|
3036
|
+
|
|
3037
|
+
|
|
3038
|
+
|
|
3039
|
+
|
|
3040
|
+
|
|
3041
|
+
* @example
|
|
3042
|
+
* // DirectedGraph deleteEdge and vertex operations
|
|
3043
|
+
* const graph = new DirectedGraph<string>();
|
|
3044
|
+
*
|
|
3045
|
+
* // Build a small graph
|
|
3046
|
+
* graph.addVertex('X');
|
|
3047
|
+
* graph.addVertex('Y');
|
|
3048
|
+
* graph.addVertex('Z');
|
|
3049
|
+
* graph.addEdge('X', 'Y', 1);
|
|
3050
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
3051
|
+
*
|
|
3052
|
+
* // Delete an edge
|
|
3053
|
+
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
3054
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
3055
|
+
*
|
|
3056
|
+
* // Edge in other direction should not exist
|
|
3057
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
3058
|
+
*
|
|
3059
|
+
* // Other edges should remain
|
|
3060
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
3061
|
+
*
|
|
3062
|
+
* // Delete a vertex
|
|
3063
|
+
* graph.deleteVertex('Y');
|
|
3064
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
3065
|
+
* console.log(graph.size); // 2;
|
|
3066
|
+
*/
|
|
2527
3067
|
deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
|
|
2528
3068
|
let removed = void 0;
|
|
2529
3069
|
let src, dest;
|
|
@@ -2550,6 +3090,26 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2550
3090
|
}
|
|
2551
3091
|
return removed;
|
|
2552
3092
|
}
|
|
3093
|
+
/**
|
|
3094
|
+
* Remove a vertex
|
|
3095
|
+
|
|
3096
|
+
|
|
3097
|
+
|
|
3098
|
+
|
|
3099
|
+
|
|
3100
|
+
|
|
3101
|
+
|
|
3102
|
+
|
|
3103
|
+
* @example
|
|
3104
|
+
* // Remove a vertex
|
|
3105
|
+
* const g = new DirectedGraph();
|
|
3106
|
+
* g.addVertex('A');
|
|
3107
|
+
* g.addVertex('B');
|
|
3108
|
+
* g.addEdge('A', 'B');
|
|
3109
|
+
* g.deleteVertex('A');
|
|
3110
|
+
* console.log(g.hasVertex('A')); // false;
|
|
3111
|
+
* console.log(g.hasEdge('A', 'B')); // false;
|
|
3112
|
+
*/
|
|
2553
3113
|
deleteVertex(vertexOrKey) {
|
|
2554
3114
|
let vertexKey;
|
|
2555
3115
|
let vertex;
|
|
@@ -2581,11 +3141,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2581
3141
|
return removed;
|
|
2582
3142
|
}
|
|
2583
3143
|
/**
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
3144
|
+
* Incoming edges of a vertex.
|
|
3145
|
+
* @param vertexOrKey - Vertex or key.
|
|
3146
|
+
* @returns Array of incoming edges.
|
|
3147
|
+
* @remarks Time O(deg_in), Space O(deg_in)
|
|
3148
|
+
|
|
3149
|
+
|
|
3150
|
+
|
|
3151
|
+
|
|
3152
|
+
|
|
3153
|
+
|
|
3154
|
+
|
|
3155
|
+
|
|
3156
|
+
* @example
|
|
3157
|
+
* // Get incoming edges
|
|
3158
|
+
* const g = new DirectedGraph();
|
|
3159
|
+
* g.addVertex('A');
|
|
3160
|
+
* g.addVertex('B');
|
|
3161
|
+
* g.addVertex('C');
|
|
3162
|
+
* g.addEdge('A', 'C');
|
|
3163
|
+
* g.addEdge('B', 'C');
|
|
3164
|
+
* console.log(g.incomingEdgesOf('C').length); // 2;
|
|
3165
|
+
*/
|
|
2589
3166
|
incomingEdgesOf(vertexOrKey) {
|
|
2590
3167
|
const target = this._getVertex(vertexOrKey);
|
|
2591
3168
|
if (target) {
|
|
@@ -2594,11 +3171,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2594
3171
|
return [];
|
|
2595
3172
|
}
|
|
2596
3173
|
/**
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
3174
|
+
* Outgoing edges of a vertex.
|
|
3175
|
+
* @param vertexOrKey - Vertex or key.
|
|
3176
|
+
* @returns Array of outgoing edges.
|
|
3177
|
+
* @remarks Time O(deg_out), Space O(deg_out)
|
|
3178
|
+
|
|
3179
|
+
|
|
3180
|
+
|
|
3181
|
+
|
|
3182
|
+
|
|
3183
|
+
|
|
3184
|
+
|
|
3185
|
+
|
|
3186
|
+
* @example
|
|
3187
|
+
* // Get outgoing edges
|
|
3188
|
+
* const g = new DirectedGraph();
|
|
3189
|
+
* g.addVertex('A');
|
|
3190
|
+
* g.addVertex('B');
|
|
3191
|
+
* g.addVertex('C');
|
|
3192
|
+
* g.addEdge('A', 'B');
|
|
3193
|
+
* g.addEdge('A', 'C');
|
|
3194
|
+
* console.log(g.outgoingEdgesOf('A').length); // 2;
|
|
3195
|
+
*/
|
|
2602
3196
|
outgoingEdgesOf(vertexOrKey) {
|
|
2603
3197
|
const target = this._getVertex(vertexOrKey);
|
|
2604
3198
|
if (target) {
|
|
@@ -2657,11 +3251,44 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2657
3251
|
return destinations;
|
|
2658
3252
|
}
|
|
2659
3253
|
/**
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
3254
|
+
* Topological sort if DAG; returns `undefined` if a cycle exists.
|
|
3255
|
+
* @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
|
|
3256
|
+
* @returns Array of keys/vertices, or `undefined` when cycle is found.
|
|
3257
|
+
* @remarks Time O(V + E), Space O(V)
|
|
3258
|
+
|
|
3259
|
+
|
|
3260
|
+
|
|
3261
|
+
|
|
3262
|
+
|
|
3263
|
+
|
|
3264
|
+
|
|
3265
|
+
|
|
3266
|
+
|
|
3267
|
+
|
|
3268
|
+
|
|
3269
|
+
* @example
|
|
3270
|
+
* // DirectedGraph topologicalSort for task scheduling
|
|
3271
|
+
* const graph = new DirectedGraph<string>();
|
|
3272
|
+
*
|
|
3273
|
+
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
3274
|
+
* graph.addVertex('Design');
|
|
3275
|
+
* graph.addVertex('Implement');
|
|
3276
|
+
* graph.addVertex('Test');
|
|
3277
|
+
* graph.addVertex('Deploy');
|
|
3278
|
+
*
|
|
3279
|
+
* // Add dependency edges
|
|
3280
|
+
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
3281
|
+
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
3282
|
+
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
3283
|
+
*
|
|
3284
|
+
* // Topological sort gives valid execution order
|
|
3285
|
+
* const executionOrder = graph.topologicalSort();
|
|
3286
|
+
* console.log(executionOrder); // defined;
|
|
3287
|
+
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
3288
|
+
*
|
|
3289
|
+
* // All vertices should be included
|
|
3290
|
+
* console.log(executionOrder?.length); // 4;
|
|
3291
|
+
*/
|
|
2665
3292
|
topologicalSort(propertyName) {
|
|
2666
3293
|
propertyName = propertyName != null ? propertyName : "key";
|
|
2667
3294
|
const statusMap = /* @__PURE__ */ new Map();
|
|
@@ -2693,6 +3320,24 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2693
3320
|
if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
|
|
2694
3321
|
return sorted.reverse();
|
|
2695
3322
|
}
|
|
3323
|
+
/**
|
|
3324
|
+
* Get all edges
|
|
3325
|
+
|
|
3326
|
+
|
|
3327
|
+
|
|
3328
|
+
|
|
3329
|
+
|
|
3330
|
+
|
|
3331
|
+
|
|
3332
|
+
|
|
3333
|
+
* @example
|
|
3334
|
+
* // Get all edges
|
|
3335
|
+
* const g = new DirectedGraph();
|
|
3336
|
+
* g.addVertex('A');
|
|
3337
|
+
* g.addVertex('B');
|
|
3338
|
+
* g.addEdge('A', 'B', 3);
|
|
3339
|
+
* console.log(g.edgeSet().length); // 1;
|
|
3340
|
+
*/
|
|
2696
3341
|
edgeSet() {
|
|
2697
3342
|
let edgeMap = [];
|
|
2698
3343
|
this._outEdgeMap.forEach((outEdges) => {
|
|
@@ -2700,6 +3345,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2700
3345
|
});
|
|
2701
3346
|
return edgeMap;
|
|
2702
3347
|
}
|
|
3348
|
+
/**
|
|
3349
|
+
* Get outgoing neighbors
|
|
3350
|
+
|
|
3351
|
+
|
|
3352
|
+
|
|
3353
|
+
|
|
3354
|
+
|
|
3355
|
+
|
|
3356
|
+
|
|
3357
|
+
|
|
3358
|
+
|
|
3359
|
+
* @example
|
|
3360
|
+
* // Get outgoing neighbors
|
|
3361
|
+
* const g = new DirectedGraph();
|
|
3362
|
+
* g.addVertex('A');
|
|
3363
|
+
* g.addVertex('B');
|
|
3364
|
+
* g.addVertex('C');
|
|
3365
|
+
* g.addEdge('A', 'B');
|
|
3366
|
+
* g.addEdge('A', 'C');
|
|
3367
|
+
* const neighbors = g.getNeighbors('A');
|
|
3368
|
+
* console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
|
|
3369
|
+
*/
|
|
2703
3370
|
getNeighbors(vertexOrKey) {
|
|
2704
3371
|
const neighbors = [];
|
|
2705
3372
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -2757,10 +3424,31 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2757
3424
|
return super.clone();
|
|
2758
3425
|
}
|
|
2759
3426
|
/**
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
3427
|
+
* Tarjan's algorithm for strongly connected components.
|
|
3428
|
+
* @returns `{ dfnMap, lowMap, SCCs }`.
|
|
3429
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
3430
|
+
|
|
3431
|
+
|
|
3432
|
+
|
|
3433
|
+
|
|
3434
|
+
|
|
3435
|
+
|
|
3436
|
+
|
|
3437
|
+
|
|
3438
|
+
* @example
|
|
3439
|
+
* // Find strongly connected components
|
|
3440
|
+
* const g = new DirectedGraph();
|
|
3441
|
+
* g.addVertex('A');
|
|
3442
|
+
* g.addVertex('B');
|
|
3443
|
+
* g.addVertex('C');
|
|
3444
|
+
* g.addEdge('A', 'B');
|
|
3445
|
+
* g.addEdge('B', 'C');
|
|
3446
|
+
* g.addEdge('C', 'A');
|
|
3447
|
+
* const { SCCs } = g.tarjan();
|
|
3448
|
+
* // A→B→C→A forms one SCC with 3 members
|
|
3449
|
+
* const sccArrays = [...SCCs.values()];
|
|
3450
|
+
* console.log(sccArrays.some(scc => scc.length === 3)); // true;
|
|
3451
|
+
*/
|
|
2764
3452
|
tarjan() {
|
|
2765
3453
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
2766
3454
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -2818,10 +3506,29 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2818
3506
|
return this.tarjan().lowMap;
|
|
2819
3507
|
}
|
|
2820
3508
|
/**
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
3509
|
+
* Strongly connected components computed by `tarjan()`.
|
|
3510
|
+
* @returns Map from SCC id to vertices.
|
|
3511
|
+
* @remarks Time O(#SCC + V), Space O(V)
|
|
3512
|
+
|
|
3513
|
+
|
|
3514
|
+
|
|
3515
|
+
|
|
3516
|
+
|
|
3517
|
+
|
|
3518
|
+
|
|
3519
|
+
|
|
3520
|
+
* @example
|
|
3521
|
+
* // Get strongly connected components
|
|
3522
|
+
* const g = new DirectedGraph();
|
|
3523
|
+
* g.addVertex(1);
|
|
3524
|
+
* g.addVertex(2);
|
|
3525
|
+
* g.addVertex(3);
|
|
3526
|
+
* g.addEdge(1, 2);
|
|
3527
|
+
* g.addEdge(2, 3);
|
|
3528
|
+
* g.addEdge(3, 1);
|
|
3529
|
+
* const sccs = g.getSCCs(); // Map<number, VO[]>
|
|
3530
|
+
* console.log(sccs.size); // >= 1;
|
|
3531
|
+
*/
|
|
2825
3532
|
getSCCs() {
|
|
2826
3533
|
return this.tarjan().SCCs;
|
|
2827
3534
|
}
|