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
package/dist/esm/index.mjs
CHANGED
|
@@ -271,7 +271,7 @@ var IterableElementBase = class {
|
|
|
271
271
|
if (options) {
|
|
272
272
|
const { toElementFn } = options;
|
|
273
273
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
274
|
-
else if (toElementFn) throw new TypeError(
|
|
274
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
275
275
|
}
|
|
276
276
|
}
|
|
277
277
|
/**
|
|
@@ -434,7 +434,7 @@ var IterableElementBase = class {
|
|
|
434
434
|
acc = initialValue;
|
|
435
435
|
} else {
|
|
436
436
|
const first = iter.next();
|
|
437
|
-
if (first.done) throw new TypeError(
|
|
437
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
438
438
|
acc = first.value;
|
|
439
439
|
index = 1;
|
|
440
440
|
}
|
|
@@ -507,10 +507,30 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
507
507
|
return this._elements;
|
|
508
508
|
}
|
|
509
509
|
/**
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
510
|
+
* Get the number of elements.
|
|
511
|
+
* @remarks Time O(1), Space O(1)
|
|
512
|
+
* @returns Heap size.
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
* @example
|
|
525
|
+
* // Track heap capacity
|
|
526
|
+
* const heap = new Heap<number>();
|
|
527
|
+
* console.log(heap.size); // 0;
|
|
528
|
+
* heap.add(10);
|
|
529
|
+
* heap.add(20);
|
|
530
|
+
* console.log(heap.size); // 2;
|
|
531
|
+
* heap.poll();
|
|
532
|
+
* console.log(heap.size); // 1;
|
|
533
|
+
*/
|
|
514
534
|
get size() {
|
|
515
535
|
return this.elements.length;
|
|
516
536
|
}
|
|
@@ -548,21 +568,61 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
548
568
|
return new _Heap(elements, options);
|
|
549
569
|
}
|
|
550
570
|
/**
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
571
|
+
* Insert an element.
|
|
572
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
573
|
+
* @param element - Element to insert.
|
|
574
|
+
* @returns True.
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
* @example
|
|
587
|
+
* // basic Heap creation and add operation
|
|
588
|
+
* // Create a min heap (default)
|
|
589
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
590
|
+
*
|
|
591
|
+
* // Verify size
|
|
592
|
+
* console.log(minHeap.size); // 6;
|
|
593
|
+
*
|
|
594
|
+
* // Add new element
|
|
595
|
+
* minHeap.add(4);
|
|
596
|
+
* console.log(minHeap.size); // 7;
|
|
597
|
+
*
|
|
598
|
+
* // Min heap property: smallest element at root
|
|
599
|
+
* const min = minHeap.peek();
|
|
600
|
+
* console.log(min); // 1;
|
|
601
|
+
*/
|
|
556
602
|
add(element) {
|
|
557
603
|
this._elements.push(element);
|
|
558
604
|
return this._bubbleUp(this.elements.length - 1);
|
|
559
605
|
}
|
|
560
606
|
/**
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
607
|
+
* Insert many elements from an iterable.
|
|
608
|
+
* @remarks Time O(N log N), Space O(1)
|
|
609
|
+
* @param elements - Iterable of elements or raw values.
|
|
610
|
+
* @returns Array of per-element success flags.
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
* @example
|
|
620
|
+
* // Add multiple elements
|
|
621
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
622
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
623
|
+
* console.log(heap.peek()); // 1;
|
|
624
|
+
* console.log(heap.size); // 4;
|
|
625
|
+
*/
|
|
566
626
|
addMany(elements) {
|
|
567
627
|
const flags = [];
|
|
568
628
|
for (const el of elements) {
|
|
@@ -577,10 +637,46 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
577
637
|
return flags;
|
|
578
638
|
}
|
|
579
639
|
/**
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
640
|
+
* Remove and return the top element.
|
|
641
|
+
* @remarks Time O(log N), Space O(1)
|
|
642
|
+
* @returns Top element or undefined.
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
* @example
|
|
655
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
656
|
+
* interface Task {
|
|
657
|
+
* id: number;
|
|
658
|
+
* priority: number;
|
|
659
|
+
* name: string;
|
|
660
|
+
* }
|
|
661
|
+
*
|
|
662
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
663
|
+
* const tasks: Task[] = [
|
|
664
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
665
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
666
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
667
|
+
* ];
|
|
668
|
+
*
|
|
669
|
+
* const maxHeap = new Heap(tasks, {
|
|
670
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
671
|
+
* });
|
|
672
|
+
*
|
|
673
|
+
* console.log(maxHeap.size); // 3;
|
|
674
|
+
*
|
|
675
|
+
* // Peek returns highest priority task
|
|
676
|
+
* const topTask = maxHeap.peek();
|
|
677
|
+
* console.log(topTask?.priority); // 8;
|
|
678
|
+
* console.log(topTask?.name); // 'Alert';
|
|
679
|
+
*/
|
|
584
680
|
poll() {
|
|
585
681
|
if (this.elements.length === 0) return;
|
|
586
682
|
const value = this.elements[0];
|
|
@@ -592,26 +688,125 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
592
688
|
return value;
|
|
593
689
|
}
|
|
594
690
|
/**
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
691
|
+
* Get the current top element without removing it.
|
|
692
|
+
* @remarks Time O(1), Space O(1)
|
|
693
|
+
* @returns Top element or undefined.
|
|
694
|
+
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
* @example
|
|
706
|
+
* // Heap for event processing with priority
|
|
707
|
+
* interface Event {
|
|
708
|
+
* id: number;
|
|
709
|
+
* type: 'critical' | 'warning' | 'info';
|
|
710
|
+
* timestamp: number;
|
|
711
|
+
* message: string;
|
|
712
|
+
* }
|
|
713
|
+
*
|
|
714
|
+
* // Custom priority: critical > warning > info
|
|
715
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
716
|
+
*
|
|
717
|
+
* const eventHeap = new Heap<Event>([], {
|
|
718
|
+
* comparator: (a: Event, b: Event) => {
|
|
719
|
+
* const priorityA = priorityMap[a.type];
|
|
720
|
+
* const priorityB = priorityMap[b.type];
|
|
721
|
+
* return priorityB - priorityA; // Higher priority first
|
|
722
|
+
* }
|
|
723
|
+
* });
|
|
724
|
+
*
|
|
725
|
+
* // Add events in random order
|
|
726
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
727
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
728
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
729
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
730
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
731
|
+
*
|
|
732
|
+
* console.log(eventHeap.size); // 5;
|
|
733
|
+
*
|
|
734
|
+
* // Process events by priority (critical first)
|
|
735
|
+
* const processedOrder: Event[] = [];
|
|
736
|
+
* while (eventHeap.size > 0) {
|
|
737
|
+
* const event = eventHeap.poll();
|
|
738
|
+
* if (event) {
|
|
739
|
+
* processedOrder.push(event);
|
|
740
|
+
* }
|
|
741
|
+
* }
|
|
742
|
+
*
|
|
743
|
+
* // Verify critical events came first
|
|
744
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
745
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
746
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
747
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
748
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
749
|
+
*
|
|
750
|
+
* // Verify O(log n) operations
|
|
751
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
752
|
+
*
|
|
753
|
+
* // Add - O(log n)
|
|
754
|
+
* newHeap.add(2);
|
|
755
|
+
* console.log(newHeap.size); // 5;
|
|
756
|
+
*
|
|
757
|
+
* // Poll - O(log n)
|
|
758
|
+
* const removed = newHeap.poll();
|
|
759
|
+
* console.log(removed); // 1;
|
|
760
|
+
*
|
|
761
|
+
* // Peek - O(1)
|
|
762
|
+
* const top = newHeap.peek();
|
|
763
|
+
* console.log(top); // 2;
|
|
764
|
+
*/
|
|
599
765
|
peek() {
|
|
600
766
|
return this.elements[0];
|
|
601
767
|
}
|
|
602
768
|
/**
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
769
|
+
* Check whether the heap is empty.
|
|
770
|
+
* @remarks Time O(1), Space O(1)
|
|
771
|
+
* @returns True if size is 0.
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
* @example
|
|
782
|
+
* // Check if heap is empty
|
|
783
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
784
|
+
* console.log(heap.isEmpty()); // true;
|
|
785
|
+
* heap.add(1);
|
|
786
|
+
* console.log(heap.isEmpty()); // false;
|
|
787
|
+
*/
|
|
607
788
|
isEmpty() {
|
|
608
789
|
return this.size === 0;
|
|
609
790
|
}
|
|
610
791
|
/**
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
792
|
+
* Remove all elements.
|
|
793
|
+
* @remarks Time O(1), Space O(1)
|
|
794
|
+
* @returns void
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
* @example
|
|
805
|
+
* // Remove all elements
|
|
806
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
807
|
+
* heap.clear();
|
|
808
|
+
* console.log(heap.isEmpty()); // true;
|
|
809
|
+
*/
|
|
615
810
|
clear() {
|
|
616
811
|
this._elements = [];
|
|
617
812
|
}
|
|
@@ -626,21 +821,41 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
626
821
|
return this.fix();
|
|
627
822
|
}
|
|
628
823
|
/**
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
824
|
+
* Check if an equal element exists in the heap.
|
|
825
|
+
* @remarks Time O(N), Space O(1)
|
|
826
|
+
* @param element - Element to search for.
|
|
827
|
+
* @returns True if found.
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
* @example
|
|
831
|
+
* // Check element existence
|
|
832
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
833
|
+
* console.log(heap.has(1)); // true;
|
|
834
|
+
* console.log(heap.has(99)); // false;
|
|
835
|
+
*/
|
|
634
836
|
has(element) {
|
|
635
837
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
636
838
|
return false;
|
|
637
839
|
}
|
|
638
840
|
/**
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
841
|
+
* Delete one occurrence of an element.
|
|
842
|
+
* @remarks Time O(N), Space O(1)
|
|
843
|
+
* @param element - Element to delete.
|
|
844
|
+
* @returns True if an element was removed.
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
* @example
|
|
854
|
+
* // Remove specific element
|
|
855
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
856
|
+
* heap.delete(4);
|
|
857
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
858
|
+
*/
|
|
644
859
|
delete(element) {
|
|
645
860
|
let index = -1;
|
|
646
861
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -698,11 +913,18 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
698
913
|
return this;
|
|
699
914
|
}
|
|
700
915
|
/**
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
916
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
917
|
+
* @remarks Time O(N), Space O(H)
|
|
918
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
919
|
+
* @returns Array of visited elements.
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
* @example
|
|
923
|
+
* // Depth-first traversal
|
|
924
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
925
|
+
* const result = heap.dfs('IN');
|
|
926
|
+
* console.log(result.length); // 3;
|
|
927
|
+
*/
|
|
706
928
|
dfs(order = "PRE") {
|
|
707
929
|
const result = [];
|
|
708
930
|
const _dfs = /* @__PURE__ */ __name((index) => {
|
|
@@ -739,10 +961,26 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
739
961
|
return results;
|
|
740
962
|
}
|
|
741
963
|
/**
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
964
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
965
|
+
* @remarks Time O(N log N), Space O(N)
|
|
966
|
+
* @returns Sorted array of elements.
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
* @example
|
|
979
|
+
* // Sort elements using heap
|
|
980
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
981
|
+
* const sorted = heap.sort();
|
|
982
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
983
|
+
*/
|
|
746
984
|
sort() {
|
|
747
985
|
const visited = [];
|
|
748
986
|
const cloned = this._createInstance();
|
|
@@ -754,22 +992,52 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
754
992
|
return visited;
|
|
755
993
|
}
|
|
756
994
|
/**
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
995
|
+
* Deep clone this heap.
|
|
996
|
+
* @remarks Time O(N), Space O(N)
|
|
997
|
+
* @returns A new heap with the same elements.
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
* @example
|
|
1008
|
+
* // Create independent copy
|
|
1009
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
1010
|
+
* const copy = heap.clone();
|
|
1011
|
+
* copy.poll();
|
|
1012
|
+
* console.log(heap.size); // 3;
|
|
1013
|
+
* console.log(copy.size); // 2;
|
|
1014
|
+
*/
|
|
761
1015
|
clone() {
|
|
762
1016
|
const next = this._createInstance();
|
|
763
1017
|
for (const x of this.elements) next.add(x);
|
|
764
1018
|
return next;
|
|
765
1019
|
}
|
|
766
1020
|
/**
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
1021
|
+
* Filter elements into a new heap of the same class.
|
|
1022
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1023
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
1024
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1025
|
+
* @returns A new heap with the kept elements.
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
* @example
|
|
1036
|
+
* // Filter elements
|
|
1037
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
1038
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
1039
|
+
* console.log(evens.size); // 2;
|
|
1040
|
+
*/
|
|
773
1041
|
filter(callback, thisArg) {
|
|
774
1042
|
const out = this._createInstance();
|
|
775
1043
|
let i = 0;
|
|
@@ -783,15 +1051,28 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
783
1051
|
return out;
|
|
784
1052
|
}
|
|
785
1053
|
/**
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
1054
|
+
* Map elements into a new heap of possibly different element type.
|
|
1055
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1056
|
+
* @template EM
|
|
1057
|
+
* @template RM
|
|
1058
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
1059
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
1060
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1061
|
+
* @returns A new heap with mapped elements.
|
|
1062
|
+
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
* @example
|
|
1071
|
+
* // Transform elements
|
|
1072
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1073
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
1074
|
+
* console.log(doubled.peek()); // 2;
|
|
1075
|
+
*/
|
|
795
1076
|
map(callback, options, thisArg) {
|
|
796
1077
|
const { comparator, toElementFn, ...rest } = options ?? {};
|
|
797
1078
|
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
@@ -1154,18 +1435,52 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1154
1435
|
this._autoCompactRatio = value;
|
|
1155
1436
|
}
|
|
1156
1437
|
/**
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1438
|
+
* Get the number of elements currently in the queue.
|
|
1439
|
+
* @remarks Time O(1), Space O(1)
|
|
1440
|
+
* @returns Current length.
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
* @example
|
|
1453
|
+
* // Track queue length
|
|
1454
|
+
* const q = new Queue<number>();
|
|
1455
|
+
* console.log(q.length); // 0;
|
|
1456
|
+
* q.push(1);
|
|
1457
|
+
* q.push(2);
|
|
1458
|
+
* console.log(q.length); // 2;
|
|
1459
|
+
*/
|
|
1161
1460
|
get length() {
|
|
1162
1461
|
return this.elements.length - this._offset;
|
|
1163
1462
|
}
|
|
1164
1463
|
/**
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1464
|
+
* Get the first element (front) without removing it.
|
|
1465
|
+
* @remarks Time O(1), Space O(1)
|
|
1466
|
+
* @returns Front element or undefined.
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
|
|
1470
|
+
|
|
1471
|
+
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
|
|
1478
|
+
* @example
|
|
1479
|
+
* // View the front element
|
|
1480
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
1481
|
+
* console.log(q.first); // 'first';
|
|
1482
|
+
* console.log(q.length); // 3;
|
|
1483
|
+
*/
|
|
1169
1484
|
get first() {
|
|
1170
1485
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
1171
1486
|
}
|
|
@@ -1188,19 +1503,69 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1188
1503
|
return new _Queue(elements);
|
|
1189
1504
|
}
|
|
1190
1505
|
/**
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1506
|
+
* Check whether the queue is empty.
|
|
1507
|
+
* @remarks Time O(1), Space O(1)
|
|
1508
|
+
* @returns True if length is 0.
|
|
1509
|
+
|
|
1510
|
+
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
|
|
1514
|
+
|
|
1515
|
+
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
|
|
1519
|
+
|
|
1520
|
+
* @example
|
|
1521
|
+
* // Queue for...of iteration and isEmpty check
|
|
1522
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
1523
|
+
*
|
|
1524
|
+
* const elements: string[] = [];
|
|
1525
|
+
* for (const item of queue) {
|
|
1526
|
+
* elements.push(item);
|
|
1527
|
+
* }
|
|
1528
|
+
*
|
|
1529
|
+
* // Verify all elements are iterated in order
|
|
1530
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
1531
|
+
*
|
|
1532
|
+
* // Process all elements
|
|
1533
|
+
* while (queue.length > 0) {
|
|
1534
|
+
* queue.shift();
|
|
1535
|
+
* }
|
|
1536
|
+
*
|
|
1537
|
+
* console.log(queue.length); // 0;
|
|
1538
|
+
*/
|
|
1195
1539
|
isEmpty() {
|
|
1196
1540
|
return this.length === 0;
|
|
1197
1541
|
}
|
|
1198
1542
|
/**
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1543
|
+
* Enqueue one element at the back.
|
|
1544
|
+
* @remarks Time O(1), Space O(1)
|
|
1545
|
+
* @param element - Element to enqueue.
|
|
1546
|
+
* @returns True on success.
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
* @example
|
|
1559
|
+
* // basic Queue creation and push operation
|
|
1560
|
+
* // Create a simple Queue with initial values
|
|
1561
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
1562
|
+
*
|
|
1563
|
+
* // Verify the queue maintains insertion order
|
|
1564
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
1565
|
+
*
|
|
1566
|
+
* // Check length
|
|
1567
|
+
* console.log(queue.length); // 5;
|
|
1568
|
+
*/
|
|
1204
1569
|
push(element) {
|
|
1205
1570
|
this.elements.push(element);
|
|
1206
1571
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -1221,10 +1586,35 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1221
1586
|
return ans;
|
|
1222
1587
|
}
|
|
1223
1588
|
/**
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1589
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1590
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1591
|
+
* @returns Removed element or undefined.
|
|
1592
|
+
|
|
1593
|
+
|
|
1594
|
+
|
|
1595
|
+
|
|
1596
|
+
|
|
1597
|
+
|
|
1598
|
+
|
|
1599
|
+
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
|
|
1603
|
+
* @example
|
|
1604
|
+
* // Queue shift and peek operations
|
|
1605
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
1606
|
+
*
|
|
1607
|
+
* // Peek at the front element without removing it
|
|
1608
|
+
* console.log(queue.first); // 10;
|
|
1609
|
+
*
|
|
1610
|
+
* // Remove and get the first element (FIFO)
|
|
1611
|
+
* const first = queue.shift();
|
|
1612
|
+
* console.log(first); // 10;
|
|
1613
|
+
*
|
|
1614
|
+
* // Verify remaining elements and length decreased
|
|
1615
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
1616
|
+
* console.log(queue.length); // 3;
|
|
1617
|
+
*/
|
|
1228
1618
|
shift() {
|
|
1229
1619
|
if (this.length === 0) return void 0;
|
|
1230
1620
|
const first = this.first;
|
|
@@ -1233,11 +1623,24 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1233
1623
|
return first;
|
|
1234
1624
|
}
|
|
1235
1625
|
/**
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1626
|
+
* Delete the first occurrence of a specific element.
|
|
1627
|
+
* @remarks Time O(N), Space O(1)
|
|
1628
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
1629
|
+
* @returns True if an element was removed.
|
|
1630
|
+
|
|
1631
|
+
|
|
1632
|
+
|
|
1633
|
+
|
|
1634
|
+
|
|
1635
|
+
|
|
1636
|
+
|
|
1637
|
+
|
|
1638
|
+
* @example
|
|
1639
|
+
* // Remove specific element
|
|
1640
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
1641
|
+
* q.delete(2);
|
|
1642
|
+
* console.log(q.length); // 3;
|
|
1643
|
+
*/
|
|
1241
1644
|
delete(element) {
|
|
1242
1645
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
1243
1646
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -1248,11 +1651,24 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1248
1651
|
return false;
|
|
1249
1652
|
}
|
|
1250
1653
|
/**
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1654
|
+
* Get the element at a given logical index.
|
|
1655
|
+
* @remarks Time O(1), Space O(1)
|
|
1656
|
+
* @param index - Zero-based index from the front.
|
|
1657
|
+
* @returns Element or undefined.
|
|
1658
|
+
|
|
1659
|
+
|
|
1660
|
+
|
|
1661
|
+
|
|
1662
|
+
|
|
1663
|
+
|
|
1664
|
+
|
|
1665
|
+
|
|
1666
|
+
* @example
|
|
1667
|
+
* // Access element by index
|
|
1668
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
1669
|
+
* console.log(q.at(0)); // 'a';
|
|
1670
|
+
* console.log(q.at(2)); // 'c';
|
|
1671
|
+
*/
|
|
1256
1672
|
at(index) {
|
|
1257
1673
|
if (index < 0 || index >= this.length) return void 0;
|
|
1258
1674
|
return this._elements[this._offset + index];
|
|
@@ -1304,19 +1720,48 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1304
1720
|
return this;
|
|
1305
1721
|
}
|
|
1306
1722
|
/**
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1723
|
+
* Remove all elements and reset offset.
|
|
1724
|
+
* @remarks Time O(1), Space O(1)
|
|
1725
|
+
* @returns void
|
|
1726
|
+
|
|
1727
|
+
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
|
|
1731
|
+
|
|
1732
|
+
|
|
1733
|
+
|
|
1734
|
+
|
|
1735
|
+
* @example
|
|
1736
|
+
* // Remove all elements
|
|
1737
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1738
|
+
* q.clear();
|
|
1739
|
+
* console.log(q.length); // 0;
|
|
1740
|
+
*/
|
|
1311
1741
|
clear() {
|
|
1312
1742
|
this._elements = [];
|
|
1313
1743
|
this._offset = 0;
|
|
1314
1744
|
}
|
|
1315
1745
|
/**
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1746
|
+
* Compact storage by discarding consumed head elements.
|
|
1747
|
+
* @remarks Time O(N), Space O(N)
|
|
1748
|
+
* @returns True when compaction performed.
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
* @example
|
|
1758
|
+
* // Reclaim unused memory
|
|
1759
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1760
|
+
* q.shift();
|
|
1761
|
+
* q.shift();
|
|
1762
|
+
* q.compact();
|
|
1763
|
+
* console.log(q.length); // 3;
|
|
1764
|
+
*/
|
|
1320
1765
|
compact() {
|
|
1321
1766
|
this._elements = this.elements.slice(this._offset);
|
|
1322
1767
|
this._offset = 0;
|
|
@@ -1342,10 +1787,26 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1342
1787
|
return removed;
|
|
1343
1788
|
}
|
|
1344
1789
|
/**
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1790
|
+
* Deep clone this queue and its parameters.
|
|
1791
|
+
* @remarks Time O(N), Space O(N)
|
|
1792
|
+
* @returns A new queue with the same content and options.
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
|
|
1797
|
+
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
|
|
1801
|
+
|
|
1802
|
+
* @example
|
|
1803
|
+
* // Create independent copy
|
|
1804
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1805
|
+
* const copy = q.clone();
|
|
1806
|
+
* copy.shift();
|
|
1807
|
+
* console.log(q.length); // 3;
|
|
1808
|
+
* console.log(copy.length); // 2;
|
|
1809
|
+
*/
|
|
1349
1810
|
clone() {
|
|
1350
1811
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1351
1812
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1353,12 +1814,26 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1353
1814
|
return out;
|
|
1354
1815
|
}
|
|
1355
1816
|
/**
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1817
|
+
* Filter elements into a new queue of the same class.
|
|
1818
|
+
* @remarks Time O(N), Space O(N)
|
|
1819
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
1820
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
1821
|
+
* @returns A new queue with kept elements.
|
|
1822
|
+
|
|
1823
|
+
|
|
1824
|
+
|
|
1825
|
+
|
|
1826
|
+
|
|
1827
|
+
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
|
|
1831
|
+
* @example
|
|
1832
|
+
* // Filter elements
|
|
1833
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1834
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
1835
|
+
* console.log(evens.length); // 2;
|
|
1836
|
+
*/
|
|
1362
1837
|
filter(predicate, thisArg) {
|
|
1363
1838
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1364
1839
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1370,15 +1845,28 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1370
1845
|
return out;
|
|
1371
1846
|
}
|
|
1372
1847
|
/**
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1848
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
1849
|
+
* @remarks Time O(N), Space O(N)
|
|
1850
|
+
* @template EM
|
|
1851
|
+
* @template RM
|
|
1852
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
1853
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
1854
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1855
|
+
* @returns A new Queue with mapped elements.
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
|
|
1861
|
+
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
* @example
|
|
1865
|
+
* // Transform elements
|
|
1866
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1867
|
+
* const doubled = q.map(x => x * 2);
|
|
1868
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
1869
|
+
*/
|
|
1382
1870
|
map(callback, options, thisArg) {
|
|
1383
1871
|
const out = new this.constructor([], {
|
|
1384
1872
|
toElementFn: options?.toElementFn,
|
|
@@ -2475,12 +2963,28 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2475
2963
|
return new DirectedEdge(src, dest, weight ?? this.options.defaultEdgeWeight ?? 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 ?? "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
|
}
|