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.
- package/dist/cjs/index.cjs +1324 -220
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +1325 -219
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1324 -221
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +1325 -220
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/common/error.d.ts +23 -0
- package/dist/types/common/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +313 -66
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
- package/dist/umd/graph-typed.js +1323 -217
- package/dist/umd/graph-typed.js.map +1 -1
- package/dist/umd/graph-typed.min.js +3 -1
- package/dist/umd/graph-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/common/error.ts +60 -0
- package/src/common/index.ts +2 -0
- package/src/data-structures/base/iterable-element-base.ts +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
- package/src/data-structures/binary-tree/binary-tree.ts +542 -121
- package/src/data-structures/binary-tree/bst.ts +346 -37
- package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1292 -13
- package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
- package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
- package/src/data-structures/binary-tree/tree-set.ts +1143 -15
- package/src/data-structures/graph/abstract-graph.ts +106 -1
- package/src/data-structures/graph/directed-graph.ts +223 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +299 -59
- package/src/data-structures/hash/hash-map.ts +243 -79
- package/src/data-structures/heap/heap.ts +291 -102
- package/src/data-structures/heap/max-heap.ts +48 -3
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +425 -22
- package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +343 -68
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +215 -44
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
- package/src/types/data-structures/queue/deque.ts +7 -0
- 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(
|
|
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
|
-
|
|
468
|
-
|
|
469
|
-
|
|
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
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
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
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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
|
-
|
|
539
|
-
|
|
540
|
-
|
|
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
|
-
|
|
554
|
-
|
|
555
|
-
|
|
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
|
-
|
|
562
|
-
|
|
563
|
-
|
|
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
|
-
|
|
570
|
-
|
|
571
|
-
|
|
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
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
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
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
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
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
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
|
-
|
|
701
|
-
|
|
702
|
-
|
|
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
|
-
|
|
716
|
-
|
|
717
|
-
|
|
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
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
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
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
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
|
|
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
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
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
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
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
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
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
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
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
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
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
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
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
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
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
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
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
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
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
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
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
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
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
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
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
|
|
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
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
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
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
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
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
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
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
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
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
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
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
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
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
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
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
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
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
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
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
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
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
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
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
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
|
-
*
|
|
3057
|
-
*
|
|
3058
|
-
* @
|
|
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
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
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
|