graph-typed 2.4.4 → 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.
Files changed (84) hide show
  1. package/dist/cjs/index.cjs +1324 -220
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +1325 -219
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +1324 -221
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +1325 -220
  8. package/dist/esm-legacy/index.mjs.map +1 -1
  9. package/dist/types/common/error.d.ts +23 -0
  10. package/dist/types/common/index.d.ts +1 -0
  11. package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
  12. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
  13. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
  14. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
  15. package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
  16. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
  17. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
  18. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
  19. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
  20. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
  21. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
  22. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  23. package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
  24. package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
  25. package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
  26. package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
  27. package/dist/types/data-structures/heap/heap.d.ts +287 -99
  28. package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
  29. package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
  30. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
  31. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
  32. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
  33. package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
  34. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
  35. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
  36. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
  37. package/dist/types/data-structures/queue/deque.d.ts +313 -66
  38. package/dist/types/data-structures/queue/queue.d.ts +211 -42
  39. package/dist/types/data-structures/stack/stack.d.ts +174 -32
  40. package/dist/types/data-structures/trie/trie.d.ts +213 -43
  41. package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
  42. package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
  43. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  44. package/dist/umd/graph-typed.js +1323 -217
  45. package/dist/umd/graph-typed.js.map +1 -1
  46. package/dist/umd/graph-typed.min.js +3 -1
  47. package/dist/umd/graph-typed.min.js.map +1 -1
  48. package/package.json +2 -2
  49. package/src/common/error.ts +60 -0
  50. package/src/common/index.ts +2 -0
  51. package/src/data-structures/base/iterable-element-base.ts +2 -2
  52. package/src/data-structures/binary-tree/avl-tree.ts +134 -51
  53. package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
  54. package/src/data-structures/binary-tree/binary-tree.ts +542 -121
  55. package/src/data-structures/binary-tree/bst.ts +346 -37
  56. package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
  57. package/src/data-structures/binary-tree/segment-tree.ts +372 -248
  58. package/src/data-structures/binary-tree/tree-map.ts +1292 -13
  59. package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
  60. package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
  61. package/src/data-structures/binary-tree/tree-set.ts +1143 -15
  62. package/src/data-structures/graph/abstract-graph.ts +106 -1
  63. package/src/data-structures/graph/directed-graph.ts +223 -47
  64. package/src/data-structures/graph/map-graph.ts +59 -1
  65. package/src/data-structures/graph/undirected-graph.ts +299 -59
  66. package/src/data-structures/hash/hash-map.ts +243 -79
  67. package/src/data-structures/heap/heap.ts +291 -102
  68. package/src/data-structures/heap/max-heap.ts +48 -3
  69. package/src/data-structures/heap/min-heap.ts +59 -0
  70. package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
  71. package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
  72. package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
  73. package/src/data-structures/matrix/matrix.ts +425 -22
  74. package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
  75. package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
  76. package/src/data-structures/priority-queue/priority-queue.ts +60 -0
  77. package/src/data-structures/queue/deque.ts +343 -68
  78. package/src/data-structures/queue/queue.ts +211 -42
  79. package/src/data-structures/stack/stack.ts +174 -32
  80. package/src/data-structures/trie/trie.ts +215 -44
  81. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
  82. package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
  83. package/src/types/data-structures/queue/deque.ts +7 -0
  84. package/src/utils/utils.ts +4 -2
@@ -26,6 +26,54 @@ var arrayRemove = /* @__PURE__ */ __name(function(array, predicate) {
26
26
  return result;
27
27
  }, "arrayRemove");
28
28
 
29
+ // src/common/error.ts
30
+ var ERR = {
31
+ // Range / index
32
+ indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
33
+ invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
34
+ // Type / argument
35
+ invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
36
+ comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
37
+ invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
38
+ notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
39
+ invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
40
+ invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
41
+ invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
42
+ reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
43
+ callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
44
+ // State / operation
45
+ invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
46
+ // Matrix
47
+ matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
48
+ matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
49
+ matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
50
+ matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
51
+ matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
52
+ };
53
+
54
+ // src/common/index.ts
55
+ var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
56
+ DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
57
+ DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
58
+ return DFSOperation2;
59
+ })(DFSOperation || {});
60
+ var _Range = class _Range {
61
+ constructor(low, high, includeLow = true, includeHigh = true) {
62
+ this.low = low;
63
+ this.high = high;
64
+ this.includeLow = includeLow;
65
+ this.includeHigh = includeHigh;
66
+ }
67
+ // Determine whether a key is within the range
68
+ isInRange(key, comparator) {
69
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
70
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
71
+ return lowCheck && highCheck;
72
+ }
73
+ };
74
+ __name(_Range, "Range");
75
+ var Range = _Range;
76
+
29
77
  // src/data-structures/base/iterable-entry-base.ts
