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
package/dist/cjs/index.cjs
CHANGED
|
@@ -24,6 +24,55 @@ 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 {
|
|
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
|
+
static {
|
|
66
|
+
__name(this, "Range");
|
|
67
|
+
}
|
|
68
|
+
// Determine whether a key is within the range
|
|
69
|
+
isInRange(key, comparator) {
|
|
70
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
71
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
72
|
+
return lowCheck && highCheck;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
27
76
|
// src/data-structures/base/iterable-entry-base.ts
|
|
28
77
|
var IterableEntryBase = class {
|
|
29
78
|
static {
|
|
@@ -460,10 +509,30 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
460
509
|
return this._elements;
|
|
461
510
|
}
|
|
462
511
|
/**
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
512
|
+
* Get the number of elements.
|
|
513
|
+
* @remarks Time O(1), Space O(1)
|
|
514
|
+
* @returns Heap size.
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
* @example
|
|
527
|
+
* // Track heap capacity
|
|
528
|
+
* const heap = new Heap<number>();
|
|
529
|
+
* console.log(heap.size); // 0;
|
|
530
|
+
* heap.add(10);
|
|
531
|
+
* heap.add(20);
|
|
532
|
+
* console.log(heap.size); // 2;
|
|
533
|
+
* heap.poll();
|
|
534
|
+
* console.log(heap.size); // 1;
|
|
535
|
+
*/
|
|
467
536
|
get size() {
|
|
468
537
|
return this.elements.length;
|
|
469
538
|
}
|
|
@@ -501,21 +570,61 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
501
570
|
return new _Heap(elements, options);
|
|
502
571
|
}
|
|
503
572
|
/**
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
573
|
+
* Insert an element.
|
|
574
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
575
|
+
* @param element - Element to insert.
|
|
576
|
+
* @returns True.
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
* @example
|
|
589
|
+
* // basic Heap creation and add operation
|
|
590
|
+
* // Create a min heap (default)
|
|
591
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
592
|
+
*
|
|
593
|
+
* // Verify size
|
|
594
|
+
* console.log(minHeap.size); // 6;
|
|
595
|
+
*
|
|
596
|
+
* // Add new element
|
|
597
|
+
* minHeap.add(4);
|
|
598
|
+
* console.log(minHeap.size); // 7;
|
|
599
|
+
*
|
|
600
|
+
* // Min heap property: smallest element at root
|
|
601
|
+
* const min = minHeap.peek();
|
|
602
|
+
* console.log(min); // 1;
|
|
603
|
+
*/
|
|
509
604
|
add(element) {
|
|
510
605
|
this._elements.push(element);
|
|
511
606
|
return this._bubbleUp(this.elements.length - 1);
|
|
512
607
|
}
|
|
513
608
|
/**
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
609
|
+
* Insert many elements from an iterable.
|
|
610
|
+
* @remarks Time O(N log N), Space O(1)
|
|
611
|
+
* @param elements - Iterable of elements or raw values.
|
|
612
|
+
* @returns Array of per-element success flags.
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
* @example
|
|
622
|
+
* // Add multiple elements
|
|
623
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
624
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
625
|
+
* console.log(heap.peek()); // 1;
|
|
626
|
+
* console.log(heap.size); // 4;
|
|
627
|
+
*/
|
|
519
628
|
addMany(elements) {
|
|
520
629
|
const flags = [];
|
|
521
630
|
for (const el of elements) {
|
|
@@ -530,10 +639,46 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
530
639
|
return flags;
|
|
531
640
|
}
|
|
532
641
|
/**
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
642
|
+
* Remove and return the top element.
|
|
643
|
+
* @remarks Time O(log N), Space O(1)
|
|
644
|
+
* @returns Top element or undefined.
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
* @example
|
|
657
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
658
|
+
* interface Task {
|
|
659
|
+
* id: number;
|
|
660
|
+
* priority: number;
|
|
661
|
+
* name: string;
|
|
662
|
+
* }
|
|
663
|
+
*
|
|
664
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
665
|
+
* const tasks: Task[] = [
|
|
666
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
667
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
668
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
669
|
+
* ];
|
|
670
|
+
*
|
|
671
|
+
* const maxHeap = new Heap(tasks, {
|
|
672
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
673
|
+
* });
|
|
674
|
+
*
|
|
675
|
+
* console.log(maxHeap.size); // 3;
|
|
676
|
+
*
|
|
677
|
+
* // Peek returns highest priority task
|
|
678
|
+
* const topTask = maxHeap.peek();
|
|
679
|
+
* console.log(topTask?.priority); // 8;
|
|
680
|
+
* console.log(topTask?.name); // 'Alert';
|
|
681
|
+
*/
|
|
537
682
|
poll() {
|
|
538
683
|
if (this.elements.length === 0) return;
|
|
539
684
|
const value = this.elements[0];
|
|
@@ -545,26 +690,125 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
545
690
|
return value;
|
|
546
691
|
}
|
|
547
692
|
/**
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
693
|
+
* Get the current top element without removing it.
|
|
694
|
+
* @remarks Time O(1), Space O(1)
|
|
695
|
+
* @returns Top element or undefined.
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
|
|
707
|
+
* @example
|
|
708
|
+
* // Heap for event processing with priority
|
|
709
|
+
* interface Event {
|
|
710
|
+
* id: number;
|
|
711
|
+
* type: 'critical' | 'warning' | 'info';
|
|
712
|
+
* timestamp: number;
|
|
713
|
+
* message: string;
|
|
714
|
+
* }
|
|
715
|
+
*
|
|
716
|
+
* // Custom priority: critical > warning > info
|
|
717
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
718
|
+
*
|
|
719
|
+
* const eventHeap = new Heap<Event>([], {
|
|
720
|
+
* comparator: (a: Event, b: Event) => {
|
|
721
|
+
* const priorityA = priorityMap[a.type];
|
|
722
|
+
* const priorityB = priorityMap[b.type];
|
|
723
|
+
* return priorityB - priorityA; // Higher priority first
|
|
724
|
+
* }
|
|
725
|
+
* });
|
|
726
|
+
*
|
|
727
|
+
* // Add events in random order
|
|
728
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
729
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
730
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
731
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
732
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
733
|
+
*
|
|
734
|
+
* console.log(eventHeap.size); // 5;
|
|
735
|
+
*
|
|
736
|
+
* // Process events by priority (critical first)
|
|
737
|
+
* const processedOrder: Event[] = [];
|
|
738
|
+
* while (eventHeap.size > 0) {
|
|
739
|
+
* const event = eventHeap.poll();
|
|
740
|
+
* if (event) {
|
|
741
|
+
* processedOrder.push(event);
|
|
742
|
+
* }
|
|
743
|
+
* }
|
|
744
|
+
*
|
|
745
|
+
* // Verify critical events came first
|
|
746
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
747
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
748
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
749
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
750
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
751
|
+
*
|
|
752
|
+
* // Verify O(log n) operations
|
|
753
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
754
|
+
*
|
|
755
|
+
* // Add - O(log n)
|
|
756
|
+
* newHeap.add(2);
|
|
757
|
+
* console.log(newHeap.size); // 5;
|
|
758
|
+
*
|
|
759
|
+
* // Poll - O(log n)
|
|
760
|
+
* const removed = newHeap.poll();
|
|
761
|
+
* console.log(removed); // 1;
|
|
762
|
+
*
|
|
763
|
+
* // Peek - O(1)
|
|
764
|
+
* const top = newHeap.peek();
|
|
765
|
+
* console.log(top); // 2;
|
|
766
|
+
*/
|
|
552
767
|
peek() {
|
|
553
768
|
return this.elements[0];
|
|
554
769
|
}
|
|
555
770
|
/**
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
771
|
+
* Check whether the heap is empty.
|
|
772
|
+
* @remarks Time O(1), Space O(1)
|
|
773
|
+
* @returns True if size is 0.
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
* @example
|
|
784
|
+
* // Check if heap is empty
|
|
785
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
786
|
+
* console.log(heap.isEmpty()); // true;
|
|
787
|
+
* heap.add(1);
|
|
788
|
+
* console.log(heap.isEmpty()); // false;
|
|
789
|
+
*/
|
|
560
790
|
isEmpty() {
|
|
561
791
|
return this.size === 0;
|
|
562
792
|
}
|
|
563
793
|
/**
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
794
|
+
* Remove all elements.
|
|
795
|
+
* @remarks Time O(1), Space O(1)
|
|
796
|
+
* @returns void
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
* @example
|
|
807
|
+
* // Remove all elements
|
|
808
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
809
|
+
* heap.clear();
|
|
810
|
+
* console.log(heap.isEmpty()); // true;
|
|
811
|
+
*/
|
|
568
812
|
clear() {
|
|
569
813
|
this._elements = [];
|
|
570
814
|
}
|
|
@@ -579,21 +823,41 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
579
823
|
return this.fix();
|
|
580
824
|
}
|
|
581
825
|
/**
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
826
|
+
* Check if an equal element exists in the heap.
|
|
827
|
+
* @remarks Time O(N), Space O(1)
|
|
828
|
+
* @param element - Element to search for.
|
|
829
|
+
* @returns True if found.
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
* @example
|
|
833
|
+
* // Check element existence
|
|
834
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
835
|
+
* console.log(heap.has(1)); // true;
|
|
836
|
+
* console.log(heap.has(99)); // false;
|
|
837
|
+
*/
|
|
587
838
|
has(element) {
|
|
588
839
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
589
840
|
return false;
|
|
590
841
|
}
|
|
591
842
|
/**
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
843
|
+
* Delete one occurrence of an element.
|
|
844
|
+
* @remarks Time O(N), Space O(1)
|
|
845
|
+
* @param element - Element to delete.
|
|
846
|
+
* @returns True if an element was removed.
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
* @example
|
|
856
|
+
* // Remove specific element
|
|
857
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
858
|
+
* heap.delete(4);
|
|
859
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
860
|
+
*/
|
|
597
861
|
delete(element) {
|
|
598
862
|
let index = -1;
|
|
599
863
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -651,11 +915,18 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
651
915
|
return this;
|
|
652
916
|
}
|
|
653
917
|
/**
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
918
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
919
|
+
* @remarks Time O(N), Space O(H)
|
|
920
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
921
|
+
* @returns Array of visited elements.
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
* @example
|
|
925
|
+
* // Depth-first traversal
|
|
926
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
927
|
+
* const result = heap.dfs('IN');
|
|
928
|
+
* console.log(result.length); // 3;
|
|
929
|
+
*/
|
|
659
930
|
dfs(order = "PRE") {
|
|
660
931
|
const result = [];
|
|
661
932
|
const _dfs = /* @__PURE__ */ __name((index) => {
|
|
@@ -692,10 +963,26 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
692
963
|
return results;
|
|
693
964
|
}
|
|
694
965
|
/**
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
966
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
967
|
+
* @remarks Time O(N log N), Space O(N)
|
|
968
|
+
* @returns Sorted array of elements.
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
* @example
|
|
981
|
+
* // Sort elements using heap
|
|
982
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
983
|
+
* const sorted = heap.sort();
|
|
984
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
985
|
+
*/
|
|
699
986
|
sort() {
|
|
700
987
|
const visited = [];
|
|
701
988
|
const cloned = this._createInstance();
|
|
@@ -707,22 +994,52 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
707
994
|
return visited;
|
|
708
995
|
}
|
|
709
996
|
/**
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
997
|
+
* Deep clone this heap.
|
|
998
|
+
* @remarks Time O(N), Space O(N)
|
|
999
|
+
* @returns A new heap with the same elements.
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
* @example
|
|
1010
|
+
* // Create independent copy
|
|
1011
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
1012
|
+
* const copy = heap.clone();
|
|
1013
|
+
* copy.poll();
|
|
1014
|
+
* console.log(heap.size); // 3;
|
|
1015
|
+
* console.log(copy.size); // 2;
|
|
1016
|
+
*/
|
|
714
1017
|
clone() {
|
|
715
1018
|
const next = this._createInstance();
|
|
716
1019
|
for (const x of this.elements) next.add(x);
|
|
717
1020
|
return next;
|
|
718
1021
|
}
|
|
719
1022
|
/**
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
1023
|
+
* Filter elements into a new heap of the same class.
|
|
1024
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1025
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
1026
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1027
|
+
* @returns A new heap with the kept elements.
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
* @example
|
|
1038
|
+
* // Filter elements
|
|
1039
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
1040
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
1041
|
+
* console.log(evens.size); // 2;
|
|
1042
|
+
*/
|
|
726
1043
|
filter(callback, thisArg) {
|
|
727
1044
|
const out = this._createInstance();
|
|
728
1045
|
let i = 0;
|
|
@@ -736,18 +1053,31 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
736
1053
|
return out;
|
|
737
1054
|
}
|
|
738
1055
|
/**
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
1056
|
+
* Map elements into a new heap of possibly different element type.
|
|
1057
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1058
|
+
* @template EM
|
|
1059
|
+
* @template RM
|
|
1060
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
1061
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
1062
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1063
|
+
* @returns A new heap with mapped elements.
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
* @example
|
|
1073
|
+
* // Transform elements
|
|
1074
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1075
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
1076
|
+
* console.log(doubled.peek()); // 2;
|
|
1077
|
+
*/
|
|
748
1078
|
map(callback, options, thisArg) {
|
|
749
1079
|
const { comparator, toElementFn, ...rest } = options ?? {};
|
|
750
|
-
if (!comparator) throw new TypeError("Heap.map
|
|
1080
|
+
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
751
1081
|
const out = this._createLike([], { ...rest, comparator, toElementFn });
|
|
752
1082
|
let i = 0;
|
|
753
1083
|
for (const x of this) {
|
|
@@ -774,7 +1104,7 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
774
1104
|
}
|
|
775
1105
|
_DEFAULT_COMPARATOR = /* @__PURE__ */ __name((a, b) => {
|
|
776
1106
|
if (typeof a === "object" || typeof b === "object") {
|
|
777
|
-
throw TypeError(
|
|
1107
|
+
throw new TypeError(ERR.comparatorRequired("Heap"));
|
|
778
1108
|
}
|
|
779
1109
|
if (a > b) return 1;
|
|
780
1110
|
if (a < b) return -1;
|
|
@@ -1107,18 +1437,52 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1107
1437
|
this._autoCompactRatio = value;
|
|
1108
1438
|
}
|
|
1109
1439
|
/**
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1440
|
+
* Get the number of elements currently in the queue.
|
|
1441
|
+
* @remarks Time O(1), Space O(1)
|
|
1442
|
+
* @returns Current length.
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
|
|
1453
|
+
|
|
1454
|
+
* @example
|
|
1455
|
+
* // Track queue length
|
|
1456
|
+
* const q = new Queue<number>();
|
|
1457
|
+
* console.log(q.length); // 0;
|
|
1458
|
+
* q.push(1);
|
|
1459
|
+
* q.push(2);
|
|
1460
|
+
* console.log(q.length); // 2;
|
|
1461
|
+
*/
|
|
1114
1462
|
get length() {
|
|
1115
1463
|
return this.elements.length - this._offset;
|
|
1116
1464
|
}
|
|
1117
1465
|
/**
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1466
|
+
* Get the first element (front) without removing it.
|
|
1467
|
+
* @remarks Time O(1), Space O(1)
|
|
1468
|
+
* @returns Front element or undefined.
|
|
1469
|
+
|
|
1470
|
+
|
|
1471
|
+
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
|
|
1478
|
+
|
|
1479
|
+
|
|
1480
|
+
* @example
|
|
1481
|
+
* // View the front element
|
|
1482
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
1483
|
+
* console.log(q.first); // 'first';
|
|
1484
|
+
* console.log(q.length); // 3;
|
|
1485
|
+
*/
|
|
1122
1486
|
get first() {
|
|
1123
1487
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
1124
1488
|
}
|
|
@@ -1141,19 +1505,69 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1141
1505
|
return new _Queue(elements);
|
|
1142
1506
|
}
|
|
1143
1507
|
/**
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1508
|
+
* Check whether the queue is empty.
|
|
1509
|
+
* @remarks Time O(1), Space O(1)
|
|
1510
|
+
* @returns True if length is 0.
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
|
|
1514
|
+
|
|
1515
|
+
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
|
|
1519
|
+
|
|
1520
|
+
|
|
1521
|
+
|
|
1522
|
+
* @example
|
|
1523
|
+
* // Queue for...of iteration and isEmpty check
|
|
1524
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
1525
|
+
*
|
|
1526
|
+
* const elements: string[] = [];
|
|
1527
|
+
* for (const item of queue) {
|
|
1528
|
+
* elements.push(item);
|
|
1529
|
+
* }
|
|
1530
|
+
*
|
|
1531
|
+
* // Verify all elements are iterated in order
|
|
1532
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
1533
|
+
*
|
|
1534
|
+
* // Process all elements
|
|
1535
|
+
* while (queue.length > 0) {
|
|
1536
|
+
* queue.shift();
|
|
1537
|
+
* }
|
|
1538
|
+
*
|
|
1539
|
+
* console.log(queue.length); // 0;
|
|
1540
|
+
*/
|
|
1148
1541
|
isEmpty() {
|
|
1149
1542
|
return this.length === 0;
|
|
1150
1543
|
}
|
|
1151
1544
|
/**
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1545
|
+
* Enqueue one element at the back.
|
|
1546
|
+
* @remarks Time O(1), Space O(1)
|
|
1547
|
+
* @param element - Element to enqueue.
|
|
1548
|
+
* @returns True on success.
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
|
|
1559
|
+
|
|
1560
|
+
* @example
|
|
1561
|
+
* // basic Queue creation and push operation
|
|
1562
|
+
* // Create a simple Queue with initial values
|
|
1563
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
1564
|
+
*
|
|
1565
|
+
* // Verify the queue maintains insertion order
|
|
1566
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
1567
|
+
*
|
|
1568
|
+
* // Check length
|
|
1569
|
+
* console.log(queue.length); // 5;
|
|
1570
|
+
*/
|
|
1157
1571
|
push(element) {
|
|
1158
1572
|
this.elements.push(element);
|
|
1159
1573
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -1174,10 +1588,35 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1174
1588
|
return ans;
|
|
1175
1589
|
}
|
|
1176
1590
|
/**
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1591
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1592
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1593
|
+
* @returns Removed element or undefined.
|
|
1594
|
+
|
|
1595
|
+
|
|
1596
|
+
|
|
1597
|
+
|
|
1598
|
+
|
|
1599
|
+
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
|
|
1603
|
+
|
|
1604
|
+
|
|
1605
|
+
* @example
|
|
1606
|
+
* // Queue shift and peek operations
|
|
1607
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
1608
|
+
*
|
|
1609
|
+
* // Peek at the front element without removing it
|
|
1610
|
+
* console.log(queue.first); // 10;
|
|
1611
|
+
*
|
|
1612
|
+
* // Remove and get the first element (FIFO)
|
|
1613
|
+
* const first = queue.shift();
|
|
1614
|
+
* console.log(first); // 10;
|
|
1615
|
+
*
|
|
1616
|
+
* // Verify remaining elements and length decreased
|
|
1617
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
1618
|
+
* console.log(queue.length); // 3;
|
|
1619
|
+
*/
|
|
1181
1620
|
shift() {
|
|
1182
1621
|
if (this.length === 0) return void 0;
|
|
1183
1622
|
const first = this.first;
|
|
@@ -1186,11 +1625,24 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1186
1625
|
return first;
|
|
1187
1626
|
}
|
|
1188
1627
|
/**
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1628
|
+
* Delete the first occurrence of a specific element.
|
|
1629
|
+
* @remarks Time O(N), Space O(1)
|
|
1630
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
1631
|
+
* @returns True if an element was removed.
|
|
1632
|
+
|
|
1633
|
+
|
|
1634
|
+
|
|
1635
|
+
|
|
1636
|
+
|
|
1637
|
+
|
|
1638
|
+
|
|
1639
|
+
|
|
1640
|
+
* @example
|
|
1641
|
+
* // Remove specific element
|
|
1642
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
1643
|
+
* q.delete(2);
|
|
1644
|
+
* console.log(q.length); // 3;
|
|
1645
|
+
*/
|
|
1194
1646
|
delete(element) {
|
|
1195
1647
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
1196
1648
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -1201,11 +1653,24 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1201
1653
|
return false;
|
|
1202
1654
|
}
|
|
1203
1655
|
/**
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1656
|
+
* Get the element at a given logical index.
|
|
1657
|
+
* @remarks Time O(1), Space O(1)
|
|
1658
|
+
* @param index - Zero-based index from the front.
|
|
1659
|
+
* @returns Element or undefined.
|
|
1660
|
+
|
|
1661
|
+
|
|
1662
|
+
|
|
1663
|
+
|
|
1664
|
+
|
|
1665
|
+
|
|
1666
|
+
|
|
1667
|
+
|
|
1668
|
+
* @example
|
|
1669
|
+
* // Access element by index
|
|
1670
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
1671
|
+
* console.log(q.at(0)); // 'a';
|
|
1672
|
+
* console.log(q.at(2)); // 'c';
|
|
1673
|
+
*/
|
|
1209
1674
|
at(index) {
|
|
1210
1675
|
if (index < 0 || index >= this.length) return void 0;
|
|
1211
1676
|
return this._elements[this._offset + index];
|
|
@@ -1257,19 +1722,48 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1257
1722
|
return this;
|
|
1258
1723
|
}
|
|
1259
1724
|
/**
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1725
|
+
* Remove all elements and reset offset.
|
|
1726
|
+
* @remarks Time O(1), Space O(1)
|
|
1727
|
+
* @returns void
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
|
|
1731
|
+
|
|
1732
|
+
|
|
1733
|
+
|
|
1734
|
+
|
|
1735
|
+
|
|
1736
|
+
|
|
1737
|
+
* @example
|
|
1738
|
+
* // Remove all elements
|
|
1739
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1740
|
+
* q.clear();
|
|
1741
|
+
* console.log(q.length); // 0;
|
|
1742
|
+
*/
|
|
1264
1743
|
clear() {
|
|
1265
1744
|
this._elements = [];
|
|
1266
1745
|
this._offset = 0;
|
|
1267
1746
|
}
|
|
1268
1747
|
/**
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1748
|
+
* Compact storage by discarding consumed head elements.
|
|
1749
|
+
* @remarks Time O(N), Space O(N)
|
|
1750
|
+
* @returns True when compaction performed.
|
|
1751
|
+
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
|
|
1758
|
+
|
|
1759
|
+
* @example
|
|
1760
|
+
* // Reclaim unused memory
|
|
1761
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1762
|
+
* q.shift();
|
|
1763
|
+
* q.shift();
|
|
1764
|
+
* q.compact();
|
|
1765
|
+
* console.log(q.length); // 3;
|
|
1766
|
+
*/
|
|
1273
1767
|
compact() {
|
|
1274
1768
|
this._elements = this.elements.slice(this._offset);
|
|
1275
1769
|
this._offset = 0;
|
|
@@ -1295,10 +1789,26 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1295
1789
|
return removed;
|
|
1296
1790
|
}
|
|
1297
1791
|
/**
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1792
|
+
* Deep clone this queue and its parameters.
|
|
1793
|
+
* @remarks Time O(N), Space O(N)
|
|
1794
|
+
* @returns A new queue with the same content and options.
|
|
1795
|
+
|
|
1796
|
+
|
|
1797
|
+
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
|
|
1801
|
+
|
|
1802
|
+
|
|
1803
|
+
|
|
1804
|
+
* @example
|
|
1805
|
+
* // Create independent copy
|
|
1806
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1807
|
+
* const copy = q.clone();
|
|
1808
|
+
* copy.shift();
|
|
1809
|
+
* console.log(q.length); // 3;
|
|
1810
|
+
* console.log(copy.length); // 2;
|
|
1811
|
+
*/
|
|
1302
1812
|
clone() {
|
|
1303
1813
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1304
1814
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1306,12 +1816,26 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1306
1816
|
return out;
|
|
1307
1817
|
}
|
|
1308
1818
|
/**
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1819
|
+
* Filter elements into a new queue of the same class.
|
|
1820
|
+
* @remarks Time O(N), Space O(N)
|
|
1821
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
1822
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
1823
|
+
* @returns A new queue with kept elements.
|
|
1824
|
+
|
|
1825
|
+
|
|
1826
|
+
|
|
1827
|
+
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
|
|
1831
|
+
|
|
1832
|
+
|
|
1833
|
+
* @example
|
|
1834
|
+
* // Filter elements
|
|
1835
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1836
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
1837
|
+
* console.log(evens.length); // 2;
|
|
1838
|
+
*/
|
|
1315
1839
|
filter(predicate, thisArg) {
|
|
1316
1840
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1317
1841
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1323,15 +1847,28 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1323
1847
|
return out;
|
|
1324
1848
|
}
|
|
1325
1849
|
/**
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1850
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
1851
|
+
* @remarks Time O(N), Space O(N)
|
|
1852
|
+
* @template EM
|
|
1853
|
+
* @template RM
|
|
1854
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
1855
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
1856
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1857
|
+
* @returns A new Queue with mapped elements.
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
|
|
1861
|
+
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
* @example
|
|
1867
|
+
* // Transform elements
|
|
1868
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1869
|
+
* const doubled = q.map(x => x * 2);
|
|
1870
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
1871
|
+
*/
|
|
1335
1872
|
map(callback, options, thisArg) {
|
|
1336
1873
|
const out = new this.constructor([], {
|
|
1337
1874
|
toElementFn: options?.toElementFn,
|
|
@@ -1561,7 +2098,7 @@ var AbstractGraph = class extends IterableEntryBase {
|
|
|
1561
2098
|
const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
|
|
1562
2099
|
return this._addEdge(newEdge);
|
|
1563
2100
|
} else {
|
|
1564
|
-
throw new
|
|
2101
|
+
throw new TypeError(ERR.invalidArgument("dest must be a Vertex or vertex key when srcOrEdge is an Edge.", "Graph"));
|
|
1565
2102
|
}
|
|
1566
2103
|
}
|
|
1567
2104
|
}
|
|
@@ -2241,6 +2778,92 @@ var AbstractGraph = class extends IterableEntryBase {
|
|
|
2241
2778
|
_getVertexKey(vertexOrKey) {
|
|
2242
2779
|
return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
|
|
2243
2780
|
}
|
|
2781
|
+
/**
|
|
2782
|
+
* The edge connector string used in visual output.
|
|
2783
|
+
* Override in subclasses (e.g., '--' for undirected, '->' for directed).
|
|
2784
|
+
*/
|
|
2785
|
+
get _edgeConnector() {
|
|
2786
|
+
return "--";
|
|
2787
|
+
}
|
|
2788
|
+
/**
|
|
2789
|
+
* Generate a text-based visual representation of the graph.
|
|
2790
|
+
*
|
|
2791
|
+
* **Adjacency list format:**
|
|
2792
|
+
* ```
|
|
2793
|
+
* Graph (5 vertices, 6 edges):
|
|
2794
|
+
* A -> B (1), C (2)
|
|
2795
|
+
* B -> D (3)
|
|
2796
|
+
* C -> (no outgoing edges)
|
|
2797
|
+
* D -> A (1)
|
|
2798
|
+
* E (isolated)
|
|
2799
|
+
* ```
|
|
2800
|
+
*
|
|
2801
|
+
* @param options - Optional display settings.
|
|
2802
|
+
* @param options.showWeight - Whether to show edge weights (default: true).
|
|
2803
|
+
* @returns The visual string.
|
|
2804
|
+
*/
|
|
2805
|
+
toVisual(options) {
|
|
2806
|
+
const showWeight = options?.showWeight ?? true;
|
|
2807
|
+
const vertices = [...this._vertexMap.values()];
|
|
2808
|
+
const vertexCount = vertices.length;
|
|
2809
|
+
const edgeCount = this.edgeSet().length;
|
|
2810
|
+
const lines = [`Graph (${vertexCount} vertices, ${edgeCount} edges):`];
|
|
2811
|
+
for (const vertex of vertices) {
|
|
2812
|
+
const neighbors = this.getNeighbors(vertex);
|
|
2813
|
+
if (neighbors.length === 0) {
|
|
2814
|
+
lines.push(` ${vertex.key} (isolated)`);
|
|
2815
|
+
} else {
|
|
2816
|
+
const edgeStrs = neighbors.map((neighbor) => {
|
|
2817
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
2818
|
+
if (edge && showWeight && edge.weight !== void 0 && edge.weight !== 1) {
|
|
2819
|
+
return `${neighbor.key} (${edge.weight})`;
|
|
2820
|
+
}
|
|
2821
|
+
return `${neighbor.key}`;
|
|
2822
|
+
});
|
|
2823
|
+
lines.push(` ${vertex.key} ${this._edgeConnector} ${edgeStrs.join(", ")}`);
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
return lines.join("\n");
|
|
2827
|
+
}
|
|
2828
|
+
/**
|
|
2829
|
+
* Generate DOT language representation for Graphviz.
|
|
2830
|
+
*
|
|
2831
|
+
* @param options - Optional display settings.
|
|
2832
|
+
* @param options.name - Graph name (default: 'G').
|
|
2833
|
+
* @param options.showWeight - Whether to label edges with weight (default: true).
|
|
2834
|
+
* @returns DOT format string.
|
|
2835
|
+
*/
|
|
2836
|
+
toDot(options) {
|
|
2837
|
+
const name = options?.name ?? "G";
|
|
2838
|
+
const showWeight = options?.showWeight ?? true;
|
|
2839
|
+
const isDirected = this._edgeConnector === "->";
|
|
2840
|
+
const graphType = isDirected ? "digraph" : "graph";
|
|
2841
|
+
const edgeOp = isDirected ? "->" : "--";
|
|
2842
|
+
const lines = [`${graphType} ${name} {`];
|
|
2843
|
+
for (const vertex of this._vertexMap.values()) {
|
|
2844
|
+
lines.push(` "${vertex.key}";`);
|
|
2845
|
+
}
|
|
2846
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2847
|
+
for (const vertex of this._vertexMap.values()) {
|
|
2848
|
+
for (const neighbor of this.getNeighbors(vertex)) {
|
|
2849
|
+
const edgeId = isDirected ? `${vertex.key}->${neighbor.key}` : [vertex.key, neighbor.key].sort().join("--");
|
|
2850
|
+
if (visited.has(edgeId)) continue;
|
|
2851
|
+
visited.add(edgeId);
|
|
2852
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
2853
|
+
const label = edge && showWeight && edge.weight !== void 0 && edge.weight !== 1 ? ` [label="${edge.weight}"]` : "";
|
|
2854
|
+
lines.push(` "${vertex.key}" ${edgeOp} "${neighbor.key}"${label};`);
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
lines.push("}");
|
|
2858
|
+
return lines.join("\n");
|
|
2859
|
+
}
|
|
2860
|
+
/**
|
|
2861
|
+
* Print the graph to console.
|
|
2862
|
+
* @param options - Display settings passed to `toVisual`.
|
|
2863
|
+
*/
|
|
2864
|
+
print(options) {
|
|
2865
|
+
console.log(this.toVisual(options));
|
|
2866
|
+
}
|
|
2244
2867
|
};
|
|
2245
2868
|
|
|
2246
2869
|
// src/data-structures/graph/directed-graph.ts
|
|
@@ -2276,6 +2899,9 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2276
2899
|
constructor(options) {
|
|
2277
2900
|
super(options);
|
|
2278
2901
|
}
|
|
2902
|
+
get _edgeConnector() {
|
|
2903
|
+
return "->";
|
|
2904
|
+
}
|
|
2279
2905
|
_outEdgeMap = /* @__PURE__ */ new Map();
|
|
2280
2906
|
get outEdgeMap() {
|
|
2281
2907
|
return this._outEdgeMap;
|
|
@@ -2339,12 +2965,28 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2339
2965
|
return new DirectedEdge(src, dest, weight ?? this.options.defaultEdgeWeight ?? 1, value);
|
|
2340
2966
|
}
|
|
2341
2967
|
/**
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2968
|
+
* Get the unique edge from `src` to `dest`, if present.
|
|
2969
|
+
* @param srcOrKey - Source vertex or key.
|
|
2970
|
+
* @param destOrKey - Destination vertex or key.
|
|
2971
|
+
* @returns Edge instance or `undefined`.
|
|
2972
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
2973
|
+
|
|
2974
|
+
|
|
2975
|
+
|
|
2976
|
+
|
|
2977
|
+
|
|
2978
|
+
|
|
2979
|
+
|
|
2980
|
+
|
|
2981
|
+
* @example
|
|
2982
|
+
* // Get edge between vertices
|
|
2983
|
+
* const g = new DirectedGraph();
|
|
2984
|
+
* g.addVertex('A');
|
|
2985
|
+
* g.addVertex('B');
|
|
2986
|
+
* g.addEdge('A', 'B', 5);
|
|
2987
|
+
* const edge = g.getEdge('A', 'B');
|
|
2988
|
+
* console.log(edge?.weight); // 5;
|
|
2989
|
+
*/
|
|
2348
2990
|
getEdge(srcOrKey, destOrKey) {
|
|
2349
2991
|
let edgeMap = [];
|
|
2350
2992
|
if (srcOrKey !== void 0 && destOrKey !== void 0) {
|
|
@@ -2384,12 +3026,48 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2384
3026
|
return removed;
|
|
2385
3027
|
}
|
|
2386
3028
|
/**
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
3029
|
+
* Delete an edge by instance or by `(srcKey, destKey)`.
|
|
3030
|
+
* @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
|
|
3031
|
+
* @param destVertexKey - Optional destination vertex/key when deleting by pair.
|
|
3032
|
+
* @returns Removed edge or `undefined`.
|
|
3033
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3034
|
+
|
|
3035
|
+
|
|
3036
|
+
|
|
3037
|
+
|
|
3038
|
+
|
|
3039
|
+
|
|
3040
|
+
|
|
3041
|
+
|
|
3042
|
+
|
|
3043
|
+
|
|
3044
|
+
|
|
3045
|
+
* @example
|
|
3046
|
+
* // DirectedGraph deleteEdge and vertex operations
|
|
3047
|
+
* const graph = new DirectedGraph<string>();
|
|
3048
|
+
*
|
|
3049
|
+
* // Build a small graph
|
|
3050
|
+
* graph.addVertex('X');
|
|
3051
|
+
* graph.addVertex('Y');
|
|
3052
|
+
* graph.addVertex('Z');
|
|
3053
|
+
* graph.addEdge('X', 'Y', 1);
|
|
3054
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
3055
|
+
*
|
|
3056
|
+
* // Delete an edge
|
|
3057
|
+
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
3058
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
3059
|
+
*
|
|
3060
|
+
* // Edge in other direction should not exist
|
|
3061
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
3062
|
+
*
|
|
3063
|
+
* // Other edges should remain
|
|
3064
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
3065
|
+
*
|
|
3066
|
+
* // Delete a vertex
|
|
3067
|
+
* graph.deleteVertex('Y');
|
|
3068
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
3069
|
+
* console.log(graph.size); // 2;
|
|
3070
|
+
*/
|
|
2393
3071
|
deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
|
|
2394
3072
|
let removed = void 0;
|
|
2395
3073
|
let src, dest;
|
|
@@ -2416,6 +3094,26 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2416
3094
|
}
|
|
2417
3095
|
return removed;
|
|
2418
3096
|
}
|
|
3097
|
+
/**
|
|
3098
|
+
* Remove a vertex
|
|
3099
|
+
|
|
3100
|
+
|
|
3101
|
+
|
|
3102
|
+
|
|
3103
|
+
|
|
3104
|
+
|
|
3105
|
+
|
|
3106
|
+
|
|
3107
|
+
* @example
|
|
3108
|
+
* // Remove a vertex
|
|
3109
|
+
* const g = new DirectedGraph();
|
|
3110
|
+
* g.addVertex('A');
|
|
3111
|
+
* g.addVertex('B');
|
|
3112
|
+
* g.addEdge('A', 'B');
|
|
3113
|
+
* g.deleteVertex('A');
|
|
3114
|
+
* console.log(g.hasVertex('A')); // false;
|
|
3115
|
+
* console.log(g.hasEdge('A', 'B')); // false;
|
|
3116
|
+
*/
|
|
2419
3117
|
deleteVertex(vertexOrKey) {
|
|
2420
3118
|
let vertexKey;
|
|
2421
3119
|
let vertex;
|
|
@@ -2447,11 +3145,28 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2447
3145
|
return removed;
|
|
2448
3146
|
}
|
|
2449
3147
|
/**
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
3148
|
+
* Incoming edges of a vertex.
|
|
3149
|
+
* @param vertexOrKey - Vertex or key.
|
|
3150
|
+
* @returns Array of incoming edges.
|
|
3151
|
+
* @remarks Time O(deg_in), Space O(deg_in)
|
|
3152
|
+
|
|
3153
|
+
|
|
3154
|
+
|
|
3155
|
+
|
|
3156
|
+
|
|
3157
|
+
|
|
3158
|
+
|
|
3159
|
+
|
|
3160
|
+
* @example
|
|
3161
|
+
* // Get incoming edges
|
|
3162
|
+
* const g = new DirectedGraph();
|
|
3163
|
+
* g.addVertex('A');
|
|
3164
|
+
* g.addVertex('B');
|
|
3165
|
+
* g.addVertex('C');
|
|
3166
|
+
* g.addEdge('A', 'C');
|
|
3167
|
+
* g.addEdge('B', 'C');
|
|
3168
|
+
* console.log(g.incomingEdgesOf('C').length); // 2;
|
|
3169
|
+
*/
|
|
2455
3170
|
incomingEdgesOf(vertexOrKey) {
|
|
2456
3171
|
const target = this._getVertex(vertexOrKey);
|
|
2457
3172
|
if (target) {
|
|
@@ -2460,11 +3175,28 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2460
3175
|
return [];
|
|
2461
3176
|
}
|
|
2462
3177
|
/**
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
3178
|
+
* Outgoing edges of a vertex.
|
|
3179
|
+
* @param vertexOrKey - Vertex or key.
|
|
3180
|
+
* @returns Array of outgoing edges.
|
|
3181
|
+
* @remarks Time O(deg_out), Space O(deg_out)
|
|
3182
|
+
|
|
3183
|
+
|
|
3184
|
+
|
|
3185
|
+
|
|
3186
|
+
|
|
3187
|
+
|
|
3188
|
+
|
|
3189
|
+
|
|
3190
|
+
* @example
|
|
3191
|
+
* // Get outgoing edges
|
|
3192
|
+
* const g = new DirectedGraph();
|
|
3193
|
+
* g.addVertex('A');
|
|
3194
|
+
* g.addVertex('B');
|
|
3195
|
+
* g.addVertex('C');
|
|
3196
|
+
* g.addEdge('A', 'B');
|
|
3197
|
+
* g.addEdge('A', 'C');
|
|
3198
|
+
* console.log(g.outgoingEdgesOf('A').length); // 2;
|
|
3199
|
+
*/
|
|
2468
3200
|
outgoingEdgesOf(vertexOrKey) {
|
|
2469
3201
|
const target = this._getVertex(vertexOrKey);
|
|
2470
3202
|
if (target) {
|
|
@@ -2523,11 +3255,44 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2523
3255
|
return destinations;
|
|
2524
3256
|
}
|
|
2525
3257
|
/**
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
3258
|
+
* Topological sort if DAG; returns `undefined` if a cycle exists.
|
|
3259
|
+
* @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
|
|
3260
|
+
* @returns Array of keys/vertices, or `undefined` when cycle is found.
|
|
3261
|
+
* @remarks Time O(V + E), Space O(V)
|
|
3262
|
+
|
|
3263
|
+
|
|
3264
|
+
|
|
3265
|
+
|
|
3266
|
+
|
|
3267
|
+
|
|
3268
|
+
|
|
3269
|
+
|
|
3270
|
+
|
|
3271
|
+
|
|
3272
|
+
|
|
3273
|
+
* @example
|
|
3274
|
+
* // DirectedGraph topologicalSort for task scheduling
|
|
3275
|
+
* const graph = new DirectedGraph<string>();
|
|
3276
|
+
*
|
|
3277
|
+
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
3278
|
+
* graph.addVertex('Design');
|
|
3279
|
+
* graph.addVertex('Implement');
|
|
3280
|
+
* graph.addVertex('Test');
|
|
3281
|
+
* graph.addVertex('Deploy');
|
|
3282
|
+
*
|
|
3283
|
+
* // Add dependency edges
|
|
3284
|
+
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
3285
|
+
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
3286
|
+
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
3287
|
+
*
|
|
3288
|
+
* // Topological sort gives valid execution order
|
|
3289
|
+
* const executionOrder = graph.topologicalSort();
|
|
3290
|
+
* console.log(executionOrder); // defined;
|
|
3291
|
+
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
3292
|
+
*
|
|
3293
|
+
* // All vertices should be included
|
|
3294
|
+
* console.log(executionOrder?.length); // 4;
|
|
3295
|
+
*/
|
|
2531
3296
|
topologicalSort(propertyName) {
|
|
2532
3297
|
propertyName = propertyName ?? "key";
|
|
2533
3298
|
const statusMap = /* @__PURE__ */ new Map();
|
|
@@ -2559,6 +3324,24 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2559
3324
|
if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
|
|
2560
3325
|
return sorted.reverse();
|
|
2561
3326
|
}
|
|
3327
|
+
/**
|
|
3328
|
+
* Get all edges
|
|
3329
|
+
|
|
3330
|
+
|
|
3331
|
+
|
|
3332
|
+
|
|
3333
|
+
|
|
3334
|
+
|
|
3335
|
+
|
|
3336
|
+
|
|
3337
|
+
* @example
|
|
3338
|
+
* // Get all edges
|
|
3339
|
+
* const g = new DirectedGraph();
|
|
3340
|
+
* g.addVertex('A');
|
|
3341
|
+
* g.addVertex('B');
|
|
3342
|
+
* g.addEdge('A', 'B', 3);
|
|
3343
|
+
* console.log(g.edgeSet().length); // 1;
|
|
3344
|
+
*/
|
|
2562
3345
|
edgeSet() {
|
|
2563
3346
|
let edgeMap = [];
|
|
2564
3347
|
this._outEdgeMap.forEach((outEdges) => {
|
|
@@ -2566,6 +3349,28 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2566
3349
|
});
|
|
2567
3350
|
return edgeMap;
|
|
2568
3351
|
}
|
|
3352
|
+
/**
|
|
3353
|
+
* Get outgoing neighbors
|
|
3354
|
+
|
|
3355
|
+
|
|
3356
|
+
|
|
3357
|
+
|
|
3358
|
+
|
|
3359
|
+
|
|
3360
|
+
|
|
3361
|
+
|
|
3362
|
+
|
|
3363
|
+
* @example
|
|
3364
|
+
* // Get outgoing neighbors
|
|
3365
|
+
* const g = new DirectedGraph();
|
|
3366
|
+
* g.addVertex('A');
|
|
3367
|
+
* g.addVertex('B');
|
|
3368
|
+
* g.addVertex('C');
|
|
3369
|
+
* g.addEdge('A', 'B');
|
|
3370
|
+
* g.addEdge('A', 'C');
|
|
3371
|
+
* const neighbors = g.getNeighbors('A');
|
|
3372
|
+
* console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
|
|
3373
|
+
*/
|
|
2569
3374
|
getNeighbors(vertexOrKey) {
|
|
2570
3375
|
const neighbors = [];
|
|
2571
3376
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -2623,10 +3428,31 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2623
3428
|
return super.clone();
|
|
2624
3429
|
}
|
|
2625
3430
|
/**
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
3431
|
+
* Tarjan's algorithm for strongly connected components.
|
|
3432
|
+
* @returns `{ dfnMap, lowMap, SCCs }`.
|
|
3433
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
3434
|
+
|
|
3435
|
+
|
|
3436
|
+
|
|
3437
|
+
|
|
3438
|
+
|
|
3439
|
+
|
|
3440
|
+
|
|
3441
|
+
|
|
3442
|
+
* @example
|
|
3443
|
+
* // Find strongly connected components
|
|
3444
|
+
* const g = new DirectedGraph();
|
|
3445
|
+
* g.addVertex('A');
|
|
3446
|
+
* g.addVertex('B');
|
|
3447
|
+
* g.addVertex('C');
|
|
3448
|
+
* g.addEdge('A', 'B');
|
|
3449
|
+
* g.addEdge('B', 'C');
|
|
3450
|
+
* g.addEdge('C', 'A');
|
|
3451
|
+
* const { SCCs } = g.tarjan();
|
|
3452
|
+
* // A→B→C→A forms one SCC with 3 members
|
|
3453
|
+
* const sccArrays = [...SCCs.values()];
|
|
3454
|
+
* console.log(sccArrays.some(scc => scc.length === 3)); // true;
|
|
3455
|
+
*/
|
|
2630
3456
|
tarjan() {
|
|
2631
3457
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
2632
3458
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -2684,10 +3510,29 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2684
3510
|
return this.tarjan().lowMap;
|
|
2685
3511
|
}
|
|
2686
3512
|
/**
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
3513
|
+
* Strongly connected components computed by `tarjan()`.
|
|
3514
|
+
* @returns Map from SCC id to vertices.
|
|
3515
|
+
* @remarks Time O(#SCC + V), Space O(V)
|
|
3516
|
+
|
|
3517
|
+
|
|
3518
|
+
|
|
3519
|
+
|
|
3520
|
+
|
|
3521
|
+
|
|
3522
|
+
|
|
3523
|
+
|
|
3524
|
+
* @example
|
|
3525
|
+
* // Get strongly connected components
|
|
3526
|
+
* const g = new DirectedGraph();
|
|
3527
|
+
* g.addVertex(1);
|
|
3528
|
+
* g.addVertex(2);
|
|
3529
|
+
* g.addVertex(3);
|
|
3530
|
+
* g.addEdge(1, 2);
|
|
3531
|
+
* g.addEdge(2, 3);
|
|
3532
|
+
* g.addEdge(3, 1);
|
|
3533
|
+
* const sccs = g.getSCCs(); // Map<number, VO[]>
|
|
3534
|
+
* console.log(sccs.size); // >= 1;
|
|
3535
|
+
*/
|
|
2691
3536
|
getSCCs() {
|
|
2692
3537
|
return this.tarjan().SCCs;
|
|
2693
3538
|
}
|
|
@@ -2811,12 +3656,27 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2811
3656
|
return new UndirectedEdge(v1, v2, weight ?? this.options.defaultEdgeWeight ?? 1, value);
|
|
2812
3657
|
}
|
|
2813
3658
|
/**
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
3659
|
+
* Get an undirected edge between two vertices, if present.
|
|
3660
|
+
* @param v1 - One vertex or key.
|
|
3661
|
+
* @param v2 - The other vertex or key.
|
|
3662
|
+
* @returns Edge instance or `undefined`.
|
|
3663
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3664
|
+
|
|
3665
|
+
|
|
3666
|
+
|
|
3667
|
+
|
|
3668
|
+
|
|
3669
|
+
|
|
3670
|
+
|
|
3671
|
+
|
|
3672
|
+
* @example
|
|
3673
|
+
* // Get edge between vertices
|
|
3674
|
+
* const g = new UndirectedGraph();
|
|
3675
|
+
* g.addVertex('A');
|
|
3676
|
+
* g.addVertex('B');
|
|
3677
|
+
* g.addEdge('A', 'B', 7);
|
|
3678
|
+
* console.log(g.getEdge('A', 'B')?.weight); // 7;
|
|
3679
|
+
*/
|
|
2820
3680
|
getEdge(v1, v2) {
|
|
2821
3681
|
let edgeMap = [];
|
|
2822
3682
|
if (v1 !== void 0 && v2 !== void 0) {
|
|
@@ -2853,12 +3713,50 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2853
3713
|
return removed;
|
|
2854
3714
|
}
|
|
2855
3715
|
/**
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
3716
|
+
* Delete an edge by instance or by a pair of keys.
|
|
3717
|
+
* @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
|
|
3718
|
+
* @param otherSideVertexKey - Required second endpoint when deleting by pair.
|
|
3719
|
+
* @returns Removed edge or `undefined`.
|
|
3720
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3721
|
+
|
|
3722
|
+
|
|
3723
|
+
|
|
3724
|
+
|
|
3725
|
+
|
|
3726
|
+
|
|
3727
|
+
|
|
3728
|
+
|
|
3729
|
+
|
|
3730
|
+
|
|
3731
|
+
|
|
3732
|
+
* @example
|
|
3733
|
+
* // UndirectedGraph deleteEdge and vertex operations
|
|
3734
|
+
* const graph = new UndirectedGraph<string>();
|
|
3735
|
+
*
|
|
3736
|
+
* // Build a simple undirected graph
|
|
3737
|
+
* graph.addVertex('X');
|
|
3738
|
+
* graph.addVertex('Y');
|
|
3739
|
+
* graph.addVertex('Z');
|
|
3740
|
+
* graph.addEdge('X', 'Y', 1);
|
|
3741
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
3742
|
+
* graph.addEdge('X', 'Z', 3);
|
|
3743
|
+
*
|
|
3744
|
+
* // Delete an edge
|
|
3745
|
+
* graph.deleteEdge('X', 'Y');
|
|
3746
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
3747
|
+
*
|
|
3748
|
+
* // Bidirectional deletion confirmed
|
|
3749
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
3750
|
+
*
|
|
3751
|
+
* // Other edges should remain
|
|
3752
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
3753
|
+
* console.log(graph.hasEdge('Z', 'Y')); // true;
|
|
3754
|
+
*
|
|
3755
|
+
* // Delete a vertex
|
|
3756
|
+
* graph.deleteVertex('Y');
|
|
3757
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
3758
|
+
* console.log(graph.size); // 2;
|
|
3759
|
+
*/
|
|
2862
3760
|
deleteEdge(edgeOrOneSideVertexKey, otherSideVertexKey) {
|
|
2863
3761
|
let oneSide, otherSide;
|
|
2864
3762
|
if (this.isVertexKey(edgeOrOneSideVertexKey)) {
|
|
@@ -2879,11 +3777,27 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2879
3777
|
}
|
|
2880
3778
|
}
|
|
2881
3779
|
/**
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
3780
|
+
* Delete a vertex and remove it from all neighbor lists.
|
|
3781
|
+
* @param vertexOrKey - Vertex or key.
|
|
3782
|
+
* @returns `true` if removed; otherwise `false`.
|
|
3783
|
+
* @remarks Time O(deg), Space O(1)
|
|
3784
|
+
|
|
3785
|
+
|
|
3786
|
+
|
|
3787
|
+
|
|
3788
|
+
|
|
3789
|
+
|
|
3790
|
+
|
|
3791
|
+
|
|
3792
|
+
* @example
|
|
3793
|
+
* // Remove vertex and edges
|
|
3794
|
+
* const g = new UndirectedGraph();
|
|
3795
|
+
* g.addVertex('A');
|
|
3796
|
+
* g.addVertex('B');
|
|
3797
|
+
* g.addEdge('A', 'B');
|
|
3798
|
+
* g.deleteVertex('A');
|
|
3799
|
+
* console.log(g.hasVertex('A')); // false;
|
|
3800
|
+
*/
|
|
2887
3801
|
deleteVertex(vertexOrKey) {
|
|
2888
3802
|
let vertexKey;
|
|
2889
3803
|
let vertex;
|
|
@@ -2938,10 +3852,25 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2938
3852
|
}
|
|
2939
3853
|
}
|
|
2940
3854
|
/**
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
3855
|
+
* Unique set of undirected edges across endpoints.
|
|
3856
|
+
* @returns Array of edges.
|
|
3857
|
+
* @remarks Time O(E), Space O(E)
|
|
3858
|
+
|
|
3859
|
+
|
|
3860
|
+
|
|
3861
|
+
|
|
3862
|
+
|
|
3863
|
+
|
|
3864
|
+
|
|
3865
|
+
|
|
3866
|
+
* @example
|
|
3867
|
+
* // Get all edges
|
|
3868
|
+
* const g = new UndirectedGraph();
|
|
3869
|
+
* g.addVertex('A');
|
|
3870
|
+
* g.addVertex('B');
|
|
3871
|
+
* g.addEdge('A', 'B');
|
|
3872
|
+
* console.log(g.edgeSet().length); // 1;
|
|
3873
|
+
*/
|
|
2945
3874
|
edgeSet() {
|
|
2946
3875
|
const edgeSet = /* @__PURE__ */ new Set();
|
|
2947
3876
|
this._edgeMap.forEach((edgeMap) => {
|
|
@@ -2951,6 +3880,52 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2951
3880
|
});
|
|
2952
3881
|
return [...edgeSet];
|
|
2953
3882
|
}
|
|
3883
|
+
/**
|
|
3884
|
+
* UndirectedGraph connectivity and neighbors
|
|
3885
|
+
|
|
3886
|
+
|
|
3887
|
+
|
|
3888
|
+
|
|
3889
|
+
|
|
3890
|
+
|
|
3891
|
+
|
|
3892
|
+
|
|
3893
|
+
|
|
3894
|
+
|
|
3895
|
+
|
|
3896
|
+
* @example
|
|
3897
|
+
* // UndirectedGraph connectivity and neighbors
|
|
3898
|
+
* const graph = new UndirectedGraph<string>();
|
|
3899
|
+
*
|
|
3900
|
+
* // Build a friendship network
|
|
3901
|
+
* const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
|
|
3902
|
+
* for (const person of people) {
|
|
3903
|
+
* graph.addVertex(person);
|
|
3904
|
+
* }
|
|
3905
|
+
*
|
|
3906
|
+
* // Add friendships (undirected edges)
|
|
3907
|
+
* graph.addEdge('Alice', 'Bob', 1);
|
|
3908
|
+
* graph.addEdge('Alice', 'Charlie', 1);
|
|
3909
|
+
* graph.addEdge('Bob', 'Diana', 1);
|
|
3910
|
+
* graph.addEdge('Charlie', 'Eve', 1);
|
|
3911
|
+
* graph.addEdge('Diana', 'Eve', 1);
|
|
3912
|
+
*
|
|
3913
|
+
* // Get friends of each person
|
|
3914
|
+
* const aliceFriends = graph.getNeighbors('Alice');
|
|
3915
|
+
* console.log(aliceFriends[0].key); // 'Bob';
|
|
3916
|
+
* console.log(aliceFriends[1].key); // 'Charlie';
|
|
3917
|
+
* console.log(aliceFriends.length); // 2;
|
|
3918
|
+
*
|
|
3919
|
+
* const dianaFriends = graph.getNeighbors('Diana');
|
|
3920
|
+
* console.log(dianaFriends[0].key); // 'Bob';
|
|
3921
|
+
* console.log(dianaFriends[1].key); // 'Eve';
|
|
3922
|
+
* console.log(dianaFriends.length); // 2;
|
|
3923
|
+
*
|
|
3924
|
+
* // Verify bidirectional friendship
|
|
3925
|
+
* const bobFriends = graph.getNeighbors('Bob');
|
|
3926
|
+
* console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
|
|
3927
|
+
* console.log(bobFriends[1].key); // 'Diana';
|
|
3928
|
+
*/
|
|
2954
3929
|
getNeighbors(vertexOrKey) {
|
|
2955
3930
|
const neighbors = [];
|
|
2956
3931
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -3007,10 +3982,28 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3007
3982
|
return super.clone();
|
|
3008
3983
|
}
|
|
3009
3984
|
/**
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3985
|
+
* Tarjan-based bridge and articulation point detection.
|
|
3986
|
+
* @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
|
|
3987
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
3988
|
+
|
|
3989
|
+
|
|
3990
|
+
|
|
3991
|
+
|
|
3992
|
+
|
|
3993
|
+
|
|
3994
|
+
|
|
3995
|
+
|
|
3996
|
+
* @example
|
|
3997
|
+
* // Find articulation points and bridges
|
|
3998
|
+
* const g = new UndirectedGraph();
|
|
3999
|
+
* g.addVertex('A');
|
|
4000
|
+
* g.addVertex('B');
|
|
4001
|
+
* g.addVertex('C');
|
|
4002
|
+
* g.addEdge('A', 'B');
|
|
4003
|
+
* g.addEdge('B', 'C');
|
|
4004
|
+
* const result = g.tarjan();
|
|
4005
|
+
* console.log(result); // defined;
|
|
4006
|
+
*/
|
|
3014
4007
|
tarjan() {
|
|
3015
4008
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
3016
4009
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -3058,18 +4051,152 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3058
4051
|
};
|
|
3059
4052
|
}
|
|
3060
4053
|
/**
|
|
3061
|
-
*
|
|
3062
|
-
*
|
|
3063
|
-
* @
|
|
4054
|
+
* Find biconnected components using edge-stack Tarjan variant.
|
|
4055
|
+
* A biconnected component is a maximal biconnected subgraph.
|
|
4056
|
+
* @returns Array of edge arrays, each representing a biconnected component.
|
|
4057
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
3064
4058
|
*/
|
|
4059
|
+
getBiconnectedComponents() {
|
|
4060
|
+
const dfn = /* @__PURE__ */ new Map();
|
|
4061
|
+
const low = /* @__PURE__ */ new Map();
|
|
4062
|
+
const edgeStack = [];
|
|
4063
|
+
const components = [];
|
|
4064
|
+
let time = 0;
|
|
4065
|
+
const dfs = /* @__PURE__ */ __name((vertex, parent) => {
|
|
4066
|
+
dfn.set(vertex, time);
|
|
4067
|
+
low.set(vertex, time);
|
|
4068
|
+
time++;
|
|
4069
|
+
const neighbors = this.getNeighbors(vertex);
|
|
4070
|
+
let childCount = 0;
|
|
4071
|
+
for (const neighbor of neighbors) {
|
|
4072
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
4073
|
+
if (!edge) continue;
|
|
4074
|
+
if (!dfn.has(neighbor)) {
|
|
4075
|
+
childCount++;
|
|
4076
|
+
edgeStack.push(edge);
|
|
4077
|
+
dfs(neighbor, vertex);
|
|
4078
|
+
low.set(vertex, Math.min(low.get(vertex), low.get(neighbor)));
|
|
4079
|
+
if (parent === void 0 && childCount > 1 || parent !== void 0 && low.get(neighbor) >= dfn.get(vertex)) {
|
|
4080
|
+
const component = [];
|
|
4081
|
+
let e;
|
|
4082
|
+
do {
|
|
4083
|
+
e = edgeStack.pop();
|
|
4084
|
+
if (e) component.push(e);
|
|
4085
|
+
} while (e && e !== edge);
|
|
4086
|
+
if (component.length > 0) components.push(component);
|
|
4087
|
+
}
|
|
4088
|
+
} else if (neighbor !== parent && dfn.get(neighbor) < dfn.get(vertex)) {
|
|
4089
|
+
edgeStack.push(edge);
|
|
4090
|
+
low.set(vertex, Math.min(low.get(vertex), dfn.get(neighbor)));
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
}, "dfs");
|
|
4094
|
+
for (const vertex of this.vertexMap.values()) {
|
|
4095
|
+
if (!dfn.has(vertex)) {
|
|
4096
|
+
dfs(vertex, void 0);
|
|
4097
|
+
if (edgeStack.length > 0) {
|
|
4098
|
+
components.push([...edgeStack]);
|
|
4099
|
+
edgeStack.length = 0;
|
|
4100
|
+
}
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
return components;
|
|
4104
|
+
}
|
|
4105
|
+
/**
|
|
4106
|
+
* Detect whether the graph contains a cycle.
|
|
4107
|
+
* Uses DFS with parent tracking.
|
|
4108
|
+
* @returns `true` if a cycle exists, `false` otherwise.
|
|
4109
|
+
* @remarks Time O(V + E), Space O(V)
|
|
4110
|
+
|
|
4111
|
+
|
|
4112
|
+
|
|
4113
|
+
|
|
4114
|
+
|
|
4115
|
+
|
|
4116
|
+
|
|
4117
|
+
|
|
4118
|
+
* @example
|
|
4119
|
+
* // Detect cycle
|
|
4120
|
+
* const g = new UndirectedGraph();
|
|
4121
|
+
* g.addVertex('A');
|
|
4122
|
+
* g.addVertex('B');
|
|
4123
|
+
* g.addVertex('C');
|
|
4124
|
+
* g.addEdge('A', 'B');
|
|
4125
|
+
* g.addEdge('B', 'C');
|
|
4126
|
+
* console.log(g.hasCycle()); // false;
|
|
4127
|
+
* g.addEdge('C', 'A');
|
|
4128
|
+
* console.log(g.hasCycle()); // true;
|
|
4129
|
+
*/
|
|
4130
|
+
hasCycle() {
|
|
4131
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4132
|
+
const dfs = /* @__PURE__ */ __name((vertex, parent) => {
|
|
4133
|
+
visited.add(vertex);
|
|
4134
|
+
for (const neighbor of this.getNeighbors(vertex)) {
|
|
4135
|
+
if (!visited.has(neighbor)) {
|
|
4136
|
+
if (dfs(neighbor, vertex)) return true;
|
|
4137
|
+
} else if (neighbor !== parent) {
|
|
4138
|
+
return true;
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
return false;
|
|
4142
|
+
}, "dfs");
|
|
4143
|
+
for (const vertex of this.vertexMap.values()) {
|
|
4144
|
+
if (!visited.has(vertex)) {
|
|
4145
|
+
if (dfs(vertex, void 0)) return true;
|
|
4146
|
+
}
|
|
4147
|
+
}
|
|
4148
|
+
return false;
|
|
4149
|
+
}
|
|
4150
|
+
/**
|
|
4151
|
+
* Get bridges discovered by `tarjan()`.
|
|
4152
|
+
* @returns Array of edges that are bridges.
|
|
4153
|
+
* @remarks Time O(B), Space O(1)
|
|
4154
|
+
|
|
4155
|
+
|
|
4156
|
+
|
|
4157
|
+
|
|
4158
|
+
|
|
4159
|
+
|
|
4160
|
+
|
|
4161
|
+
|
|
4162
|
+
* @example
|
|
4163
|
+
* // Find bridge edges
|
|
4164
|
+
* const g = new UndirectedGraph();
|
|
4165
|
+
* g.addVertex('A');
|
|
4166
|
+
* g.addVertex('B');
|
|
4167
|
+
* g.addVertex('C');
|
|
4168
|
+
* g.addEdge('A', 'B');
|
|
4169
|
+
* g.addEdge('B', 'C');
|
|
4170
|
+
* const bridges = g.getBridges();
|
|
4171
|
+
* console.log(bridges.length); // 2;
|
|
4172
|
+
*/
|
|
3065
4173
|
getBridges() {
|
|
3066
4174
|
return this.tarjan().bridges;
|
|
3067
4175
|
}
|
|
3068
4176
|
/**
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
4177
|
+
* Get articulation points discovered by `tarjan()`.
|
|
4178
|
+
* @returns Array of cut vertices.
|
|
4179
|
+
* @remarks Time O(C), Space O(1)
|
|
4180
|
+
|
|
4181
|
+
|
|
4182
|
+
|
|
4183
|
+
|
|
4184
|
+
|
|
4185
|
+
|
|
4186
|
+
|
|
4187
|
+
|
|
4188
|
+
* @example
|
|
4189
|
+
* // Find articulation points
|
|
4190
|
+
* const g = new UndirectedGraph();
|
|
4191
|
+
* g.addVertex('A');
|
|
4192
|
+
* g.addVertex('B');
|
|
4193
|
+
* g.addVertex('C');
|
|
4194
|
+
* g.addEdge('A', 'B');
|
|
4195
|
+
* g.addEdge('B', 'C');
|
|
4196
|
+
* const cuts = g.getCutVertices();
|
|
4197
|
+
* console.log(cuts.length); // 1;
|
|
4198
|
+
* console.log(cuts[0].key); // 'B';
|
|
4199
|
+
*/
|
|
3073
4200
|
getCutVertices() {
|
|
3074
4201
|
return this.tarjan().cutVertices;
|
|
3075
4202
|
}
|
|
@@ -3209,30 +4336,6 @@ var MapGraph = class _MapGraph extends DirectedGraph {
|
|
|
3209
4336
|
return new _MapGraph(oc, br);
|
|
3210
4337
|
}
|
|
3211
4338
|
};
|
|
3212
|
-
|
|
3213
|
-
// src/common/index.ts
|
|
3214
|
-
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
3215
|
-
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
3216
|
-
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
3217
|
-
return DFSOperation2;
|
|
3218
|
-
})(DFSOperation || {});
|
|
3219
|
-
var Range = class {
|
|
3220
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
3221
|
-
this.low = low;
|
|
3222
|
-
this.high = high;
|
|
3223
|
-
this.includeLow = includeLow;
|
|
3224
|
-
this.includeHigh = includeHigh;
|
|
3225
|
-
}
|
|
3226
|
-
static {
|
|
3227
|
-
__name(this, "Range");
|
|
3228
|
-
}
|
|
3229
|
-
// Determine whether a key is within the range
|
|
3230
|
-
isInRange(key, comparator) {
|
|
3231
|
-
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
3232
|
-
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
3233
|
-
return lowCheck && highCheck;
|
|
3234
|
-
}
|
|
3235
|
-
};
|
|
3236
4339
|
/**
|
|
3237
4340
|
* data-structure-typed
|
|
3238
4341
|
*
|
|
@@ -3248,6 +4351,7 @@ exports.DFSOperation = DFSOperation;
|
|
|
3248
4351
|
exports.DirectedEdge = DirectedEdge;
|
|
3249
4352
|
exports.DirectedGraph = DirectedGraph;
|
|
3250
4353
|
exports.DirectedVertex = DirectedVertex;
|
|
4354
|
+
exports.ERR = ERR;
|
|
3251
4355
|
exports.MapEdge = MapEdge;
|
|
3252
4356
|
exports.MapGraph = MapGraph;
|
|
3253
4357
|
exports.MapVertex = MapVertex;
|