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
@@ -24,6 +24,54 @@ var arrayRemove = /* @__PURE__ */ __name(function(array, predicate) {
24
24
  return result;
25
25
  }, "arrayRemove");
26
26
 
27
+ // src/common/error.ts
28
+ var ERR = {
29
+ // Range / index
30
+ indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
31
+ invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
32
+ // Type / argument
33
+ invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
34
+ comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
35
+ invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
36
+ notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
37
+ invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
38
+ invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
39
+ invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
40
+ reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
41
+ callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
42
+ // State / operation
43
+ invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
44
+ // Matrix
45
+ matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
46
+ matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
47
+ matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
48
+ matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
49
+ matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
50
+ };
51
+
52
+ // src/common/index.ts
53
+ var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
54
+ DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
55
+ DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
56
+ return DFSOperation2;
57
+ })(DFSOperation || {});
58
+ var _Range = class _Range {
59
+ constructor(low, high, includeLow = true, includeHigh = true) {
60
+ this.low = low;
61
+ this.high = high;
62
+ this.includeLow = includeLow;
63
+ this.includeHigh = includeHigh;
64
+ }
65
+ // Determine whether a key is within the range
66
+ isInRange(key, comparator) {
67
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
68
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
69
+ return lowCheck && highCheck;
70
+ }
71
+ };
72
+ __name(_Range, "Range");
73
+ var Range = _Range;
74
+
27
75
  // src/data-structures/base/iterable-entry-base.ts
