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