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