28
76
  var _IterableEntryBase = class _IterableEntryBase {
29
77
  /**
@@ -442,7 +490,7 @@ var _Heap = class _Heap extends IterableElementBase {
442
490
  __publicField(this, "_elements", []);
443
491
  __publicField(this, "_DEFAULT_COMPARATOR", /* @__PURE__ */ __name((a, b) => {
444
492
  if (typeof a === "object" || typeof b === "object") {
445
- throw TypeError("When comparing object types, define a custom comparator in options.");
493
+ throw new TypeError(ERR.comparatorRequired("Heap"));
446
494
  }
447
495
  if (a > b) return 1;
448
496
  if (a < b) return -1;
@@ -464,10 +512,30 @@ var _Heap = class _Heap extends IterableElementBase {
464
512
  return this._elements;
465
513
  }
466
514
  /**
467
- * Get the number of elements.
468
- * @remarks Time O(1), Space O(1)
469
- * @returns Heap size.
470
- */
515
+ * Get the number of elements.
516
+ * @remarks Time O(1), Space O(1)
517
+ * @returns Heap size.
518
+
519
+
520
+
521
+
522
+
523
+
524
+
525
+
526
+
527
+
528
+
529
+ * @example
530
+ * // Track heap capacity
531
+ * const heap = new Heap<number>();
532
+ * console.log(heap.size); // 0;
533
+ * heap.add(10);
534
+ * heap.add(20);
535
+ * console.log(heap.size); // 2;
536
+ * heap.poll();
537
+ * console.log(heap.size); // 1;
538
+ */
471
539
  get size() {
472
540
  return this.elements.length;
473
541
  }
@@ -506,21 +574,61 @@ var _Heap = class _Heap extends IterableElementBase {
506
574
  return new _Heap(elements, options);
507
575
  }
508
576
  /**
509
- * Insert an element.
510
- * @remarks Time O(1) amortized, Space O(1)
511
- * @param element - Element to insert.
512
- * @returns True.
513
- */
577
+ * Insert an element.
578
+ * @remarks Time O(1) amortized, Space O(1)
579
+ * @param element - Element to insert.
580
+ * @returns True.
581
+
582
+
583
+
584
+
585
+
586
+
587
+
588
+
589
+
590
+
591
+
592
+ * @example
593
+ * // basic Heap creation and add operation
594
+ * // Create a min heap (default)
595
+ * const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
596
+ *
597
+ * // Verify size
598
+ * console.log(minHeap.size); // 6;
599
+ *
600
+ * // Add new element
601
+ * minHeap.add(4);
602
+ * console.log(minHeap.size); // 7;
603
+ *
604
+ * // Min heap property: smallest element at root
605
+ * const min = minHeap.peek();
606
+ * console.log(min); // 1;
607
+ */
514
608
  add(element) {
515
609
  this._elements.push(element);
516
610
  return this._bubbleUp(this.elements.length - 1);
517
611
  }
518
612
  /**
519
- * Insert many elements from an iterable.
520
- * @remarks Time O(N log N), Space O(1)
521
- * @param elements - Iterable of elements or raw values.
522
- * @returns Array of per-element success flags.
523
- */
613
+ * Insert many elements from an iterable.
614
+ * @remarks Time O(N log N), Space O(1)
615
+ * @param elements - Iterable of elements or raw values.
616
+ * @returns Array of per-element success flags.
617
+
618
+
619
+
620
+
621
+
622
+
623
+
624
+
625
+ * @example
626
+ * // Add multiple elements
627
+ * const heap = new Heap<number>([], { comparator: (a, b) => a - b });
628
+ * heap.addMany([5, 3, 7, 1]);
629
+ * console.log(heap.peek()); // 1;
630
+ * console.log(heap.size); // 4;
631
+ */
524
632
  addMany(elements) {
525
633
  const flags = [];
526
634
  for (const el of elements) {
@@ -535,10 +643,46 @@ var _Heap = class _Heap extends IterableElementBase {
535
643
  return flags;
536
644
  }
537
645
  /**
538
- * Remove and return the top element.
539
- * @remarks Time O(log N), Space O(1)
540
- * @returns Top element or undefined.
541
- */
646
+ * Remove and return the top element.
647
+ * @remarks Time O(log N), Space O(1)
648
+ * @returns Top element or undefined.
649
+
650
+
651
+
652
+
653
+
654
+
655
+
656
+
657
+
658
+
659
+
660
+ * @example
661
+ * // Heap with custom comparator (MaxHeap behavior)
662
+ * interface Task {
663
+ * id: number;
664
+ * priority: number;
665
+ * name: string;
666
+ * }
667
+ *
668
+ * // Custom comparator for max heap behavior (higher priority first)
669
+ * const tasks: Task[] = [
670
+ * { id: 1, priority: 5, name: 'Email' },
671
+ * { id: 2, priority: 3, name: 'Chat' },
672
+ * { id: 3, priority: 8, name: 'Alert' }
673
+ * ];
674
+ *
675
+ * const maxHeap = new Heap(tasks, {
676
+ * comparator: (a: Task, b: Task) => b.priority - a.priority
677
+ * });
678
+ *
679
+ * console.log(maxHeap.size); // 3;
680
+ *
681
+ * // Peek returns highest priority task
682
+ * const topTask = maxHeap.peek();
683
+ * console.log(topTask?.priority); // 8;
684
+ * console.log(topTask?.name); // 'Alert';
685
+ */
542
686
  poll() {
543
687
  if (this.elements.length === 0) return;
544
688
  const value = this.elements[0];
@@ -550,26 +694,125 @@ var _Heap = class _Heap extends IterableElementBase {
550
694
  return value;
551
695
  }
552
696
  /**
553
- * Get the current top element without removing it.
554
- * @remarks Time O(1), Space O(1)
555
- * @returns Top element or undefined.
556
- */
697
+ * Get the current top element without removing it.
698
+ * @remarks Time O(1), Space O(1)
699
+ * @returns Top element or undefined.
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+
708
+
709
+
710
+
711
+ * @example
712
+ * // Heap for event processing with priority
713
+ * interface Event {
714
+ * id: number;
715
+ * type: 'critical' | 'warning' | 'info';
716
+ * timestamp: number;
717
+ * message: string;
718
+ * }
719
+ *
720
+ * // Custom priority: critical > warning > info
721
+ * const priorityMap = { critical: 3, warning: 2, info: 1 };
722
+ *
723
+ * const eventHeap = new Heap<Event>([], {
724
+ * comparator: (a: Event, b: Event) => {
725
+ * const priorityA = priorityMap[a.type];
726
+ * const priorityB = priorityMap[b.type];
727
+ * return priorityB - priorityA; // Higher priority first
728
+ * }
729
+ * });
730
+ *
731
+ * // Add events in random order
732
+ * eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
733
+ * eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
734
+ * eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
735
+ * eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
736
+ * eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
737
+ *
738
+ * console.log(eventHeap.size); // 5;
739
+ *
740
+ * // Process events by priority (critical first)
741
+ * const processedOrder: Event[] = [];
742
+ * while (eventHeap.size > 0) {
743
+ * const event = eventHeap.poll();
744
+ * if (event) {
745
+ * processedOrder.push(event);
746
+ * }
747
+ * }
748
+ *
749
+ * // Verify critical events came first
750
+ * console.log(processedOrder[0].type); // 'critical';
751
+ * console.log(processedOrder[1].type); // 'critical';
752
+ * console.log(processedOrder[2].type); // 'warning';
753
+ * console.log(processedOrder[3].type); // 'info';
754
+ * console.log(processedOrder[4].type); // 'info';
755
+ *
756
+ * // Verify O(log n) operations
757
+ * const newHeap = new Heap<number>([5, 3, 7, 1]);
758
+ *
759
+ * // Add - O(log n)
760
+ * newHeap.add(2);
761
+ * console.log(newHeap.size); // 5;
762
+ *
763
+ * // Poll - O(log n)
764
+ * const removed = newHeap.poll();
765
+ * console.log(removed); // 1;
766
+ *
767
+ * // Peek - O(1)
768
+ * const top = newHeap.peek();
769
+ * console.log(top); // 2;
770
+ */
557
771
  peek() {
558
772
  return this.elements[0];
559
773
  }
560
774
  /**
561
- * Check whether the heap is empty.
562
- * @remarks Time O(1), Space O(1)
563
- * @returns True if size is 0.
564
- */
775
+ * Check whether the heap is empty.
776
+ * @remarks Time O(1), Space O(1)
777
+ * @returns True if size is 0.
778
+
779
+
780
+
781
+
782
+
783
+
784
+
785
+
786
+
787
+ * @example
788
+ * // Check if heap is empty
789
+ * const heap = new Heap<number>([], { comparator: (a, b) => a - b });
790
+ * console.log(heap.isEmpty()); // true;
791
+ * heap.add(1);
792
+ * console.log(heap.isEmpty()); // false;
793
+ */
565
794
  isEmpty() {
566
795
  return this.size === 0;
567
796
  }
568
797
  /**
569
- * Remove all elements.
570
- * @remarks Time O(1), Space O(1)
571
- * @returns void
572
- */
798
+ * Remove all elements.
799
+ * @remarks Time O(1), Space O(1)
800
+ * @returns void
801
+
802
+
803
+
804
+
805
+
806
+
807
+
808
+
809
+
810
+ * @example
811
+ * // Remove all elements
812
+ * const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
813
+ * heap.clear();
814
+ * console.log(heap.isEmpty()); // true;
815
+ */
573
816
  clear() {
574
817
  this._elements = [];
575
818
  }
@@ -584,21 +827,41 @@ var _Heap = class _Heap extends IterableElementBase {
584
827
  return this.fix();
585
828
  }
586
829
  /**
587
- * Check if an equal element exists in the heap.
588
- * @remarks Time O(N), Space O(1)
589
- * @param element - Element to search for.
590
- * @returns True if found.
591
- */
830
+ * Check if an equal element exists in the heap.
831
+ * @remarks Time O(N), Space O(1)
832
+ * @param element - Element to search for.
833
+ * @returns True if found.
834
+
835
+
836
+ * @example
837
+ * // Check element existence
838
+ * const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
839
+ * console.log(heap.has(1)); // true;
840
+ * console.log(heap.has(99)); // false;
841
+ */
592
842
  has(element) {
593
843
  for (const el of this.elements) if (this._equals(el, element)) return true;
594
844
  return false;
595
845
  }
596
846
  /**
597
- * Delete one occurrence of an element.
598
- * @remarks Time O(N), Space O(1)
599
- * @param element - Element to delete.
600
- * @returns True if an element was removed.
601
- */
847
+ * Delete one occurrence of an element.
848
+ * @remarks Time O(N), Space O(1)
849
+ * @param element - Element to delete.
850
+ * @returns True if an element was removed.
851
+
852
+
853
+
854
+
855
+
856
+
857
+
858
+
859
+ * @example
860
+ * // Remove specific element
861
+ * const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
862
+ * heap.delete(4);
863
+ * console.log(heap.toArray().includes(4)); // false;
864
+ */
602
865
  delete(element) {
603
866
  let index = -1;
604
867
  for (let i = 0; i < this.elements.length; i++) {
@@ -656,11 +919,18 @@ var _Heap = class _Heap extends IterableElementBase {
656
919
  return this;
657
920
  }
658
921
  /**
659
- * Traverse the binary heap as a complete binary tree and collect elements.
660
- * @remarks Time O(N), Space O(H)
661
- * @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
662
- * @returns Array of visited elements.
663
- */
922
+ * Traverse the binary heap as a complete binary tree and collect elements.
923
+ * @remarks Time O(N), Space O(H)
924
+ * @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
925
+ * @returns Array of visited elements.
926
+
927
+
928
+ * @example
929
+ * // Depth-first traversal
930
+ * const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
931
+ * const result = heap.dfs('IN');
932
+ * console.log(result.length); // 3;
933
+ */
664
934
  dfs(order = "PRE") {
665
935
  const result = [];
666
936
  const _dfs = /* @__PURE__ */ __name((index) => {
@@ -697,10 +967,26 @@ var _Heap = class _Heap extends IterableElementBase {
697
967
  return results;
698
968
  }
699
969
  /**
700
- * Return all elements in ascending order by repeatedly polling.
701
- * @remarks Time O(N log N), Space O(N)
702
- * @returns Sorted array of elements.
703
- */
970
+ * Return all elements in ascending order by repeatedly polling.
971
+ * @remarks Time O(N log N), Space O(N)
972
+ * @returns Sorted array of elements.
973
+
974
+
975
+
976
+
977
+
978
+
979
+
980
+
981
+
982
+
983
+
984
+ * @example
985
+ * // Sort elements using heap
986
+ * const heap = new Heap<number>([5, 1, 3, 2, 4]);
987
+ * const sorted = heap.sort();
988
+ * console.log(sorted); // [1, 2, 3, 4, 5];
989
+ */
704
990
  sort() {
705
991
  const visited = [];
706
992
  const cloned = this._createInstance();
@@ -712,22 +998,52 @@ var _Heap = class _Heap extends IterableElementBase {
712
998
  return visited;
713
999
  }
714
1000
  /**
715
- * Deep clone this heap.
716
- * @remarks Time O(N), Space O(N)
717
- * @returns A new heap with the same elements.
718
- */
1001
+ * Deep clone this heap.
1002
+ * @remarks Time O(N), Space O(N)
1003
+ * @returns A new heap with the same elements.
1004
+
1005
+
1006
+
1007
+
1008
+
1009
+
1010
+
1011
+
1012
+
1013
+ * @example
1014
+ * // Create independent copy
1015
+ * const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
1016
+ * const copy = heap.clone();
1017
+ * copy.poll();
1018
+ * console.log(heap.size); // 3;
1019
+ * console.log(copy.size); // 2;
1020
+ */
719
1021
  clone() {
720
1022
  const next = this._createInstance();
721
1023
  for (const x of this.elements) next.add(x);
722
1024
  return next;
723
1025
  }
724
1026
  /**
725
- * Filter elements into a new heap of the same class.
726
- * @remarks Time O(N log N), Space O(N)
727
- * @param callback - Predicate (element, index, heap) → boolean to keep element.
728
- * @param [thisArg] - Value for `this` inside the callback.
729
- * @returns A new heap with the kept elements.
730
- */
1027
+ * Filter elements into a new heap of the same class.
1028
+ * @remarks Time O(N log N), Space O(N)
1029
+ * @param callback - Predicate (element, index, heap) → boolean to keep element.
1030
+ * @param [thisArg] - Value for `this` inside the callback.
1031
+ * @returns A new heap with the kept elements.
1032
+
1033
+
1034
+
1035
+
1036
+
1037
+
1038
+
1039
+
1040
+
1041
+ * @example
1042
+ * // Filter elements
1043
+ * const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
1044
+ * const evens = heap.filter(x => x % 2 === 0);
1045
+ * console.log(evens.size); // 2;
1046
+ */
731
1047
  filter(callback, thisArg) {
732
1048
  const out = this._createInstance();
733
1049
  let i = 0;
@@ -741,18 +1057,31 @@ var _Heap = class _Heap extends IterableElementBase {
741
1057
  return out;
742
1058
  }
743
1059
  /**
744
- * Map elements into a new heap of possibly different element type.
745
- * @remarks Time O(N log N), Space O(N)
746
- * @template EM
747
- * @template RM
748
- * @param callback - Mapping function (element, index, heap) → newElement.
749
- * @param options - Options for the output heap, including comparator for EM.
750
- * @param [thisArg] - Value for `this` inside the callback.
751
- * @returns A new heap with mapped elements.
752
- */
1060
+ * Map elements into a new heap of possibly different element type.
1061
+ * @remarks Time O(N log N), Space O(N)
1062
+ * @template EM
1063
+ * @template RM
1064
+ * @param callback - Mapping function (element, index, heap) → newElement.
1065
+ * @param options - Options for the output heap, including comparator for EM.
1066
+ * @param [thisArg] - Value for `this` inside the callback.
1067
+ * @returns A new heap with mapped elements.
1068
+
1069
+
1070
+
1071
+
1072
+
1073
+
1074
+
1075
+
1076
+ * @example
1077
+ * // Transform elements
1078
+ * const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
1079
+ * const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
1080
+ * console.log(doubled.peek()); // 2;
1081
+ */
753
1082
  map(callback, options, thisArg) {
754
1083
  const { comparator, toElementFn, ...rest } = options != null ? options : {};
755
- if (!comparator) throw new TypeError("Heap.map requires options.comparator for EM");
1084
+ if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
756
1085
  const out = this._createLike([], { ...rest, comparator, toElementFn });
757
1086
  let i = 0;
758
1087
  for (const x of this) {
@@ -1101,18 +1430,52 @@ var _Queue = class _Queue extends LinearBase {
1101
1430
  this._autoCompactRatio = value;
1102
1431
  }
1103
1432
  /**
1104
- * Get the number of elements currently in the queue.
1105
- * @remarks Time O(1), Space O(1)
1106
- * @returns Current length.
1107
- */
1433
+ * Get the number of elements currently in the queue.
1434
+ * @remarks Time O(1), Space O(1)
1435
+ * @returns Current length.
1436
+
1437
+
1438
+
1439
+
1440
+
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+ * @example
1448
+ * // Track queue length
1449
+ * const q = new Queue<number>();
1450
+ * console.log(q.length); // 0;
1451
+ * q.push(1);
1452
+ * q.push(2);
1453
+ * console.log(q.length); // 2;
1454
+ */
1108
1455
  get length() {
1109
1456
  return this.elements.length - this._offset;
1110
1457
  }
1111
1458
  /**
1112
- * Get the first element (front) without removing it.
1113
- * @remarks Time O(1), Space O(1)
1114
- * @returns Front element or undefined.
1115
- */
1459
+ * Get the first element (front) without removing it.
1460
+ * @remarks Time O(1), Space O(1)
1461
+ * @returns Front element or undefined.
1462
+
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+ * @example
1474
+ * // View the front element
1475
+ * const q = new Queue<string>(['first', 'second', 'third']);
1476
+ * console.log(q.first); // 'first';
1477
+ * console.log(q.length); // 3;
1478
+ */
1116
1479
  get first() {
1117
1480
  return this.length > 0 ? this.elements[this._offset] : void 0;
1118
1481
  }
@@ -1135,19 +1498,69 @@ var _Queue = class _Queue extends LinearBase {
1135
1498
  return new _Queue(elements);
1136
1499
  }
1137
1500
  /**
1138
- * Check whether the queue is empty.
1139
- * @remarks Time O(1), Space O(1)
1140
- * @returns True if length is 0.
1141
- */
1501
+ * Check whether the queue is empty.
1502
+ * @remarks Time O(1), Space O(1)
1503
+ * @returns True if length is 0.
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+
1511
+
1512
+
1513
+
1514
+
1515
+ * @example
1516
+ * // Queue for...of iteration and isEmpty check
1517
+ * const queue = new Queue<string>(['A', 'B', 'C', 'D']);
1518
+ *
1519
+ * const elements: string[] = [];
1520
+ * for (const item of queue) {
1521
+ * elements.push(item);
1522
+ * }
1523
+ *
1524
+ * // Verify all elements are iterated in order
1525
+ * console.log(elements); // ['A', 'B', 'C', 'D'];
1526
+ *
1527
+ * // Process all elements
1528
+ * while (queue.length > 0) {
1529
+ * queue.shift();
1530
+ * }
1531
+ *
1532
+ * console.log(queue.length); // 0;
1533
+ */
1142
1534
  isEmpty() {
1143
1535
  return this.length === 0;
1144
1536
  }
1145
1537
  /**
1146
- * Enqueue one element at the back.
1147
- * @remarks Time O(1), Space O(1)
1148
- * @param element - Element to enqueue.
1149
- * @returns True on success.
1150
- */
1538
+ * Enqueue one element at the back.
1539
+ * @remarks Time O(1), Space O(1)
1540
+ * @param element - Element to enqueue.
1541
+ * @returns True on success.
1542
+
1543
+
1544
+
1545
+
1546
+
1547
+
1548
+
1549
+
1550
+
1551
+
1552
+
1553
+ * @example
1554
+ * // basic Queue creation and push operation
1555
+ * // Create a simple Queue with initial values
1556
+ * const queue = new Queue([1, 2, 3, 4, 5]);
1557
+ *
1558
+ * // Verify the queue maintains insertion order
1559
+ * console.log([...queue]); // [1, 2, 3, 4, 5];
1560
+ *
1561
+ * // Check length
1562
+ * console.log(queue.length); // 5;
1563
+ */
1151
1564
  push(element) {
1152
1565
  this.elements.push(element);
1153
1566
  if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
@@ -1168,10 +1581,35 @@ var _Queue = class _Queue extends LinearBase {
1168
1581
  return ans;
1169
1582
  }
1170
1583
  /**
1171
- * Dequeue one element from the front (amortized via offset).
1172
- * @remarks Time O(1) amortized, Space O(1)
1173
- * @returns Removed element or undefined.
1174
- */
1584
+ * Dequeue one element from the front (amortized via offset).
1585
+ * @remarks Time O(1) amortized, Space O(1)
1586
+ * @returns Removed element or undefined.
1587
+
1588
+
1589
+
1590
+
1591
+
1592
+
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+ * @example
1599
+ * // Queue shift and peek operations
1600
+ * const queue = new Queue<number>([10, 20, 30, 40]);
1601
+ *
1602
+ * // Peek at the front element without removing it
1603
+ * console.log(queue.first); // 10;
1604
+ *
1605
+ * // Remove and get the first element (FIFO)
1606
+ * const first = queue.shift();
1607
+ * console.log(first); // 10;
1608
+ *
1609
+ * // Verify remaining elements and length decreased
1610
+ * console.log([...queue]); // [20, 30, 40];
1611
+ * console.log(queue.length); // 3;
1612
+ */
1175
1613
  shift() {
1176
1614
  if (this.length === 0) return void 0;
1177
1615
  const first = this.first;
@@ -1180,11 +1618,24 @@ var _Queue = class _Queue extends LinearBase {
1180
1618
  return first;
1181
1619
  }
1182
1620
  /**
1183
- * Delete the first occurrence of a specific element.
1184
- * @remarks Time O(N), Space O(1)
1185
- * @param element - Element to remove (strict equality via Object.is).
1186
- * @returns True if an element was removed.
1187
- */
1621
+ * Delete the first occurrence of a specific element.
1622
+ * @remarks Time O(N), Space O(1)
1623
+ * @param element - Element to remove (strict equality via Object.is).
1624
+ * @returns True if an element was removed.
1625
+
1626
+
1627
+
1628
+
1629
+
1630
+
1631
+
1632
+
1633
+ * @example
1634
+ * // Remove specific element
1635
+ * const q = new Queue<number>([1, 2, 3, 2]);
1636
+ * q.delete(2);
1637
+ * console.log(q.length); // 3;
1638
+ */
1188
1639
  delete(element) {
1189
1640
  for (let i = this._offset; i < this.elements.length; i++) {
1190
1641
  if (Object.is(this.elements[i], element)) {
@@ -1195,11 +1646,24 @@ var _Queue = class _Queue extends LinearBase {
1195
1646
  return false;
1196
1647
  }
1197
1648
  /**
1198
- * Get the element at a given logical index.
1199
- * @remarks Time O(1), Space O(1)
1200
- * @param index - Zero-based index from the front.
1201
- * @returns Element or undefined.
1202
- */
1649
+ * Get the element at a given logical index.
1650
+ * @remarks Time O(1), Space O(1)
1651
+ * @param index - Zero-based index from the front.
1652
+ * @returns Element or undefined.
1653
+
1654
+
1655
+
1656
+
1657
+
1658
+
1659
+
1660
+
1661
+ * @example
1662
+ * // Access element by index
1663
+ * const q = new Queue<string>(['a', 'b', 'c']);
1664
+ * console.log(q.at(0)); // 'a';
1665
+ * console.log(q.at(2)); // 'c';
1666
+ */
1203
1667
  at(index) {
1204
1668
  if (index < 0 || index >= this.length) return void 0;
1205
1669
  return this._elements[this._offset + index];
@@ -1251,19 +1715,48 @@ var _Queue = class _Queue extends LinearBase {
1251
1715
  return this;
1252
1716
  }
1253
1717
  /**
1254
- * Remove all elements and reset offset.
1255
- * @remarks Time O(1), Space O(1)
1256
- * @returns void
1257
- */
1718
+ * Remove all elements and reset offset.
1719
+ * @remarks Time O(1), Space O(1)
1720
+ * @returns void
1721
+
1722
+
1723
+
1724
+
1725
+
1726
+
1727
+
1728
+
1729
+
1730
+ * @example
1731
+ * // Remove all elements
1732
+ * const q = new Queue<number>([1, 2, 3]);
1733
+ * q.clear();
1734
+ * console.log(q.length); // 0;
1735
+ */
1258
1736
  clear() {
1259
1737
  this._elements = [];
1260
1738
  this._offset = 0;
1261
1739
  }
1262
1740
  /**
1263
- * Compact storage by discarding consumed head elements.
1264
- * @remarks Time O(N), Space O(N)
1265
- * @returns True when compaction performed.
1266
- */
1741
+ * Compact storage by discarding consumed head elements.
1742
+ * @remarks Time O(N), Space O(N)
1743
+ * @returns True when compaction performed.
1744
+
1745
+
1746
+
1747
+
1748
+
1749
+
1750
+
1751
+
1752
+ * @example
1753
+ * // Reclaim unused memory
1754
+ * const q = new Queue<number>([1, 2, 3, 4, 5]);
1755
+ * q.shift();
1756
+ * q.shift();
1757
+ * q.compact();
1758
+ * console.log(q.length); // 3;
1759
+ */
1267
1760
  compact() {
1268
1761
  this._elements = this.elements.slice(this._offset);
1269
1762
  this._offset = 0;
@@ -1289,10 +1782,26 @@ var _Queue = class _Queue extends LinearBase {
1289
1782
  return removed;
1290
1783
  }
1291
1784
  /**
1292
- * Deep clone this queue and its parameters.
1293
- * @remarks Time O(N), Space O(N)
1294
- * @returns A new queue with the same content and options.
1295
- */
1785
+ * Deep clone this queue and its parameters.
1786
+ * @remarks Time O(N), Space O(N)
1787
+ * @returns A new queue with the same content and options.
1788
+
1789
+
1790
+
1791
+
1792
+
1793
+
1794
+
1795
+
1796
+
1797
+ * @example
1798
+ * // Create independent copy
1799
+ * const q = new Queue<number>([1, 2, 3]);
1800
+ * const copy = q.clone();
1801
+ * copy.shift();
1802
+ * console.log(q.length); // 3;
1803
+ * console.log(copy.length); // 2;
1804
+ */
1296
1805
  clone() {
1297
1806
  const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
1298
1807
  out._setAutoCompactRatio(this._autoCompactRatio);
@@ -1300,12 +1809,26 @@ var _Queue = class _Queue extends LinearBase {
1300
1809
  return out;
1301
1810
  }
1302
1811
  /**
1303
- * Filter elements into a new queue of the same class.
1304
- * @remarks Time O(N), Space O(N)
1305
- * @param predicate - Predicate (element, index, queue) → boolean to keep element.
1306
- * @param [thisArg] - Value for `this` inside the predicate.
1307
- * @returns A new queue with kept elements.
1308
- */
1812
+ * Filter elements into a new queue of the same class.
1813
+ * @remarks Time O(N), Space O(N)
1814
+ * @param predicate - Predicate (element, index, queue) → boolean to keep element.
1815
+ * @param [thisArg] - Value for `this` inside the predicate.
1816
+ * @returns A new queue with kept elements.
1817
+
1818
+
1819
+
1820
+
1821
+
1822
+
1823
+
1824
+
1825
+
1826
+ * @example
1827
+ * // Filter elements
1828
+ * const q = new Queue<number>([1, 2, 3, 4, 5]);
1829
+ * const evens = q.filter(x => x % 2 === 0);
1830
+ * console.log(evens.length); // 2;
1831
+ */
1309
1832
  filter(predicate, thisArg) {
1310
1833
  const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
1311
1834
  out._setAutoCompactRatio(this._autoCompactRatio);
@@ -1317,15 +1840,28 @@ var _Queue = class _Queue extends LinearBase {
1317
1840
  return out;
1318
1841
  }
1319
1842
  /**
1320
- * Map each element to a new element in a possibly different-typed queue.
1321
- * @remarks Time O(N), Space O(N)
1322
- * @template EM
1323
- * @template RM
1324
- * @param callback - Mapping function (element, index, queue) → newElement.
1325
- * @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
1326
- * @param [thisArg] - Value for `this` inside the callback.
1327
- * @returns A new Queue with mapped elements.
1328
- */
1843
+ * Map each element to a new element in a possibly different-typed queue.
1844
+ * @remarks Time O(N), Space O(N)
1845
+ * @template EM
1846
+ * @template RM
1847
+ * @param callback - Mapping function (element, index, queue) → newElement.
1848
+ * @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
1849
+ * @param [thisArg] - Value for `this` inside the callback.
1850
+ * @returns A new Queue with mapped elements.
1851
+
1852
+
1853
+
1854
+
1855
+
1856
+
1857
+
1858
+
1859
+ * @example
1860
+ * // Transform elements
1861
+ * const q = new Queue<number>([1, 2, 3]);
1862
+ * const doubled = q.map(x => x * 2);
1863
+ * console.log(doubled.toArray()); // [2, 4, 6];
1864
+ */
1329
1865
  map(callback, options, thisArg) {
1330
1866
  var _a, _b;
1331
1867
  const out = new this.constructor([], {
@@ -1554,7 +2090,7 @@ var _AbstractGraph = class _AbstractGraph extends IterableEntryBase {
1554
2090
  const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
1555
2091
  return this._addEdge(newEdge);
1556
2092
  } else {
1557
- throw new Error("dest must be a Vertex or vertex key while srcOrEdge is an Edge");
2093
+ throw new TypeError(ERR.invalidArgument("dest must be a Vertex or vertex key when srcOrEdge is an Edge.", "Graph"));
1558
2094
  }
1559
2095
  }
1560
2096
  }
@@ -2238,6 +2774,94 @@ var _AbstractGraph = class _AbstractGraph extends IterableEntryBase {
2238
2774
  _getVertexKey(vertexOrKey) {
2239
2775
  return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
2240
2776
  }
2777
+ /**
2778
+ * The edge connector string used in visual output.
2779
+ * Override in subclasses (e.g., '--' for undirected, '->' for directed).
2780
+ */
2781
+ get _edgeConnector() {
2782
+ return "--";
2783
+ }
2784
+ /**
2785
+ * Generate a text-based visual representation of the graph.
2786
+ *
2787
+ * **Adjacency list format:**
2788
+ * ```
2789
+ * Graph (5 vertices, 6 edges):
2790
+ * A -> B (1), C (2)
2791
+ * B -> D (3)
2792
+ * C -> (no outgoing edges)
2793
+ * D -> A (1)
2794
+ * E (isolated)
2795
+ * ```
2796
+ *
2797
+ * @param options - Optional display settings.
2798
+ * @param options.showWeight - Whether to show edge weights (default: true).
2799
+ * @returns The visual string.
2800
+ */
2801
+ toVisual(options) {
2802
+ var _a;
2803
+ const showWeight = (_a = options == null ? void 0 : options.showWeight) != null ? _a : true;
2804
+ const vertices = [...this._vertexMap.values()];
2805
+ const vertexCount = vertices.length;
2806
+ const edgeCount = this.edgeSet().length;
2807
+ const lines = [`Graph (${vertexCount} vertices, ${edgeCount} edges):`];
2808
+ for (const vertex of vertices) {
2809
+ const neighbors = this.getNeighbors(vertex);
2810
+ if (neighbors.length === 0) {
2811
+ lines.push(` ${vertex.key} (isolated)`);
2812
+ } else {
2813
+ const edgeStrs = neighbors.map((neighbor) => {
2814
+ const edge = this.getEdge(vertex, neighbor);
2815
+ if (edge && showWeight && edge.weight !== void 0 && edge.weight !== 1) {
2816
+ return `${neighbor.key} (${edge.weight})`;
2817
+ }
2818
+ return `${neighbor.key}`;
2819
+ });
2820
+ lines.push(` ${vertex.key} ${this._edgeConnector} ${edgeStrs.join(", ")}`);
2821
+ }
2822
+ }
2823
+ return lines.join("\n");
2824
+ }
2825
+ /**
2826
+ * Generate DOT language representation for Graphviz.
2827
+ *
2828
+ * @param options - Optional display settings.
2829
+ * @param options.name - Graph name (default: 'G').
2830
+ * @param options.showWeight - Whether to label edges with weight (default: true).
2831
+ * @returns DOT format string.
2832
+ */
2833
+ toDot(options) {
2834
+ var _a, _b;
2835
+ const name = (_a = options == null ? void 0 : options.name) != null ? _a : "G";
2836
+ const showWeight = (_b = options == null ? void 0 : options.showWeight) != null ? _b : true;
2837
+ const isDirected = this._edgeConnector === "->";
2838
+ const graphType = isDirected ? "digraph" : "graph";
2839
+ const edgeOp = isDirected ? "->" : "--";
2840
+ const lines = [`${graphType} ${name} {`];
2841
+ for (const vertex of this._vertexMap.values()) {
2842
+ lines.push(` "${vertex.key}";`);
2843
+ }
2844
+ const visited = /* @__PURE__ */ new Set();
2845
+ for (const vertex of this._vertexMap.values()) {
2846
+ for (const neighbor of this.getNeighbors(vertex)) {
2847
+ const edgeId = isDirected ? `${vertex.key}->${neighbor.key}` : [vertex.key, neighbor.key].sort().join("--");
2848
+ if (visited.has(edgeId)) continue;
2849
+ visited.add(edgeId);
2850
+ const edge = this.getEdge(vertex, neighbor);
2851
+ const label = edge && showWeight && edge.weight !== void 0 && edge.weight !== 1 ? ` [label="${edge.weight}"]` : "";
2852
+ lines.push(` "${vertex.key}" ${edgeOp} "${neighbor.key}"${label};`);
2853
+ }
2854
+ }
2855
+ lines.push("}");
2856
+ return lines.join("\n");
2857
+ }
2858
+ /**
2859
+ * Print the graph to console.
2860
+ * @param options - Display settings passed to `toVisual`.
2861
+ */
2862
+ print(options) {
2863
+ console.log(this.toVisual(options));
2864
+ }
2241
2865
  };
2242
2866
  __name(_AbstractGraph, "AbstractGraph");
2243
2867
  var AbstractGraph = _AbstractGraph;
@@ -2272,6 +2896,9 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2272
2896
  __publicField(this, "_outEdgeMap", /* @__PURE__ */ new Map());
2273
2897
  __publicField(this, "_inEdgeMap", /* @__PURE__ */ new Map());
2274
2898
  }
2899
+ get _edgeConnector() {
2900
+ return "->";
2901
+ }
2275
2902
  get outEdgeMap() {
2276
2903
  return this._outEdgeMap;
2277
2904
  }
@@ -2334,12 +2961,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2334
2961
  return new DirectedEdge(src, dest, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
2335
2962
  }
2336
2963
  /**
2337
- * Get the unique edge from `src` to `dest`, if present.
2338
- * @param srcOrKey - Source vertex or key.
2339
- * @param destOrKey - Destination vertex or key.
2340
- * @returns Edge instance or `undefined`.
2341
- * @remarks Time O(1) avg, Space O(1)
2342
- */
2964
+ * Get the unique edge from `src` to `dest`, if present.
2965
+ * @param srcOrKey - Source vertex or key.
2966
+ * @param destOrKey - Destination vertex or key.
2967
+ * @returns Edge instance or `undefined`.
2968
+ * @remarks Time O(1) avg, Space O(1)
2969
+
2970
+
2971
+
2972
+
2973
+
2974
+
2975
+
2976
+
2977
+ * @example
2978
+ * // Get edge between vertices
2979
+ * const g = new DirectedGraph();
2980
+ * g.addVertex('A');
2981
+ * g.addVertex('B');
2982
+ * g.addEdge('A', 'B', 5);
2983
+ * const edge = g.getEdge('A', 'B');
2984
+ * console.log(edge?.weight); // 5;
2985
+ */
2343
2986
  getEdge(srcOrKey, destOrKey) {
2344
2987
  let edgeMap = [];
2345
2988
  if (srcOrKey !== void 0 && destOrKey !== void 0) {
@@ -2379,12 +3022,48 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2379
3022
  return removed;
2380
3023
  }
2381
3024
  /**
2382
- * Delete an edge by instance or by `(srcKey, destKey)`.
2383
- * @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
2384
- * @param destVertexKey - Optional destination vertex/key when deleting by pair.
2385
- * @returns Removed edge or `undefined`.
2386
- * @remarks Time O(1) avg, Space O(1)
2387
- */
3025
+ * Delete an edge by instance or by `(srcKey, destKey)`.
3026
+ * @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
3027
+ * @param destVertexKey - Optional destination vertex/key when deleting by pair.
3028
+ * @returns Removed edge or `undefined`.
3029
+ * @remarks Time O(1) avg, Space O(1)
3030
+
3031
+
3032
+
3033
+
3034
+
3035
+
3036
+
3037
+
3038
+
3039
+
3040
+
3041
+ * @example
3042
+ * // DirectedGraph deleteEdge and vertex operations
3043
+ * const graph = new DirectedGraph<string>();
3044
+ *
3045
+ * // Build a small graph
3046
+ * graph.addVertex('X');
3047
+ * graph.addVertex('Y');
3048
+ * graph.addVertex('Z');
3049
+ * graph.addEdge('X', 'Y', 1);
3050
+ * graph.addEdge('Y', 'Z', 2);
3051
+ *
3052
+ * // Delete an edge
3053
+ * graph.deleteEdgeSrcToDest('X', 'Y');
3054
+ * console.log(graph.hasEdge('X', 'Y')); // false;
3055
+ *
3056
+ * // Edge in other direction should not exist
3057
+ * console.log(graph.hasEdge('Y', 'X')); // false;
3058
+ *
3059
+ * // Other edges should remain
3060
+ * console.log(graph.hasEdge('Y', 'Z')); // true;
3061
+ *
3062
+ * // Delete a vertex
3063
+ * graph.deleteVertex('Y');
3064
+ * console.log(graph.hasVertex('Y')); // false;
3065
+ * console.log(graph.size); // 2;
3066
+ */
2388
3067
  deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
2389
3068
  let removed = void 0;
2390
3069
  let src, dest;
@@ -2411,6 +3090,26 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2411
3090
  }
2412
3091
  return removed;
2413
3092
  }
3093
+ /**
3094
+ * Remove a vertex
3095
+
3096
+
3097
+
3098
+
3099
+
3100
+
3101
+
3102
+
3103
+ * @example
3104
+ * // Remove a vertex
3105
+ * const g = new DirectedGraph();
3106
+ * g.addVertex('A');
3107
+ * g.addVertex('B');
3108
+ * g.addEdge('A', 'B');
3109
+ * g.deleteVertex('A');
3110
+ * console.log(g.hasVertex('A')); // false;
3111
+ * console.log(g.hasEdge('A', 'B')); // false;
3112
+ */
2414
3113
  deleteVertex(vertexOrKey) {
2415
3114
  let vertexKey;
2416
3115
  let vertex;
@@ -2442,11 +3141,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2442
3141
  return removed;
2443
3142
  }
2444
3143
  /**
2445
- * Incoming edges of a vertex.
2446
- * @param vertexOrKey - Vertex or key.
2447
- * @returns Array of incoming edges.
2448
- * @remarks Time O(deg_in), Space O(deg_in)
2449
- */
3144
+ * Incoming edges of a vertex.
3145
+ * @param vertexOrKey - Vertex or key.
3146
+ * @returns Array of incoming edges.
3147
+ * @remarks Time O(deg_in), Space O(deg_in)
3148
+
3149
+
3150
+
3151
+
3152
+
3153
+
3154
+
3155
+
3156
+ * @example
3157
+ * // Get incoming edges
3158
+ * const g = new DirectedGraph();
3159
+ * g.addVertex('A');
3160
+ * g.addVertex('B');
3161
+ * g.addVertex('C');
3162
+ * g.addEdge('A', 'C');
3163
+ * g.addEdge('B', 'C');
3164
+ * console.log(g.incomingEdgesOf('C').length); // 2;
3165
+ */
2450
3166
  incomingEdgesOf(vertexOrKey) {
2451
3167
  const target = this._getVertex(vertexOrKey);
2452
3168
  if (target) {
@@ -2455,11 +3171,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2455
3171
  return [];
2456
3172
  }
2457
3173
  /**
2458
- * Outgoing edges of a vertex.
2459
- * @param vertexOrKey - Vertex or key.
2460
- * @returns Array of outgoing edges.
2461
- * @remarks Time O(deg_out), Space O(deg_out)
2462
- */
3174
+ * Outgoing edges of a vertex.
3175
+ * @param vertexOrKey - Vertex or key.
3176
+ * @returns Array of outgoing edges.
3177
+ * @remarks Time O(deg_out), Space O(deg_out)
3178
+
3179
+
3180
+
3181
+
3182
+
3183
+
3184
+
3185
+
3186
+ * @example
3187
+ * // Get outgoing edges
3188
+ * const g = new DirectedGraph();
3189
+ * g.addVertex('A');
3190
+ * g.addVertex('B');
3191
+ * g.addVertex('C');
3192
+ * g.addEdge('A', 'B');
3193
+ * g.addEdge('A', 'C');
3194
+ * console.log(g.outgoingEdgesOf('A').length); // 2;
3195
+ */
2463
3196
  outgoingEdgesOf(vertexOrKey) {
2464
3197
  const target = this._getVertex(vertexOrKey);
2465
3198
  if (target) {
@@ -2518,11 +3251,44 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2518
3251
  return destinations;
2519
3252
  }
2520
3253
  /**
2521
- * Topological sort if DAG; returns `undefined` if a cycle exists.
2522
- * @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
2523
- * @returns Array of keys/vertices, or `undefined` when cycle is found.
2524
- * @remarks Time O(V + E), Space O(V)
2525
- */
3254
+ * Topological sort if DAG; returns `undefined` if a cycle exists.
3255
+ * @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
3256
+ * @returns Array of keys/vertices, or `undefined` when cycle is found.
3257
+ * @remarks Time O(V + E), Space O(V)
3258
+
3259
+
3260
+
3261
+
3262
+
3263
+
3264
+
3265
+
3266
+
3267
+
3268
+
3269
+ * @example
3270
+ * // DirectedGraph topologicalSort for task scheduling
3271
+ * const graph = new DirectedGraph<string>();
3272
+ *
3273
+ * // Build a DAG (Directed Acyclic Graph) for task dependencies
3274
+ * graph.addVertex('Design');
3275
+ * graph.addVertex('Implement');
3276
+ * graph.addVertex('Test');
3277
+ * graph.addVertex('Deploy');
3278
+ *
3279
+ * // Add dependency edges
3280
+ * graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
3281
+ * graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
3282
+ * graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
3283
+ *
3284
+ * // Topological sort gives valid execution order
3285
+ * const executionOrder = graph.topologicalSort();
3286
+ * console.log(executionOrder); // defined;
3287
+ * console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
3288
+ *
3289
+ * // All vertices should be included
3290
+ * console.log(executionOrder?.length); // 4;
3291
+ */
2526
3292
  topologicalSort(propertyName) {
2527
3293
  propertyName = propertyName != null ? propertyName : "key";
2528
3294
  const statusMap = /* @__PURE__ */ new Map();
@@ -2554,6 +3320,24 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2554
3320
  if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
2555
3321
  return sorted.reverse();
2556
3322
  }
3323
+ /**
3324
+ * Get all edges
3325
+
3326
+
3327
+
3328
+
3329
+
3330
+
3331
+
3332
+
3333
+ * @example
3334
+ * // Get all edges
3335
+ * const g = new DirectedGraph();
3336
+ * g.addVertex('A');
3337
+ * g.addVertex('B');
3338
+ * g.addEdge('A', 'B', 3);
3339
+ * console.log(g.edgeSet().length); // 1;
3340
+ */
2557
3341
  edgeSet() {
2558
3342
  let edgeMap = [];
2559
3343
  this._outEdgeMap.forEach((outEdges) => {
@@ -2561,6 +3345,28 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2561
3345
  });
2562
3346
  return edgeMap;
2563
3347
  }
3348
+ /**
3349
+ * Get outgoing neighbors
3350
+
3351
+
3352
+
3353
+
3354
+
3355
+
3356
+
3357
+
3358
+
3359
+ * @example
3360
+ * // Get outgoing neighbors
3361
+ * const g = new DirectedGraph();
3362
+ * g.addVertex('A');
3363
+ * g.addVertex('B');
3364
+ * g.addVertex('C');
3365
+ * g.addEdge('A', 'B');
3366
+ * g.addEdge('A', 'C');
3367
+ * const neighbors = g.getNeighbors('A');
3368
+ * console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
3369
+ */
2564
3370
  getNeighbors(vertexOrKey) {
2565
3371
  const neighbors = [];
2566
3372
  const vertex = this._getVertex(vertexOrKey);
@@ -2618,10 +3424,31 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2618
3424
  return super.clone();
2619
3425
  }
2620
3426
  /**
2621
- * Tarjan's algorithm for strongly connected components.
2622
- * @returns `{ dfnMap, lowMap, SCCs }`.
2623
- * @remarks Time O(V + E), Space O(V + E)
2624
- */
3427
+ * Tarjan's algorithm for strongly connected components.
3428
+ * @returns `{ dfnMap, lowMap, SCCs }`.
3429
+ * @remarks Time O(V + E), Space O(V + E)
3430
+
3431
+
3432
+
3433
+
3434
+
3435
+
3436
+
3437
+
3438
+ * @example
3439
+ * // Find strongly connected components
3440
+ * const g = new DirectedGraph();
3441
+ * g.addVertex('A');
3442
+ * g.addVertex('B');
3443
+ * g.addVertex('C');
3444
+ * g.addEdge('A', 'B');
3445
+ * g.addEdge('B', 'C');
3446
+ * g.addEdge('C', 'A');
3447
+ * const { SCCs } = g.tarjan();
3448
+ * // A→B→C→A forms one SCC with 3 members
3449
+ * const sccArrays = [...SCCs.values()];
3450
+ * console.log(sccArrays.some(scc => scc.length === 3)); // true;
3451
+ */
2625
3452
  tarjan() {
2626
3453
  const dfnMap = /* @__PURE__ */ new Map();
2627
3454
  const lowMap = /* @__PURE__ */ new Map();
@@ -2679,10 +3506,29 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
2679
3506
  return this.tarjan().lowMap;
2680
3507
  }
2681
3508
  /**
2682
- * Strongly connected components computed by `tarjan()`.
2683
- * @returns Map from SCC id to vertices.
2684
- * @remarks Time O(#SCC + V), Space O(V)
2685
- */
3509
+ * Strongly connected components computed by `tarjan()`.
3510
+ * @returns Map from SCC id to vertices.
3511
+ * @remarks Time O(#SCC + V), Space O(V)
3512
+
3513
+
3514
+
3515
+
3516
+
3517
+
3518
+
3519
+
3520
+ * @example
3521
+ * // Get strongly connected components
3522
+ * const g = new DirectedGraph();
3523
+ * g.addVertex(1);
3524
+ * g.addVertex(2);
3525
+ * g.addVertex(3);
3526
+ * g.addEdge(1, 2);
3527
+ * g.addEdge(2, 3);
3528
+ * g.addEdge(3, 1);
3529
+ * const sccs = g.getSCCs(); // Map<number, VO[]>
3530
+ * console.log(sccs.size); // >= 1;
3531
+ */
2686
3532
  getSCCs() {
2687
3533
  return this.tarjan().SCCs;
2688
3534
  }
@@ -2804,12 +3650,27 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2804
3650
  return new UndirectedEdge(v1, v2, (_a = weight != null ? weight : this.options.defaultEdgeWeight) != null ? _a : 1, value);
2805
3651
  }
2806
3652
  /**
2807
- * Get an undirected edge between two vertices, if present.
2808
- * @param v1 - One vertex or key.
2809
- * @param v2 - The other vertex or key.
2810
- * @returns Edge instance or `undefined`.
2811
- * @remarks Time O(1) avg, Space O(1)
2812
- */
3653
+ * Get an undirected edge between two vertices, if present.
3654
+ * @param v1 - One vertex or key.
3655
+ * @param v2 - The other vertex or key.
3656
+ * @returns Edge instance or `undefined`.
3657
+ * @remarks Time O(1) avg, Space O(1)
3658
+
3659
+
3660
+
3661
+
3662
+
3663
+
3664
+
3665
+
3666
+ * @example
3667
+ * // Get edge between vertices
3668
+ * const g = new UndirectedGraph();
3669
+ * g.addVertex('A');
3670
+ * g.addVertex('B');
3671
+ * g.addEdge('A', 'B', 7);
3672
+ * console.log(g.getEdge('A', 'B')?.weight); // 7;
3673
+ */
2813
3674
  getEdge(v1, v2) {
2814
3675
  var _a;
2815
3676
  let edgeMap = [];
@@ -2847,12 +3708,50 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2847
3708
  return removed;
2848
3709
  }
2849
3710
  /**
2850
- * Delete an edge by instance or by a pair of keys.
2851
- * @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
2852
- * @param otherSideVertexKey - Required second endpoint when deleting by pair.
2853
- * @returns Removed edge or `undefined`.
2854
- * @remarks Time O(1) avg, Space O(1)
2855
- */
3711
+ * Delete an edge by instance or by a pair of keys.
3712
+ * @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
3713
+ * @param otherSideVertexKey - Required second endpoint when deleting by pair.
3714
+ * @returns Removed edge or `undefined`.
3715
+ * @remarks Time O(1) avg, Space O(1)
3716
+
3717
+
3718
+
3719
+
3720
+
3721
+
3722
+
3723
+
3724
+
3725
+
3726
+
3727
+ * @example
3728
+ * // UndirectedGraph deleteEdge and vertex operations
3729
+ * const graph = new UndirectedGraph<string>();
3730
+ *
3731
+ * // Build a simple undirected graph
3732
+ * graph.addVertex('X');
3733
+ * graph.addVertex('Y');
3734
+ * graph.addVertex('Z');
3735
+ * graph.addEdge('X', 'Y', 1);
3736
+ * graph.addEdge('Y', 'Z', 2);
3737
+ * graph.addEdge('X', 'Z', 3);
3738
+ *
3739
+ * // Delete an edge
3740
+ * graph.deleteEdge('X', 'Y');
3741
+ * console.log(graph.hasEdge('X', 'Y')); // false;
3742
+ *
3743
+ * // Bidirectional deletion confirmed
3744
+ * console.log(graph.hasEdge('Y', 'X')); // false;
3745
+ *
3746
+ * // Other edges should remain
3747
+ * console.log(graph.hasEdge('Y', 'Z')); // true;
3748
+ * console.log(graph.hasEdge('Z', 'Y')); // true;
3749
+ *
3750
+ * // Delete a vertex
3751
+ * graph.deleteVertex('Y');
3752
+ * console.log(graph.hasVertex('Y')); // false;
3753
+ * console.log(graph.size); // 2;
3754
+ */
2856
3755
  deleteEdge(edgeOrOneSideVertexKey, otherSideVertexKey) {
2857
3756
  let oneSide, otherSide;
2858
3757
  if (this.isVertexKey(edgeOrOneSideVertexKey)) {
@@ -2873,11 +3772,27 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2873
3772
  }
2874
3773
  }
2875
3774
  /**
2876
- * Delete a vertex and remove it from all neighbor lists.
2877
- * @param vertexOrKey - Vertex or key.
2878
- * @returns `true` if removed; otherwise `false`.
2879
- * @remarks Time O(deg), Space O(1)
2880
- */
3775
+ * Delete a vertex and remove it from all neighbor lists.
3776
+ * @param vertexOrKey - Vertex or key.
3777
+ * @returns `true` if removed; otherwise `false`.
3778
+ * @remarks Time O(deg), Space O(1)
3779
+
3780
+
3781
+
3782
+
3783
+
3784
+
3785
+
3786
+
3787
+ * @example
3788
+ * // Remove vertex and edges
3789
+ * const g = new UndirectedGraph();
3790
+ * g.addVertex('A');
3791
+ * g.addVertex('B');
3792
+ * g.addEdge('A', 'B');
3793
+ * g.deleteVertex('A');
3794
+ * console.log(g.hasVertex('A')); // false;
3795
+ */
2881
3796
  deleteVertex(vertexOrKey) {
2882
3797
  let vertexKey;
2883
3798
  let vertex;
@@ -2933,10 +3848,25 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2933
3848
  }
2934
3849
  }
2935
3850
  /**
2936
- * Unique set of undirected edges across endpoints.
2937
- * @returns Array of edges.
2938
- * @remarks Time O(E), Space O(E)
2939
- */
3851
+ * Unique set of undirected edges across endpoints.
3852
+ * @returns Array of edges.
3853
+ * @remarks Time O(E), Space O(E)
3854
+
3855
+
3856
+
3857
+
3858
+
3859
+
3860
+
3861
+
3862
+ * @example
3863
+ * // Get all edges
3864
+ * const g = new UndirectedGraph();
3865
+ * g.addVertex('A');
3866
+ * g.addVertex('B');
3867
+ * g.addEdge('A', 'B');
3868
+ * console.log(g.edgeSet().length); // 1;
3869
+ */
2940
3870
  edgeSet() {
2941
3871
  const edgeSet = /* @__PURE__ */ new Set();
2942
3872
  this._edgeMap.forEach((edgeMap) => {
@@ -2946,6 +3876,52 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
2946
3876
  });
2947
3877
  return [...edgeSet];
2948
3878
  }
3879
+ /**
3880
+ * UndirectedGraph connectivity and neighbors
3881
+
3882
+
3883
+
3884
+
3885
+
3886
+
3887
+
3888
+
3889
+
3890
+
3891
+
3892
+ * @example
3893
+ * // UndirectedGraph connectivity and neighbors
3894
+ * const graph = new UndirectedGraph<string>();
3895
+ *
3896
+ * // Build a friendship network
3897
+ * const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
3898
+ * for (const person of people) {
3899
+ * graph.addVertex(person);
3900
+ * }
3901
+ *
3902
+ * // Add friendships (undirected edges)
3903
+ * graph.addEdge('Alice', 'Bob', 1);
3904
+ * graph.addEdge('Alice', 'Charlie', 1);
3905
+ * graph.addEdge('Bob', 'Diana', 1);
3906
+ * graph.addEdge('Charlie', 'Eve', 1);
3907
+ * graph.addEdge('Diana', 'Eve', 1);
3908
+ *
3909
+ * // Get friends of each person
3910
+ * const aliceFriends = graph.getNeighbors('Alice');
3911
+ * console.log(aliceFriends[0].key); // 'Bob';
3912
+ * console.log(aliceFriends[1].key); // 'Charlie';
3913
+ * console.log(aliceFriends.length); // 2;
3914
+ *
3915
+ * const dianaFriends = graph.getNeighbors('Diana');
3916
+ * console.log(dianaFriends[0].key); // 'Bob';
3917
+ * console.log(dianaFriends[1].key); // 'Eve';
3918
+ * console.log(dianaFriends.length); // 2;
3919
+ *
3920
+ * // Verify bidirectional friendship
3921
+ * const bobFriends = graph.getNeighbors('Bob');
3922
+ * console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
3923
+ * console.log(bobFriends[1].key); // 'Diana';
3924
+ */
2949
3925
  getNeighbors(vertexOrKey) {
2950
3926
  const neighbors = [];
2951
3927
  const vertex = this._getVertex(vertexOrKey);
@@ -3002,10 +3978,28 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
3002
3978
  return super.clone();
3003
3979
  }
3004
3980
  /**
3005
- * Tarjan-based bridge and articulation point detection.
3006
- * @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
3007
- * @remarks Time O(V + E), Space O(V + E)
3008
- */
3981
+ * Tarjan-based bridge and articulation point detection.
3982
+ * @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
3983
+ * @remarks Time O(V + E), Space O(V + E)
3984
+
3985
+
3986
+
3987
+
3988
+
3989
+
3990
+
3991
+
3992
+ * @example
3993
+ * // Find articulation points and bridges
3994
+ * const g = new UndirectedGraph();
3995
+ * g.addVertex('A');
3996
+ * g.addVertex('B');
3997
+ * g.addVertex('C');
3998
+ * g.addEdge('A', 'B');
3999
+ * g.addEdge('B', 'C');
4000
+ * const result = g.tarjan();
4001
+ * console.log(result); // defined;
4002
+ */
3009
4003
  tarjan() {
3010
4004
  const dfnMap = /* @__PURE__ */ new Map();
3011
4005
  const lowMap = /* @__PURE__ */ new Map();
@@ -3053,18 +4047,152 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
3053
4047
  };
3054
4048
  }
3055
4049
  /**
3056
- * Get bridges discovered by `tarjan()`.
3057
- * @returns Array of edges that are bridges.
3058
- * @remarks Time O(B), Space O(1)
4050
+ * Find biconnected components using edge-stack Tarjan variant.
4051
+ * A biconnected component is a maximal biconnected subgraph.
4052
+ * @returns Array of edge arrays, each representing a biconnected component.
4053
+ * @remarks Time O(V + E), Space O(V + E)
3059
4054
  */
4055
+ getBiconnectedComponents() {
4056
+ const dfn = /* @__PURE__ */ new Map();
4057
+ const low = /* @__PURE__ */ new Map();
4058
+ const edgeStack = [];
4059
+ const components = [];
4060
+ let time = 0;
4061
+ const dfs = /* @__PURE__ */ __name((vertex, parent) => {
4062
+ dfn.set(vertex, time);
4063
+ low.set(vertex, time);
4064
+ time++;
4065
+ const neighbors = this.getNeighbors(vertex);
4066
+ let childCount = 0;
4067
+ for (const neighbor of neighbors) {
4068
+ const edge = this.getEdge(vertex, neighbor);
4069
+ if (!edge) continue;
4070
+ if (!dfn.has(neighbor)) {
4071
+ childCount++;
4072
+ edgeStack.push(edge);
4073
+ dfs(neighbor, vertex);
4074
+ low.set(vertex, Math.min(low.get(vertex), low.get(neighbor)));
4075
+ if (parent === void 0 && childCount > 1 || parent !== void 0 && low.get(neighbor) >= dfn.get(vertex)) {
4076
+ const component = [];
4077
+ let e;
4078
+ do {
4079
+ e = edgeStack.pop();
4080
+ if (e) component.push(e);
4081
+ } while (e && e !== edge);
4082
+ if (component.length > 0) components.push(component);
4083
+ }
4084
+ } else if (neighbor !== parent && dfn.get(neighbor) < dfn.get(vertex)) {
4085
+ edgeStack.push(edge);
4086
+ low.set(vertex, Math.min(low.get(vertex), dfn.get(neighbor)));
4087
+ }
4088
+ }
4089
+ }, "dfs");
4090
+ for (const vertex of this.vertexMap.values()) {
4091
+ if (!dfn.has(vertex)) {
4092
+ dfs(vertex, void 0);
4093
+ if (edgeStack.length > 0) {
4094
+ components.push([...edgeStack]);
4095
+ edgeStack.length = 0;
4096
+ }
4097
+ }
4098
+ }
4099
+ return components;
4100
+ }
4101
+ /**
4102
+ * Detect whether the graph contains a cycle.
4103
+ * Uses DFS with parent tracking.
4104
+ * @returns `true` if a cycle exists, `false` otherwise.
4105
+ * @remarks Time O(V + E), Space O(V)
4106
+
4107
+
4108
+
4109
+
4110
+
4111
+
4112
+
4113
+
4114
+ * @example
4115
+ * // Detect cycle
4116
+ * const g = new UndirectedGraph();
4117
+ * g.addVertex('A');
4118
+ * g.addVertex('B');
4119
+ * g.addVertex('C');
4120
+ * g.addEdge('A', 'B');
4121
+ * g.addEdge('B', 'C');
4122
+ * console.log(g.hasCycle()); // false;
4123
+ * g.addEdge('C', 'A');
4124
+ * console.log(g.hasCycle()); // true;
4125
+ */
4126
+ hasCycle() {
4127
+ const visited = /* @__PURE__ */ new Set();
4128
+ const dfs = /* @__PURE__ */ __name((vertex, parent) => {
4129
+ visited.add(vertex);
4130
+ for (const neighbor of this.getNeighbors(vertex)) {
4131
+ if (!visited.has(neighbor)) {
4132
+ if (dfs(neighbor, vertex)) return true;
4133
+ } else if (neighbor !== parent) {
4134
+ return true;
4135
+ }
4136
+ }
4137
+ return false;
4138
+ }, "dfs");
4139
+ for (const vertex of this.vertexMap.values()) {
4140
+ if (!visited.has(vertex)) {
4141
+ if (dfs(vertex, void 0)) return true;
4142
+ }
4143
+ }
4144
+ return false;
4145
+ }
4146
+ /**
4147
+ * Get bridges discovered by `tarjan()`.
4148
+ * @returns Array of edges that are bridges.
4149
+ * @remarks Time O(B), Space O(1)
4150
+
4151
+
4152
+
4153
+
4154
+
4155
+
4156
+
4157
+
4158
+ * @example
4159
+ * // Find bridge edges
4160
+ * const g = new UndirectedGraph();
4161
+ * g.addVertex('A');
4162
+ * g.addVertex('B');
4163
+ * g.addVertex('C');
4164
+ * g.addEdge('A', 'B');
4165
+ * g.addEdge('B', 'C');
4166
+ * const bridges = g.getBridges();
4167
+ * console.log(bridges.length); // 2;
4168
+ */
3060
4169
  getBridges() {
3061
4170
  return this.tarjan().bridges;
3062
4171
  }
3063
4172
  /**
3064
- * Get articulation points discovered by `tarjan()`.
3065
- * @returns Array of cut vertices.
3066
- * @remarks Time O(C), Space O(1)
3067
- */
4173
+ * Get articulation points discovered by `tarjan()`.
4174
+ * @returns Array of cut vertices.
4175
+ * @remarks Time O(C), Space O(1)
4176
+
4177
+
4178
+
4179
+
4180
+
4181
+
4182
+
4183
+
4184
+ * @example
4185
+ * // Find articulation points
4186
+ * const g = new UndirectedGraph();
4187
+ * g.addVertex('A');
4188
+ * g.addVertex('B');
4189
+ * g.addVertex('C');
4190
+ * g.addEdge('A', 'B');
4191
+ * g.addEdge('B', 'C');
4192
+ * const cuts = g.getCutVertices();
4193
+ * console.log(cuts.length); // 1;
4194
+ * console.log(cuts[0].key); // 'B';
4195
+ */
3068
4196
  getCutVertices() {
3069
4197
  return this.tarjan().cutVertices;
3070
4198
  }
@@ -3203,29 +4331,6 @@ var _MapGraph = class _MapGraph extends DirectedGraph {
3203
4331
  };
3204
4332
  __name(_MapGraph, "MapGraph");
3205
4333
  var MapGraph = _MapGraph;
3206
-
3207
- // src/common/index.ts
3208
- var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
3209
- DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
3210
- DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
3211
- return DFSOperation2;
3212
- })(DFSOperation || {});
3213
- var _Range = class _Range {
3214
- constructor(low, high, includeLow = true, includeHigh = true) {
3215
- this.low = low;
3216
- this.high = high;
3217
- this.includeLow = includeLow;
3218
- this.includeHigh = includeHigh;
3219
- }
3220
- // Determine whether a key is within the range
3221
- isInRange(key, comparator) {
3222
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
3223
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
3224
- return lowCheck && highCheck;
3225
- }
3226
- };
3227
- __name(_Range, "Range");
3228
- var Range = _Range;
3229
4334
  /**
3230
4335
  * data-structure-typed
3231
4336
  *
@@ -3234,6 +4339,6 @@ var Range = _Range;
3234
4339
  * @license MIT License
3235
4340
  */
3236
4341
 
3237
- export { AbstractEdge, AbstractGraph, AbstractVertex, DFSOperation, DirectedEdge, DirectedGraph, DirectedVertex, MapEdge, MapGraph, MapVertex, Range, UndirectedEdge, UndirectedGraph, UndirectedVertex };
4342
+ export { AbstractEdge, AbstractGraph, AbstractVertex, DFSOperation, DirectedEdge, DirectedGraph, DirectedVertex, ERR, MapEdge, MapGraph, MapVertex, Range, UndirectedEdge, UndirectedGraph, UndirectedVertex };
3238
4343
  //# sourceMappingURL=index.mjs.map
3239
4344
  //# sourceMappingURL=index.mjs.map