30
78
  var _IterableEntryBase = class _IterableEntryBase {
31
79
  /**
@@ -444,7 +492,7 @@ var _Heap = class _Heap extends IterableElementBase {
444
492
  __publicField(this, "_elements", []);
445
493
  __publicField(this, "_DEFAULT_COMPARATOR", /* @__PURE__ */ __name((a, b) => {
446
494
  if (typeof a === "object" || typeof b === "object") {
447
- throw TypeError("When comparing object types, define a custom comparator in options.");
495
+ throw new TypeError(ERR.comparatorRequired("Heap"));
448
496
  }
449
497
  if (a > b) return 1;
450
498
  if (a < b) return -1;
@@ -466,10 +514,30 @@ var _Heap = class _Heap extends IterableElementBase {
466
514
  return this._elements;
467
515
  }
468
516
  /**
469
- * Get the number of elements.
470
- * @remarks Time O(1), Space O(1)
471
- * @returns Heap size.
472
- */
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
+ */
473
541
  get size() {
474
542
  return this.elements.length;
475
543
  }
@@ -508,21 +576,61 @@ var _Heap = class _Heap extends IterableElementBase {
508
576
  return new _Heap(elements, options);
509
577
  }
510
578
  /**
511
- * Insert an element.
512
- * @remarks Time O(1) amortized, Space O(1)
513
- * @param element - Element to insert.
514
- * @returns True.
515
- */
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
+ */
516
610
  add(element) {
517
611
  this._elements.push(element);
518
612
  return this._bubbleUp(this.elements.length - 1);
519
613
  }
520
614
  /**
521
- * Insert many elements from an iterable.
522
- * @remarks Time O(N log N), Space O(1)
523
- * @param elements - Iterable of elements or raw values.
524
- * @returns Array of per-element success flags.
525
- */
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
+ */
526
634
  addMany(elements) {
527
635
  const flags = [];
528
636
  for (const el of elements) {
@@ -537,10 +645,46 @@ var _Heap = class _Heap extends IterableElementBase {
537
645
  return flags;
538
646
  }
539
647
  /**
540
- * Remove and return the top element.
541
- * @remarks Time O(log N), Space O(1)
542
- * @returns Top element or undefined.
543
- */
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
+ */
544
688
  poll() {
545
689
  if (this.elements.length === 0) return;
546
690
  const value = this.elements[0];
@@ -552,26 +696,125 @@ var _Heap = class _Heap extends IterableElementBase {
552
696
  return value;
553
697
  }
554
698
  /**
555
- * Get the current top element without removing it.
556
- * @remarks Time O(1), Space O(1)
557
- * @returns Top element or undefined.
558
- */
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
+ */
559
773
  peek() {
560
774
  return this.elements[0];
561
775
  }
562
776
  /**
563
- * Check whether the heap is empty.
564
- * @remarks Time O(1), Space O(1)
565
- * @returns True if size is 0.
566
- */
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
+ */
567
796
  isEmpty() {
568
797
  return this.size === 0;
569
798
  }
570
799
  /**
571
- * Remove all elements.
572
- * @remarks Time O(1), Space O(1)
573
- * @returns void
574
- */
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
+ */
575
818
  clear() {
576
819
  this._elements = [];
577
820
  }
@@ -586,21 +829,41 @@ var _Heap = class _Heap extends IterableElementBase {
586
829
  return this.fix();
587
830
  }
588
831
  /**
589
- * Check if an equal element exists in the heap.
590
- * @remarks Time O(N), Space O(1)
591
- * @param element - Element to search for.
592
- * @returns True if found.
593
- */
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
+ */
594
844
  has(element) {
595
845
  for (const el of this.elements) if (this._equals(el, element)) return true;
596
846
  return false;
597
847
  }
598
848
  /**
599
- * Delete one occurrence of an element.
600
- * @remarks Time O(N), Space O(1)
601
- * @param element - Element to delete.
602
- * @returns True if an element was removed.
603
- */
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
+ */
604
867
  delete(element) {
605
868
  let index = -1;
606
869
  for (let i = 0; i < this.elements.length; i++) {
@@ -658,11 +921,18 @@ var _Heap = class _Heap extends IterableElementBase {
658
921
  return this;
659
922
  }
660
923
  /**
661
- * Traverse the binary heap as a complete binary tree and collect elements.
662
- * @remarks Time O(N), Space O(H)
663
- * @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
664
- * @returns Array of visited elements.
665
- */
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
+ */
666
936
  dfs(order = "PRE") {
667
937
  const result = [];
668
938
  const _dfs = /* @__PURE__ */ __name((index) => {
@@ -699,10 +969,26 @@ var _Heap = class _Heap extends IterableElementBase {
699
969
  return results;
700
970
  }
701
971
  /**
702
- * Return all elements in ascending order by repeatedly polling.
703
- * @remarks Time O(N log N), Space O(N)
704
- * @returns Sorted array of elements.
705
- */
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
+ */
706
992
  sort() {
707
993
  const visited = [];
708
994
  const cloned = this._createInstance();
@@ -714,22 +1000,52 @@ var _Heap = class _Heap extends IterableElementBase {
714
1000
  return visited;
715
1001
  }
716
1002
  /**
717
- * Deep clone this heap.
718
- * @remarks Time O(N), Space O(N)
719
- * @returns A new heap with the same elements.
720
- */
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
+ */
721
1023
  clone() {
722
1024
  const next = this._createInstance();
723
1025
  for (const x of this.elements) next.add(x);
724
1026
  return next;
725
1027
  }
726
1028
  /**
727
- * Filter elements into a new heap of the same class.
728
- * @remarks Time O(N log N), Space O(N)
729
- * @param callback - Predicate (element, index, heap) → boolean to keep element.
730
- * @param [thisArg] - Value for `this` inside the callback.
731
- * @returns A new heap with the kept elements.
732
- */
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
+ */
733
1049
  filter(callback, thisArg) {
734
1050
  const out = this._createInstance();
735
1051
  let i = 0;
@@ -743,18 +1059,31 @@ var _Heap = class _Heap extends IterableElementBase {
743
1059
  return out;
744
1060
  }
745
1061
  /**
746
- * Map elements into a new heap of possibly different element type.
747
- * @remarks Time O(N log N), Space O(N)
748
- * @template EM
749
- * @template RM
750
- * @param callback - Mapping function (element, index, heap) → newElement.
751
- * @param options - Options for the output heap, including comparator for EM.
752
- * @param [thisArg] - Value for `this` inside the callback.
753
- * @returns A new heap with mapped elements.
754
- */
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
+ */
755
1084
  map(callback, options, thisArg) {
756
1085
  const { comparator, toElementFn, ...rest } = options != null ? options : {};
757
- if (!comparator) throw new TypeError("Heap.map requires options.comparator for EM");
1086
+ if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
758
1087
  const out = this._createLike([], { ...rest, comparator, toElementFn });
759
1088
  let i = 0;
760
1089
  for (const x of this) {
@@ -1103,18 +1432,52 @@ var _Queue = class _Queue extends LinearBase {
1103
1432
  this._autoCompactRatio = value;
1104
1433
  }
1105
1434
  /**
1106
- * Get the number of elements currently in the queue.
1107
- * @remarks Time O(1), Space O(1)
1108
- * @returns Current length.
1109
- */
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
+ */
1110
1457
  get length() {
1111
1458
  return this.elements.length - this._offset;
1112
1459
  }
1113
1460
  /**
1114
- * Get the first element (front) without removing it.
1115
- * @remarks Time O(1), Space O(1)
1116
- * @returns Front element or undefined.
1117
- */
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
+ */
1118
1481
  get first() {
1119
1482
  return this.length > 0 ? this.elements[this._offset] : void 0;
1120
1483
  }
@@ -1137,19 +1500,69 @@ var _Queue = class _Queue extends LinearBase {
1137
1500
  return new _Queue(elements);
1138
1501
  }
1139
1502
  /**
1140
- * Check whether the queue is empty.
1141
- * @remarks Time O(1), Space O(1)
1142
- * @returns True if length is 0.
1143
- */
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
+ */
1144
1536
  isEmpty() {
1145
1537
  return this.length === 0;
1146
1538
  }
1147
1539
  /**
1148
- * Enqueue one element at the back.
1149
- * @remarks Time O(1), Space O(1)
1150
- * @param element - Element to enqueue.
1151
- * @returns True on success.
1152
- */
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
+ */
1153
1566
  push(element) {
1154
1567
  this.elements.push(element);
1155
1568
  if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
@@ -1170,10 +1583,35 @@ var _Queue = class _Queue extends LinearBase {
1170
1583
  return ans;
1171
1584
  }
1172
1585
  /**
1173
- * Dequeue one element from the front (amortized via offset).
1174
- * @remarks Time O(1) amortized, Space O(1)
1175
- * @returns Removed element or undefined.
1176
- */
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
+ */
1177
1615
  shift() {
1178
1616
  if (this.length === 0) return void 0;
1179
1617
  const first = this.first;
@@ -1182,11 +1620,24 @@ var _Queue = class _Queue extends LinearBase {
1182
1620
  return first;
1183
1621
  }
1184
1622
  /**
1185
- * Delete the first occurrence of a specific element.
1186
- * @remarks Time O(N), Space O(1)
1187
- * @param element - Element to remove (strict equality via Object.is).
1188
- * @returns True if an element was removed.
1189
- */
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
+ */
1190
1641
  delete(element) {
1191
1642
  for (let i = this._offset; i < this.elements.length; i++) {
1192
1643
  if (Object.is(this.elements[i], element)) {
@@ -1197,11 +1648,24 @@ var _Queue = class _Queue extends LinearBase {
1197
1648
  return false;
1198
1649
  }
1199
1650
  /**
1200
- * Get the element at a given logical index.
1201
- * @remarks Time O(1), Space O(1)
1202
- * @param index - Zero-based index from the front.
1203
- * @returns Element or undefined.
1204
- */
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
+ */
1205
1669
  at(index) {
1206
1670
  if (index < 0 || index >= this.length) return void 0;
1207
1671
  return this._elements[this._offset + index];
@@ -1253,19 +1717,48 @@ var _Queue = class _Queue extends LinearBase {
1253
1717
  return this;
1254
1718
  }
1255
1719
  /**
1256
- * Remove all elements and reset offset.
1257
- * @remarks Time O(1), Space O(1)
1258
- * @returns void
1259
- */
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
+ */
1260
1738
  clear() {
1261
1739
  this._elements = [];
1262
1740
  this._offset = 0;
1263
1741
  }
1264
1742
  /**
1265
- * Compact storage by discarding consumed head elements.
1266
- * @remarks Time O(N), Space O(N)
1267
- * @returns True when compaction performed.
1268
- */
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
+ */
1269
1762
  compact() {
1270
1763
  this._elements = this.elements.slice(this._offset);
1271
1764
  this._offset = 0;
@@ -1291,10 +1784,26 @@ var _Queue = class _Queue extends LinearBase {
1291
1784
  return removed;
1292
1785
  }
1293
1786
  /**
1294
- * Deep clone this queue and its parameters.
1295
- * @remarks Time O(N), Space O(N)
1296
- * @returns A new queue with the same content and options.
1297
- */
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
+ */
1298
1807
  clone() {
1299
1808
  const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
1300
1809
  out._setAutoCompactRatio(this._autoCompactRatio);
@@ -1302,12 +1811,26 @@ var _Queue = class _Queue extends LinearBase {
1302
1811
  return out;
1303
1812
  }
1304
1813
  /**
1305
- * Filter elements into a new queue of the same class.
1306
- * @remarks Time O(N), Space O(N)
1307
- * @param predicate - Predicate (element, index, queue) → boolean to keep element.
1308
- * @param [thisArg] - Value for `this` inside the predicate.
1309
- * @returns A new queue with kept elements.
1310
- */
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
+ */
1311
1834
  filter(predicate, thisArg) {
1312
1835
  const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
1313
1836
  out._setAutoCompactRatio(this._autoCompactRatio);
@@ -1319,15 +1842,28 @@ var _Queue = class _Queue extends LinearBase {
1319
1842
  return out;
1320
1843
  }
1321
1844
  /**
1322
- * Map each element to a new element in a possibly different-typed queue.
1323
- * @remarks Time O(N), Space O(N)
1324
- * @template EM
1325
- * @template RM
1326
- * @param callback - Mapping function (element, index, queue) → newElement.
1327
- * @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
1328
- * @param [thisArg] - Value for `this` inside the callback.
1329
- * @returns A new Queue with mapped elements.
1330
- */
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
+ */
1331
1867
  map(callback, options, thisArg) {
1332
1868
  var _a, _b;
1333
1869
  const out = new this.constructor([], {
@@ -1556,7 +2092,7 @@ var _AbstractGraph = class _AbstractGraph extends IterableEntryBase {
1556
2092
  const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
1557
2093
  return this._addEdge(newEdge);
1558
2094
  } else {
1559
- throw new Error("dest must be a Vertex or vertex key while srcOrEdge is an Edge");
2095
+ throw new TypeError(ERR.invalidArgument("dest must be a Vertex or vertex key when srcOrEdge is an Edge.", "Graph"));
1560
2096
  }
1561
2097
  }
1562
2098
  }
@@ -2240,6 +2776,94 @@ var _AbstractGraph = class _AbstractGraph extends IterableEntryBase {
2240
2776
  _getVertexKey(vertexOrKey) {
2241
2777
  return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
2242
2778
  }
2779
+ /**
2780
+ * The edge connector string used in visual output.
2781
+ * Override in subclasses (e.g., '--' for undirected, '->' for directed).
2782
+ */
2783
+ get _edgeConnector() {
2784
+ return "--";
2785
+ }
2786
+ /**
2787
+ * Generate a text-based visual representation of the graph.
2788
+ *
2789
+ * **Adjacency list format:**
2790
+ * ```
2791
+ * Graph (5 vertices, 6 edges):
2792
+ * A -> B (1), C (2)
2793
+ * B -> D (3)
2794
+ * C -> (no outgoing edges)
2795
+ * D -> A (1)
2796
+ * E (isolated)
2797
+ * ```
2798
+ *
2799
+ * @param options - Optional display settings.
2800
+ * @param options.showWeight - Whether to show edge weights (default: true).
2801
+ * @returns The visual string.
2802
+ */
2803
+ toVisual(options) {
2804
+ var _a;
2805
+ const showWeight = (_a = options == null ? void 0 : options.showWeight) != null ? _a : true;
2806
+ const vertices = [...this._vertexMap.values()];
2807
+ const vertexCount = vertices.length;
2808
+ const edgeCount = this.edgeSet().length;
2809
+ const lines = [`Graph (${vertexCount} vertices, ${edgeCount} edges):`];
2810
+ for (const vertex of vertices) {
2811
+ const neighbors = this.getNeighbors(vertex);
2812
+ if (neighbors.length === 0) {
2813
+ lines.push(` ${vertex.key} (isolated)`);
2814
+ } else {
2815
+ const edgeStrs = neighbors.map((neighbor) => {
2816
+ const edge = this.getEdge(vertex, neighbor);
2817
+ if (edge && showWeight && edge.weight !== void 0 && edge.weight !== 1) {
2818
+ return `${neighbor.key} (${edge.weight})`;
2819
+ }
2820
+ return `${neighbor.key}`;
2821
+ });
2822
+ lines.push(` ${vertex.key} ${this._edgeConnector} ${edgeStrs.join(", ")}`);
2823
+ }
2824
+ }
2825
+ return lines.join("\n");
2826
+ }
2827
+ /**
2828
+ * Generate DOT language representation for Graphviz.
2829
+ *
2830
+ * @param options - Optional display settings.
2831
+ * @param options.name - Graph name (default: 'G').
2832
+ * @param options.showWeight - Whether to label edges with weight (default: true).
2833
+ * @returns DOT format string.
2834
+ */
2835
+ toDot(options) {
2836
+ var _a, _b;
2837
+ const name = (_a = options == null ? void 0 : options.name) != null ? _a : "G";
2838
+ const showWeight = (_b = options == null ? void 0 : options.showWeight) != null ? _b : true;
2839
+ const isDirected = this._edgeConnector === "->";
2840
+ const graphType = isDirected ? "digraph" : "graph";
2841
+ const edgeOp = isDirected ? "->" : "--";
2842
+ const lines = [`${graphType} ${name} {`];
2843
+ for (const vertex of this._vertexMap.values()) {
2844
+ lines.push(` "${vertex.key}";`);
2845
+ }
2846
+ const visited = /* @__PURE__ */ new Set();
2847
+ for (const vertex of this._vertexMap.values()) {
2848
+ for (const neighbor of this.getNeighbors(vertex)) {
2849
+ const edgeId = isDirected ? `${vertex.key}->${neighbor.key}` : [vertex.key, neighbor.key].sort().join("--");
2850
+ if (visited.has(edgeId)) continue;
2851
+ visited.add(edgeId);
2852
+ const edge = this.getEdge(vertex, neighbor);
2853
+ const label = edge && showWeight && edge.weight !== void 0 && edge.weight !== 1 ? ` [label="${edge.weight}"]` : "";
2854
+ lines.push(` "${vertex.key}" ${edgeOp} "${neighbor.key}"${label};`);
2855
+ }
2856
+ }
2857
+ lines.push("}");
2858
+ return lines.join("\n");
2859
+ }
2860
+ /**
2861
+ * Print the graph to console.
2862
+ * @param options - Display settings passed to `toVisual`.
2863
+ */
2864
+ print(options) {
2865
+ console.log(this.toVisual(options));
2866
+ }
2243
2867
  };
2244
2868
  __name(_AbstractGraph, "AbstractGraph");
2245
2869
  var AbstractGraph = _AbstractGraph;
@@ -2274,6 +2898,9 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2274
2898
  __publicField(this, "_outEdgeMap", /* @__PURE__ */ new Map());
2275
2899
  __publicField(this, "_inEdgeMap", /* @__PURE__ */ new Map());
2276
2900
  }
2901
+ get _edgeConnector() {
2902
+ return "->";
2903
+ }
2277
2904
  get outEdgeMap() {
2278
2905
  return this._outEdgeMap;
2279
2906
  }
@@ -2336,12 +2963,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2336
2963
  return new DirectedEdge(src, dest, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
2337
2964
  }
2338
2965
  /**
2339
- * Get the unique edge from `src` to `dest`, if present.
2340
- * @param srcOrKey - Source vertex or key.
2341
- * @param destOrKey - Destination vertex or key.
2342
- * @returns Edge instance or `undefined`.
2343
- * @remarks Time O(1) avg, Space O(1)
2344
- */
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
+ */
2345
2988
  getEdge(srcOrKey, destOrKey) {
2346
2989
  let edgeMap = [];
2347
2990
  if (srcOrKey !== void 0 && destOrKey !== void 0) {
@@ -2381,12 +3024,48 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2381
3024
  return removed;
2382
3025
  }
2383
3026
  /**
2384
- * Delete an edge by instance or by `(srcKey, destKey)`.
2385
- * @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
2386
- * @param destVertexKey - Optional destination vertex/key when deleting by pair.
2387
- * @returns Removed edge or `undefined`.
2388
- * @remarks Time O(1) avg, Space O(1)
2389
- */
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
+ */
2390
3069
  deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
2391
3070
  let removed = void 0;
2392
3071
  let src, dest;
@@ -2413,6 +3092,26 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2413
3092
  }
2414
3093
  return removed;
2415
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
+ */
2416
3115
  deleteVertex(vertexOrKey) {
2417
3116
  let vertexKey;
2418
3117
  let vertex;
@@ -2444,11 +3143,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2444
3143
  return removed;
2445
3144
  }
2446
3145
  /**
2447
- * Incoming edges of a vertex.
2448
- * @param vertexOrKey - Vertex or key.
2449
- * @returns Array of incoming edges.
2450
- * @remarks Time O(deg_in), Space O(deg_in)
2451
- */
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
+ */
2452
3168
  incomingEdgesOf(vertexOrKey) {
2453
3169
  const target = this._getVertex(vertexOrKey);
2454
3170
  if (target) {
@@ -2457,11 +3173,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2457
3173
  return [];
2458
3174
  }
2459
3175
  /**
2460
- * Outgoing edges of a vertex.
2461
- * @param vertexOrKey - Vertex or key.
2462
- * @returns Array of outgoing edges.
2463
- * @remarks Time O(deg_out), Space O(deg_out)
2464
- */
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
+ */
2465
3198
  outgoingEdgesOf(vertexOrKey) {
2466
3199
  const target = this._getVertex(vertexOrKey);
2467
3200
  if (target) {
@@ -2520,11 +3253,44 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2520
3253
  return destinations;
2521
3254
  }
2522
3255
  /**
2523
- * Topological sort if DAG; returns `undefined` if a cycle exists.
2524
- * @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
2525
- * @returns Array of keys/vertices, or `undefined` when cycle is found.
2526
- * @remarks Time O(V + E), Space O(V)
2527
- */
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
+ */
2528
3294
  topologicalSort(propertyName) {
2529
3295
  propertyName = propertyName != null ? propertyName : "key";
2530
3296
  const statusMap = /* @__PURE__ */ new Map();
@@ -2556,6 +3322,24 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2556
3322
  if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
2557
3323
  return sorted.reverse();
2558
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
+ */
2559
3343
  edgeSet() {
2560
3344
  let edgeMap = [];
2561
3345
  this._outEdgeMap.forEach((outEdges) => {
@@ -2563,6 +3347,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2563
3347
  });
2564
3348
  return edgeMap;
2565
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
+ */
2566
3372
  getNeighbors(vertexOrKey) {
2567
3373
  const neighbors = [];
2568
3374
  const vertex = this._getVertex(vertexOrKey);
@@ -2620,10 +3426,31 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2620
3426
  return super.clone();
2621
3427
  }
2622
3428
  /**
2623
- * Tarjan's algorithm for strongly connected components.
2624
- * @returns `{ dfnMap, lowMap, SCCs }`.
2625
- * @remarks Time O(V + E), Space O(V + E)
2626
- */
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
+ */
2627
3454
  tarjan() {
2628
3455
  const dfnMap = /* @__PURE__ */ new Map();
2629
3456
  const lowMap = /* @__PURE__ */ new Map();
@@ -2681,10 +3508,29 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2681
3508
  return this.tarjan().lowMap;
2682
3509
  }
2683
3510
  /**
2684
- * Strongly connected components computed by `tarjan()`.
2685
- * @returns Map from SCC id to vertices.
2686
- * @remarks Time O(#SCC + V), Space O(V)
2687
- */
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
+ */
2688
3534
  getSCCs() {
2689
3535
  return this.tarjan().SCCs;
2690
3536
  }
@@ -2806,12 +3652,27 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2806
3652
  return new UndirectedEdge(v1, v2, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
2807
3653
  }
2808
3654
  /**
2809
- * Get an undirected edge between two vertices, if present.
2810
- * @param v1 - One vertex or key.
2811
- * @param v2 - The other vertex or key.
2812
- * @returns Edge instance or `undefined`.
2813
- * @remarks Time O(1) avg, Space O(1)
2814
- */
3655
+ * Get an undirected edge between two vertices, if present.
3656
+ * @param v1 - One vertex or key.
3657
+ * @param v2 - The other vertex or key.
3658
+ * @returns Edge instance or `undefined`.
3659
+ * @remarks Time O(1) avg, Space O(1)
3660
+
3661
+
3662
+
3663
+
3664
+
3665
+
3666
+
3667
+
3668
+ * @example
3669
+ * // Get edge between vertices
3670
+ * const g = new UndirectedGraph();
3671
+ * g.addVertex('A');
3672
+ * g.addVertex('B');
3673
+ * g.addEdge('A', 'B', 7);
3674
+ * console.log(g.getEdge('A', 'B')?.weight); // 7;
3675
+ */
2815
3676
  getEdge(v1, v2) {
2816
3677
  var _a;
2817
3678
  let edgeMap = [];
@@ -2849,12 +3710,50 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2849
3710
  return removed;
2850
3711
  }
2851
3712
  /**
2852
- * Delete an edge by instance or by a pair of keys.
2853
- * @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
2854
- * @param otherSideVertexKey - Required second endpoint when deleting by pair.
2855
- * @returns Removed edge or `undefined`.
2856
- * @remarks Time O(1) avg, Space O(1)
2857
- */
3713
+ * Delete an edge by instance or by a pair of keys.
3714
+ * @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
3715
+ * @param otherSideVertexKey - Required second endpoint when deleting by pair.
3716
+ * @returns Removed edge or `undefined`.
3717
+ * @remarks Time O(1) avg, Space O(1)
3718
+
3719
+
3720
+
3721
+
3722
+
3723
+
3724
+
3725
+
3726
+
3727
+
3728
+
3729
+ * @example
3730
+ * // UndirectedGraph deleteEdge and vertex operations
3731
+ * const graph = new UndirectedGraph<string>();
3732
+ *
3733
+ * // Build a simple undirected graph
3734
+ * graph.addVertex('X');
3735
+ * graph.addVertex('Y');
3736
+ * graph.addVertex('Z');
3737
+ * graph.addEdge('X', 'Y', 1);
3738
+ * graph.addEdge('Y', 'Z', 2);
3739
+ * graph.addEdge('X', 'Z', 3);
3740
+ *
3741
+ * // Delete an edge
3742
+ * graph.deleteEdge('X', 'Y');
3743
+ * console.log(graph.hasEdge('X', 'Y')); // false;
3744
+ *
3745
+ * // Bidirectional deletion confirmed
3746
+ * console.log(graph.hasEdge('Y', 'X')); // false;
3747
+ *
3748
+ * // Other edges should remain
3749
+ * console.log(graph.hasEdge('Y', 'Z')); // true;
3750
+ * console.log(graph.hasEdge('Z', 'Y')); // true;
3751
+ *
3752
+ * // Delete a vertex
3753
+ * graph.deleteVertex('Y');
3754
+ * console.log(graph.hasVertex('Y')); // false;
3755
+ * console.log(graph.size); // 2;
3756
+ */
2858
3757
  deleteEdge(edgeOrOneSideVertexKey, otherSideVertexKey) {
2859
3758
  let oneSide, otherSide;
2860
3759
  if (this.isVertexKey(edgeOrOneSideVertexKey)) {
@@ -2875,11 +3774,27 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2875
3774
  }
2876
3775
  }
2877
3776
  /**
2878
- * Delete a vertex and remove it from all neighbor lists.
2879
- * @param vertexOrKey - Vertex or key.
2880
- * @returns `true` if removed; otherwise `false`.
2881
- * @remarks Time O(deg), Space O(1)
2882
- */
3777
+ * Delete a vertex and remove it from all neighbor lists.
3778
+ * @param vertexOrKey - Vertex or key.
3779
+ * @returns `true` if removed; otherwise `false`.
3780
+ * @remarks Time O(deg), Space O(1)
3781
+
3782
+
3783
+
3784
+
3785
+
3786
+
3787
+
3788
+
3789
+ * @example
3790
+ * // Remove vertex and edges
3791
+ * const g = new UndirectedGraph();
3792
+ * g.addVertex('A');
3793
+ * g.addVertex('B');
3794
+ * g.addEdge('A', 'B');
3795
+ * g.deleteVertex('A');
3796
+ * console.log(g.hasVertex('A')); // false;
3797
+ */
2883
3798
  deleteVertex(vertexOrKey) {
2884
3799
  let vertexKey;
2885
3800
  let vertex;
@@ -2935,10 +3850,25 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2935
3850
  }
2936
3851
  }
2937
3852
  /**
2938
- * Unique set of undirected edges across endpoints.
2939
- * @returns Array of edges.
2940
- * @remarks Time O(E), Space O(E)
2941
- */
3853
+ * Unique set of undirected edges across endpoints.
3854
+ * @returns Array of edges.
3855
+ * @remarks Time O(E), Space O(E)
3856
+
3857
+
3858
+
3859
+
3860
+
3861
+
3862
+
3863
+
3864
+ * @example
3865
+ * // Get all edges
3866
+ * const g = new UndirectedGraph();
3867
+ * g.addVertex('A');
3868
+ * g.addVertex('B');
3869
+ * g.addEdge('A', 'B');
3870
+ * console.log(g.edgeSet().length); // 1;
3871
+ */
2942
3872
  edgeSet() {
2943
3873
  const edgeSet = /* @__PURE__ */ new Set();
2944
3874
  this._edgeMap.forEach((edgeMap) => {
@@ -2948,6 +3878,52 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2948
3878
  });
2949
3879
  return [...edgeSet];
2950
3880
  }
3881
+ /**
3882
+ * UndirectedGraph connectivity and neighbors
3883
+
3884
+
3885
+
3886
+
3887
+
3888
+
3889
+
3890
+
3891
+
3892
+
3893
+
3894
+ * @example
3895
+ * // UndirectedGraph connectivity and neighbors
3896
+ * const graph = new UndirectedGraph<string>();
3897
+ *
3898
+ * // Build a friendship network
3899
+ * const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
3900
+ * for (const person of people) {
3901
+ * graph.addVertex(person);
3902
+ * }
3903
+ *
3904
+ * // Add friendships (undirected edges)
3905
+ * graph.addEdge('Alice', 'Bob', 1);
3906
+ * graph.addEdge('Alice', 'Charlie', 1);
3907
+ * graph.addEdge('Bob', 'Diana', 1);
3908
+ * graph.addEdge('Charlie', 'Eve', 1);
3909
+ * graph.addEdge('Diana', 'Eve', 1);
3910
+ *
3911
+ * // Get friends of each person
3912
+ * const aliceFriends = graph.getNeighbors('Alice');
3913
+ * console.log(aliceFriends[0].key); // 'Bob';
3914
+ * console.log(aliceFriends[1].key); // 'Charlie';
3915
+ * console.log(aliceFriends.length); // 2;
3916
+ *
3917
+ * const dianaFriends = graph.getNeighbors('Diana');
3918
+ * console.log(dianaFriends[0].key); // 'Bob';
3919
+ * console.log(dianaFriends[1].key); // 'Eve';
3920
+ * console.log(dianaFriends.length); // 2;
3921
+ *
3922
+ * // Verify bidirectional friendship
3923
+ * const bobFriends = graph.getNeighbors('Bob');
3924
+ * console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
3925
+ * console.log(bobFriends[1].key); // 'Diana';
3926
+ */
2951
3927
  getNeighbors(vertexOrKey) {
2952
3928
  const neighbors = [];
2953
3929
  const vertex = this._getVertex(vertexOrKey);
@@ -3004,10 +3980,28 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
3004
3980
  return super.clone();
3005
3981
  }
3006
3982
  /**
3007
- * Tarjan-based bridge and articulation point detection.
3008
- * @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
3009
- * @remarks Time O(V + E), Space O(V + E)
3010
- */
3983
+ * Tarjan-based bridge and articulation point detection.
3984
+ * @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
3985
+ * @remarks Time O(V + E), Space O(V + E)
3986
+
3987
+
3988
+
3989
+
3990
+
3991
+
3992
+
3993
+
3994
+ * @example
3995
+ * // Find articulation points and bridges
3996
+ * const g = new UndirectedGraph();
3997
+ * g.addVertex('A');
3998
+ * g.addVertex('B');
3999
+ * g.addVertex('C');
4000
+ * g.addEdge('A', 'B');
4001
+ * g.addEdge('B', 'C');
4002
+ * const result = g.tarjan();
4003
+ * console.log(result); // defined;
4004
+ */
3011
4005
  tarjan() {
3012
4006
  const dfnMap = /* @__PURE__ */ new Map();
3013
4007
  const lowMap = /* @__PURE__ */ new Map();
@@ -3055,18 +4049,152 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
3055
4049
  };
3056
4050
  }
3057
4051
  /**
3058
- * Get bridges discovered by `tarjan()`.
3059
- * @returns Array of edges that are bridges.
3060
- * @remarks Time O(B), Space O(1)
4052
+ * Find biconnected components using edge-stack Tarjan variant.
4053
+ * A biconnected component is a maximal biconnected subgraph.
4054
+ * @returns Array of edge arrays, each representing a biconnected component.
4055
+ * @remarks Time O(V + E), Space O(V + E)
3061
4056
  */
4057
+ getBiconnectedComponents() {
4058
+ const dfn = /* @__PURE__ */ new Map();
4059
+ const low = /* @__PURE__ */ new Map();
4060
+ const edgeStack = [];
4061
+ const components = [];
4062
+ let time = 0;
4063
+ const dfs = /* @__PURE__ */ __name((vertex, parent) => {
4064
+ dfn.set(vertex, time);
4065
+ low.set(vertex, time);
4066
+ time++;
4067
+ const neighbors = this.getNeighbors(vertex);
4068
+ let childCount = 0;
4069
+ for (const neighbor of neighbors) {
4070
+ const edge = this.getEdge(vertex, neighbor);
4071
+ if (!edge) continue;
4072
+ if (!dfn.has(neighbor)) {
4073
+ childCount++;
4074
+ edgeStack.push(edge);
4075
+ dfs(neighbor, vertex);
4076
+ low.set(vertex, Math.min(low.get(vertex), low.get(neighbor)));
4077
+ if (parent === void 0 && childCount > 1 || parent !== void 0 && low.get(neighbor) >= dfn.get(vertex)) {
4078
+ const component = [];
4079
+ let e;
4080
+ do {
4081
+ e = edgeStack.pop();
4082
+ if (e) component.push(e);
4083
+ } while (e && e !== edge);
4084
+ if (component.length > 0) components.push(component);
4085
+ }
4086
+ } else if (neighbor !== parent && dfn.get(neighbor) < dfn.get(vertex)) {
4087
+ edgeStack.push(edge);
4088
+ low.set(vertex, Math.min(low.get(vertex), dfn.get(neighbor)));
4089
+ }
4090
+ }
4091
+ }, "dfs");
4092
+ for (const vertex of this.vertexMap.values()) {
4093
+ if (!dfn.has(vertex)) {
4094
+ dfs(vertex, void 0);
4095
+ if (edgeStack.length > 0) {
4096
+ components.push([...edgeStack]);
4097
+ edgeStack.length = 0;
4098
+ }
4099
+ }
4100
+ }
4101
+ return components;
4102
+ }
4103
+ /**
4104
+ * Detect whether the graph contains a cycle.
4105
+ * Uses DFS with parent tracking.
4106
+ * @returns `true` if a cycle exists, `false` otherwise.
4107
+ * @remarks Time O(V + E), Space O(V)
4108
+
4109
+
4110
+
4111
+
4112
+
4113
+
4114
+
4115
+
4116
+ * @example
4117
+ * // Detect cycle
4118
+ * const g = new UndirectedGraph();
4119
+ * g.addVertex('A');
4120
+ * g.addVertex('B');
4121
+ * g.addVertex('C');
4122
+ * g.addEdge('A', 'B');
4123
+ * g.addEdge('B', 'C');
4124
+ * console.log(g.hasCycle()); // false;
4125
+ * g.addEdge('C', 'A');
4126
+ * console.log(g.hasCycle()); // true;
4127
+ */
4128
+ hasCycle() {
4129
+ const visited = /* @__PURE__ */ new Set();
4130
+ const dfs = /* @__PURE__ */ __name((vertex, parent) => {
4131
+ visited.add(vertex);
4132
+ for (const neighbor of this.getNeighbors(vertex)) {
4133
+ if (!visited.has(neighbor)) {
4134
+ if (dfs(neighbor, vertex)) return true;
4135
+ } else if (neighbor !== parent) {
4136
+ return true;
4137
+ }
4138
+ }
4139
+ return false;
4140
+ }, "dfs");
4141
+ for (const vertex of this.vertexMap.values()) {
4142
+ if (!visited.has(vertex)) {
4143
+ if (dfs(vertex, void 0)) return true;
4144
+ }
4145
+ }
4146
+ return false;
4147
+ }
4148
+ /**
4149
+ * Get bridges discovered by `tarjan()`.
4150
+ * @returns Array of edges that are bridges.
4151
+ * @remarks Time O(B), Space O(1)
4152
+
4153
+
4154
+
4155
+
4156
+
4157
+
4158
+
4159
+
4160
+ * @example
4161
+ * // Find bridge edges
4162
+ * const g = new UndirectedGraph();
4163
+ * g.addVertex('A');
4164
+ * g.addVertex('B');
4165
+ * g.addVertex('C');
4166
+ * g.addEdge('A', 'B');
4167
+ * g.addEdge('B', 'C');
4168
+ * const bridges = g.getBridges();
4169
+ * console.log(bridges.length); // 2;
4170
+ */
3062
4171
  getBridges() {
3063
4172
  return this.tarjan().bridges;
3064
4173
  }
3065
4174
  /**
3066
- * Get articulation points discovered by `tarjan()`.
3067
- * @returns Array of cut vertices.
3068
- * @remarks Time O(C), Space O(1)
3069
- */
4175
+ * Get articulation points discovered by `tarjan()`.
4176
+ * @returns Array of cut vertices.
4177
+ * @remarks Time O(C), Space O(1)
4178
+
4179
+
4180
+
4181
+
4182
+
4183
+
4184
+
4185
+
4186
+ * @example
4187
+ * // Find articulation points
4188
+ * const g = new UndirectedGraph();
4189
+ * g.addVertex('A');
4190
+ * g.addVertex('B');
4191
+ * g.addVertex('C');
4192
+ * g.addEdge('A', 'B');
4193
+ * g.addEdge('B', 'C');
4194
+ * const cuts = g.getCutVertices();
4195
+ * console.log(cuts.length); // 1;
4196
+ * console.log(cuts[0].key); // 'B';
4197
+ */
3070
4198
  getCutVertices() {
3071
4199
  return this.tarjan().cutVertices;
3072
4200
  }
@@ -3205,29 +4333,6 @@ var _MapGraph = class _MapGraph extends DirectedGraph {
3205
4333
  };
3206
4334
  __name(_MapGraph, "MapGraph");
3207
4335
  var MapGraph = _MapGraph;
3208
-
3209
- // src/common/index.ts
3210
- var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
3211
- DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
3212
- DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
3213
- return DFSOperation2;
3214
- })(DFSOperation || {});
3215
- var _Range = class _Range {
3216
- constructor(low, high, includeLow = true, includeHigh = true) {
3217
- this.low = low;
3218
- this.high = high;
3219
- this.includeLow = includeLow;
3220
- this.includeHigh = includeHigh;
3221
- }
3222
- // Determine whether a key is within the range
3223
- isInRange(key, comparator) {
3224
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
3225
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
3226
- return lowCheck && highCheck;
3227
- }
3228
- };
3229
- __name(_Range, "Range");
3230
- var Range = _Range;
3231
4336
  /**
3232
4337
  * data-structure-typed
3233
4338
  *
@@ -3243,6 +4348,7 @@ exports.DFSOperation = DFSOperation;
3243
4348
  exports.DirectedEdge = DirectedEdge;
3244
4349
  exports.DirectedGraph = DirectedGraph;
3245
4350
  exports.DirectedVertex = DirectedVertex;
4351
+ exports.ERR = ERR;
3246
4352
  exports.MapEdge = MapEdge;
3247
4353
  exports.MapGraph = MapGraph;
3248
4354
  exports.MapVertex = MapVertex;