graph-typed 2.4.5 → 2.5.1
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 +2250 -394
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +2249 -393
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +2250 -394
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +2249 -393
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
- package/dist/types/data-structures/base/linear-base.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +380 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +487 -147
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +956 -80
- package/dist/types/data-structures/binary-tree/bst.d.ts +816 -29
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +610 -31
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +326 -135
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +3781 -6
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3607 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2874 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +3528 -6
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
- package/dist/types/data-structures/graph/directed-graph.d.ts +429 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +393 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +473 -89
- package/dist/types/data-structures/heap/heap.d.ts +581 -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 +646 -47
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +596 -68
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +793 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +499 -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 +593 -71
- package/dist/types/data-structures/queue/queue.d.ts +463 -42
- package/dist/types/data-structures/stack/stack.d.ts +384 -32
- package/dist/types/data-structures/trie/trie.d.ts +470 -48
- package/dist/types/interfaces/graph.d.ts +1 -1
- package/dist/types/types/common.d.ts +2 -2
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
- package/dist/types/types/utils/validate-type.d.ts +4 -4
- package/dist/umd/graph-typed.js +2247 -391
- package/dist/umd/graph-typed.js.map +1 -1
- package/dist/umd/graph-typed.min.js +3 -3
- package/dist/umd/graph-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- package/src/data-structures/base/iterable-entry-base.ts +8 -8
- package/src/data-structures/base/linear-base.ts +3 -3
- package/src/data-structures/binary-tree/avl-tree.ts +386 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +596 -247
- package/src/data-structures/binary-tree/binary-tree.ts +956 -81
- package/src/data-structures/binary-tree/bst.ts +840 -35
- package/src/data-structures/binary-tree/red-black-tree.ts +689 -97
- package/src/data-structures/binary-tree/segment-tree.ts +498 -249
- package/src/data-structures/binary-tree/tree-map.ts +3784 -7
- package/src/data-structures/binary-tree/tree-multi-map.ts +3614 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +2874 -65
- package/src/data-structures/binary-tree/tree-set.ts +3531 -10
- package/src/data-structures/graph/abstract-graph.ts +4 -4
- package/src/data-structures/graph/directed-graph.ts +429 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +393 -59
- package/src/data-structures/hash/hash-map.ts +476 -92
- package/src/data-structures/heap/heap.ts +581 -99
- package/src/data-structures/heap/max-heap.ts +46 -0
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +646 -47
- package/src/data-structures/linked-list/singly-linked-list.ts +596 -68
- package/src/data-structures/linked-list/skip-linked-list.ts +1067 -90
- package/src/data-structures/matrix/matrix.ts +584 -12
- package/src/data-structures/priority-queue/max-priority-queue.ts +57 -0
- 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 +592 -70
- package/src/data-structures/queue/queue.ts +463 -42
- package/src/data-structures/stack/stack.ts +384 -32
- package/src/data-structures/trie/trie.ts +470 -48
- package/src/interfaces/graph.ts +1 -1
- package/src/types/common.ts +2 -2
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/heap/heap.ts +1 -0
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
- package/src/types/utils/validate-type.ts +4 -4
package/dist/cjs/index.cjs
CHANGED
|
@@ -273,7 +273,7 @@ var IterableElementBase = class {
|
|
|
273
273
|
if (options) {
|
|
274
274
|
const { toElementFn } = options;
|
|
275
275
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
276
|
-
else if (toElementFn) throw new TypeError(
|
|
276
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
/**
|
|
@@ -436,7 +436,7 @@ var IterableElementBase = class {
|
|
|
436
436
|
acc = initialValue;
|
|
437
437
|
} else {
|
|
438
438
|
const first = iter.next();
|
|
439
|
-
if (first.done) throw new TypeError(
|
|
439
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
440
440
|
acc = first.value;
|
|
441
441
|
index = 1;
|
|
442
442
|
}
|
|
@@ -478,6 +478,199 @@ var IterableElementBase = class {
|
|
|
478
478
|
}
|
|
479
479
|
};
|
|
480
480
|
|
|
481
|
+
// src/data-structures/base/linear-base.ts
|
|
482
|
+
var LinearBase = class _LinearBase extends IterableElementBase {
|
|
483
|
+
static {
|
|
484
|
+
__name(this, "LinearBase");
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Construct a linear container with runtime options.
|
|
488
|
+
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
489
|
+
* @remarks Time O(1), Space O(1)
|
|
490
|
+
*/
|
|
491
|
+
constructor(options) {
|
|
492
|
+
super(options);
|
|
493
|
+
if (options) {
|
|
494
|
+
const { maxLen } = options;
|
|
495
|
+
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
_maxLen = -1;
|
|
499
|
+
/**
|
|
500
|
+
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
501
|
+
* @returns Maximum allowed length.
|
|
502
|
+
* @remarks Time O(1), Space O(1)
|
|
503
|
+
*/
|
|
504
|
+
get maxLen() {
|
|
505
|
+
return this._maxLen;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* First index of a value from the left.
|
|
509
|
+
* @param searchElement - Value to match.
|
|
510
|
+
* @param fromIndex - Start position (supports negative index).
|
|
511
|
+
* @returns Index or `-1` if not found.
|
|
512
|
+
* @remarks Time O(n), Space O(1)
|
|
513
|
+
*/
|
|
514
|
+
indexOf(searchElement, fromIndex = 0) {
|
|
515
|
+
if (this.length === 0) return -1;
|
|
516
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
517
|
+
if (fromIndex < 0) fromIndex = 0;
|
|
518
|
+
for (let i = fromIndex; i < this.length; i++) {
|
|
519
|
+
const element = this.at(i);
|
|
520
|
+
if (element === searchElement) return i;
|
|
521
|
+
}
|
|
522
|
+
return -1;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Last index of a value from the right.
|
|
526
|
+
* @param searchElement - Value to match.
|
|
527
|
+
* @param fromIndex - Start position (supports negative index).
|
|
528
|
+
* @returns Index or `-1` if not found.
|
|
529
|
+
* @remarks Time O(n), Space O(1)
|
|
530
|
+
*/
|
|
531
|
+
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
532
|
+
if (this.length === 0) return -1;
|
|
533
|
+
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
534
|
+
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
535
|
+
for (let i = fromIndex; i >= 0; i--) {
|
|
536
|
+
const element = this.at(i);
|
|
537
|
+
if (element === searchElement) return i;
|
|
538
|
+
}
|
|
539
|
+
return -1;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Find the first index matching a predicate.
|
|
543
|
+
* @param predicate - `(element, index, self) => boolean`.
|
|
544
|
+
* @param thisArg - Optional `this` for callback.
|
|
545
|
+
* @returns Index or `-1`.
|
|
546
|
+
* @remarks Time O(n), Space O(1)
|
|
547
|
+
*/
|
|
548
|
+
findIndex(predicate, thisArg) {
|
|
549
|
+
for (let i = 0; i < this.length; i++) {
|
|
550
|
+
const item = this.at(i);
|
|
551
|
+
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
552
|
+
}
|
|
553
|
+
return -1;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Concatenate elements and/or containers.
|
|
557
|
+
* @param items - Elements or other containers.
|
|
558
|
+
* @returns New container with combined elements (`this` type).
|
|
559
|
+
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
560
|
+
*/
|
|
561
|
+
concat(...items) {
|
|
562
|
+
const newList = this.clone();
|
|
563
|
+
for (const item of items) {
|
|
564
|
+
if (item instanceof _LinearBase) {
|
|
565
|
+
newList.pushMany(item);
|
|
566
|
+
} else {
|
|
567
|
+
newList.push(item);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return newList;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* In-place stable order via array sort semantics.
|
|
574
|
+
* @param compareFn - Comparator `(a, b) => number`.
|
|
575
|
+
* @returns This container.
|
|
576
|
+
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
577
|
+
*/
|
|
578
|
+
sort(compareFn) {
|
|
579
|
+
const arr = this.toArray();
|
|
580
|
+
arr.sort(compareFn);
|
|
581
|
+
this.clear();
|
|
582
|
+
for (const item of arr) this.push(item);
|
|
583
|
+
return this;
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Remove and/or insert elements at a position (array-compatible).
|
|
587
|
+
* @param start - Start index (supports negative index).
|
|
588
|
+
* @param deleteCount - How many to remove.
|
|
589
|
+
* @param items - Elements to insert.
|
|
590
|
+
* @returns Removed elements as a new list (`this` type).
|
|
591
|
+
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
592
|
+
*/
|
|
593
|
+
splice(start, deleteCount = 0, ...items) {
|
|
594
|
+
const removedList = this._createInstance();
|
|
595
|
+
start = start < 0 ? this.length + start : start;
|
|
596
|
+
start = Math.max(0, Math.min(start, this.length));
|
|
597
|
+
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
598
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
599
|
+
const removed = this.deleteAt(start);
|
|
600
|
+
if (removed !== void 0) {
|
|
601
|
+
removedList.push(removed);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
for (let i = 0; i < items.length; i++) {
|
|
605
|
+
this.addAt(start + i, items[i]);
|
|
606
|
+
}
|
|
607
|
+
return removedList;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Join all elements into a string.
|
|
611
|
+
* @param separator - Separator string.
|
|
612
|
+
* @returns Concatenated string.
|
|
613
|
+
* @remarks Time O(n), Space O(n)
|
|
614
|
+
*/
|
|
615
|
+
join(separator = ",") {
|
|
616
|
+
return this.toArray().join(separator);
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Snapshot elements into a reversed array.
|
|
620
|
+
* @returns New reversed array.
|
|
621
|
+
* @remarks Time O(n), Space O(n)
|
|
622
|
+
*/
|
|
623
|
+
toReversedArray() {
|
|
624
|
+
const array = [];
|
|
625
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
626
|
+
array.push(this.at(i));
|
|
627
|
+
}
|
|
628
|
+
return array;
|
|
629
|
+
}
|
|
630
|
+
reduceRight(callbackfn, initialValue) {
|
|
631
|
+
let accumulator = initialValue ?? 0;
|
|
632
|
+
for (let i = this.length - 1; i >= 0; i--) {
|
|
633
|
+
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
634
|
+
}
|
|
635
|
+
return accumulator;
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Create a shallow copy of a subrange.
|
|
639
|
+
* @param start - Inclusive start (supports negative index).
|
|
640
|
+
* @param end - Exclusive end (supports negative index).
|
|
641
|
+
* @returns New list with the range (`this` type).
|
|
642
|
+
* @remarks Time O(n), Space O(n)
|
|
643
|
+
*/
|
|
644
|
+
slice(start = 0, end = this.length) {
|
|
645
|
+
start = start < 0 ? this.length + start : start;
|
|
646
|
+
end = end < 0 ? this.length + end : end;
|
|
647
|
+
const newList = this._createInstance();
|
|
648
|
+
for (let i = start; i < end; i++) {
|
|
649
|
+
newList.push(this.at(i));
|
|
650
|
+
}
|
|
651
|
+
return newList;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Fill a range with a value.
|
|
655
|
+
* @param value - Value to set.
|
|
656
|
+
* @param start - Inclusive start.
|
|
657
|
+
* @param end - Exclusive end.
|
|
658
|
+
* @returns This list.
|
|
659
|
+
* @remarks Time O(n), Space O(1)
|
|
660
|
+
*/
|
|
661
|
+
fill(value, start = 0, end = this.length) {
|
|
662
|
+
start = start < 0 ? this.length + start : start;
|
|
663
|
+
end = end < 0 ? this.length + end : end;
|
|
664
|
+
if (start < 0) start = 0;
|
|
665
|
+
if (end > this.length) end = this.length;
|
|
666
|
+
if (start >= end) return this;
|
|
667
|
+
for (let i = start; i < end; i++) {
|
|
668
|
+
this.setAt(i, value);
|
|
669
|
+
}
|
|
670
|
+
return this;
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
|
|
481
674
|
// src/data-structures/heap/heap.ts
|
|
482
675
|
var Heap = class _Heap extends IterableElementBase {
|
|
483
676
|
static {
|
|
@@ -509,10 +702,51 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
509
702
|
return this._elements;
|
|
510
703
|
}
|
|
511
704
|
/**
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
705
|
+
* Get the number of elements.
|
|
706
|
+
* @remarks Time O(1), Space O(1)
|
|
707
|
+
* @returns Heap size.
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
* @example
|
|
741
|
+
* // Track heap capacity
|
|
742
|
+
* const heap = new Heap<number>();
|
|
743
|
+
* console.log(heap.size); // 0;
|
|
744
|
+
* heap.add(10);
|
|
745
|
+
* heap.add(20);
|
|
746
|
+
* console.log(heap.size); // 2;
|
|
747
|
+
* heap.poll();
|
|
748
|
+
* console.log(heap.size); // 1;
|
|
749
|
+
*/
|
|
516
750
|
get size() {
|
|
517
751
|
return this.elements.length;
|
|
518
752
|
}
|
|
@@ -550,21 +784,103 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
550
784
|
return new _Heap(elements, options);
|
|
551
785
|
}
|
|
552
786
|
/**
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
787
|
+
* Insert an element.
|
|
788
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
789
|
+
* @param element - Element to insert.
|
|
790
|
+
* @returns True.
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
* @example
|
|
824
|
+
* // basic Heap creation and add operation
|
|
825
|
+
* // Create a min heap (default)
|
|
826
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
827
|
+
*
|
|
828
|
+
* // Verify size
|
|
829
|
+
* console.log(minHeap.size); // 6;
|
|
830
|
+
*
|
|
831
|
+
* // Add new element
|
|
832
|
+
* minHeap.add(4);
|
|
833
|
+
* console.log(minHeap.size); // 7;
|
|
834
|
+
*
|
|
835
|
+
* // Min heap property: smallest element at root
|
|
836
|
+
* const min = minHeap.peek();
|
|
837
|
+
* console.log(min); // 1;
|
|
838
|
+
*/
|
|
558
839
|
add(element) {
|
|
559
840
|
this._elements.push(element);
|
|
560
841
|
return this._bubbleUp(this.elements.length - 1);
|
|
561
842
|
}
|
|
562
843
|
/**
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
844
|
+
* Insert many elements from an iterable.
|
|
845
|
+
* @remarks Time O(N log N), Space O(1)
|
|
846
|
+
* @param elements - Iterable of elements or raw values.
|
|
847
|
+
* @returns Array of per-element success flags.
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
|
|
873
|
+
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
* @example
|
|
878
|
+
* // Add multiple elements
|
|
879
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
880
|
+
* heap.addMany([5, 3, 7, 1]);
|
|
881
|
+
* console.log(heap.peek()); // 1;
|
|
882
|
+
* console.log(heap.size); // 4;
|
|
883
|
+
*/
|
|
568
884
|
addMany(elements) {
|
|
569
885
|
const flags = [];
|
|
570
886
|
for (const el of elements) {
|
|
@@ -579,10 +895,67 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
579
895
|
return flags;
|
|
580
896
|
}
|
|
581
897
|
/**
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
898
|
+
* Remove and return the top element.
|
|
899
|
+
* @remarks Time O(log N), Space O(1)
|
|
900
|
+
* @returns Top element or undefined.
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
|
|
932
|
+
|
|
933
|
+
* @example
|
|
934
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
935
|
+
* interface Task {
|
|
936
|
+
* id: number;
|
|
937
|
+
* priority: number;
|
|
938
|
+
* name: string;
|
|
939
|
+
* }
|
|
940
|
+
*
|
|
941
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
942
|
+
* const tasks: Task[] = [
|
|
943
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
944
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
945
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
946
|
+
* ];
|
|
947
|
+
*
|
|
948
|
+
* const maxHeap = new Heap(tasks, {
|
|
949
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
950
|
+
* });
|
|
951
|
+
*
|
|
952
|
+
* console.log(maxHeap.size); // 3;
|
|
953
|
+
*
|
|
954
|
+
* // Peek returns highest priority task
|
|
955
|
+
* const topTask = maxHeap.peek();
|
|
956
|
+
* console.log(topTask?.priority); // 8;
|
|
957
|
+
* console.log(topTask?.name); // 'Alert';
|
|
958
|
+
*/
|
|
586
959
|
poll() {
|
|
587
960
|
if (this.elements.length === 0) return;
|
|
588
961
|
const value = this.elements[0];
|
|
@@ -594,26 +967,188 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
594
967
|
return value;
|
|
595
968
|
}
|
|
596
969
|
/**
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
970
|
+
* Get the current top element without removing it.
|
|
971
|
+
* @remarks Time O(1), Space O(1)
|
|
972
|
+
* @returns Top element or undefined.
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
|
|
997
|
+
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
|
|
1005
|
+
* @example
|
|
1006
|
+
* // Heap for event processing with priority
|
|
1007
|
+
* interface Event {
|
|
1008
|
+
* id: number;
|
|
1009
|
+
* type: 'critical' | 'warning' | 'info';
|
|
1010
|
+
* timestamp: number;
|
|
1011
|
+
* message: string;
|
|
1012
|
+
* }
|
|
1013
|
+
*
|
|
1014
|
+
* // Custom priority: critical > warning > info
|
|
1015
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
1016
|
+
*
|
|
1017
|
+
* const eventHeap = new Heap<Event>([], {
|
|
1018
|
+
* comparator: (a: Event, b: Event) => {
|
|
1019
|
+
* const priorityA = priorityMap[a.type];
|
|
1020
|
+
* const priorityB = priorityMap[b.type];
|
|
1021
|
+
* return priorityB - priorityA; // Higher priority first
|
|
1022
|
+
* }
|
|
1023
|
+
* });
|
|
1024
|
+
*
|
|
1025
|
+
* // Add events in random order
|
|
1026
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
1027
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
1028
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
1029
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
1030
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
1031
|
+
*
|
|
1032
|
+
* console.log(eventHeap.size); // 5;
|
|
1033
|
+
*
|
|
1034
|
+
* // Process events by priority (critical first)
|
|
1035
|
+
* const processedOrder: Event[] = [];
|
|
1036
|
+
* while (eventHeap.size > 0) {
|
|
1037
|
+
* const event = eventHeap.poll();
|
|
1038
|
+
* if (event) {
|
|
1039
|
+
* processedOrder.push(event);
|
|
1040
|
+
* }
|
|
1041
|
+
* }
|
|
1042
|
+
*
|
|
1043
|
+
* // Verify critical events came first
|
|
1044
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
1045
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
1046
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
1047
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
1048
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
1049
|
+
*
|
|
1050
|
+
* // Verify O(log n) operations
|
|
1051
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
1052
|
+
*
|
|
1053
|
+
* // Add - O(log n)
|
|
1054
|
+
* newHeap.add(2);
|
|
1055
|
+
* console.log(newHeap.size); // 5;
|
|
1056
|
+
*
|
|
1057
|
+
* // Poll - O(log n)
|
|
1058
|
+
* const removed = newHeap.poll();
|
|
1059
|
+
* console.log(removed); // 1;
|
|
1060
|
+
*
|
|
1061
|
+
* // Peek - O(1)
|
|
1062
|
+
* const top = newHeap.peek();
|
|
1063
|
+
* console.log(top); // 2;
|
|
1064
|
+
*/
|
|
601
1065
|
peek() {
|
|
602
1066
|
return this.elements[0];
|
|
603
1067
|
}
|
|
604
1068
|
/**
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
1069
|
+
* Check whether the heap is empty.
|
|
1070
|
+
* @remarks Time O(1), Space O(1)
|
|
1071
|
+
* @returns True if size is 0.
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
* @example
|
|
1103
|
+
* // Check if heap is empty
|
|
1104
|
+
* const heap = new Heap<number>([], { comparator: (a, b) => a - b });
|
|
1105
|
+
* console.log(heap.isEmpty()); // true;
|
|
1106
|
+
* heap.add(1);
|
|
1107
|
+
* console.log(heap.isEmpty()); // false;
|
|
1108
|
+
*/
|
|
609
1109
|
isEmpty() {
|
|
610
1110
|
return this.size === 0;
|
|
611
1111
|
}
|
|
612
1112
|
/**
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
1113
|
+
* Remove all elements.
|
|
1114
|
+
* @remarks Time O(1), Space O(1)
|
|
1115
|
+
* @returns void
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
* @example
|
|
1147
|
+
* // Remove all elements
|
|
1148
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1149
|
+
* heap.clear();
|
|
1150
|
+
* console.log(heap.isEmpty()); // true;
|
|
1151
|
+
*/
|
|
617
1152
|
clear() {
|
|
618
1153
|
this._elements = [];
|
|
619
1154
|
}
|
|
@@ -628,21 +1163,83 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
628
1163
|
return this.fix();
|
|
629
1164
|
}
|
|
630
1165
|
/**
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
1166
|
+
* Check if an equal element exists in the heap.
|
|
1167
|
+
* @remarks Time O(N), Space O(1)
|
|
1168
|
+
* @param element - Element to search for.
|
|
1169
|
+
* @returns True if found.
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
* @example
|
|
1194
|
+
* // Check element existence
|
|
1195
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1196
|
+
* console.log(heap.has(1)); // true;
|
|
1197
|
+
* console.log(heap.has(99)); // false;
|
|
1198
|
+
*/
|
|
636
1199
|
has(element) {
|
|
637
1200
|
for (const el of this.elements) if (this._equals(el, element)) return true;
|
|
638
1201
|
return false;
|
|
639
1202
|
}
|
|
640
1203
|
/**
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
1204
|
+
* Delete one occurrence of an element.
|
|
1205
|
+
* @remarks Time O(N), Space O(1)
|
|
1206
|
+
* @param element - Element to delete.
|
|
1207
|
+
* @returns True if an element was removed.
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
|
|
1237
|
+
* @example
|
|
1238
|
+
* // Remove specific element
|
|
1239
|
+
* const heap = new Heap<number>([3, 1, 4, 1, 5], { comparator: (a, b) => a - b });
|
|
1240
|
+
* heap.delete(4);
|
|
1241
|
+
* console.log(heap.toArray().includes(4)); // false;
|
|
1242
|
+
*/
|
|
646
1243
|
delete(element) {
|
|
647
1244
|
let index = -1;
|
|
648
1245
|
for (let i = 0; i < this.elements.length; i++) {
|
|
@@ -700,11 +1297,39 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
700
1297
|
return this;
|
|
701
1298
|
}
|
|
702
1299
|
/**
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
1300
|
+
* Traverse the binary heap as a complete binary tree and collect elements.
|
|
1301
|
+
* @remarks Time O(N), Space O(H)
|
|
1302
|
+
* @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
|
|
1303
|
+
* @returns Array of visited elements.
|
|
1304
|
+
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
* @example
|
|
1328
|
+
* // Depth-first traversal
|
|
1329
|
+
* const heap = new Heap<number>([3, 1, 2], { comparator: (a, b) => a - b });
|
|
1330
|
+
* const result = heap.dfs('IN');
|
|
1331
|
+
* console.log(result.length); // 3;
|
|
1332
|
+
*/
|
|
708
1333
|
dfs(order = "PRE") {
|
|
709
1334
|
const result = [];
|
|
710
1335
|
const _dfs = /* @__PURE__ */ __name((index) => {
|
|
@@ -741,10 +1366,47 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
741
1366
|
return results;
|
|
742
1367
|
}
|
|
743
1368
|
/**
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
1369
|
+
* Return all elements in ascending order by repeatedly polling.
|
|
1370
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1371
|
+
* @returns Sorted array of elements.
|
|
1372
|
+
|
|
1373
|
+
|
|
1374
|
+
|
|
1375
|
+
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
|
|
1382
|
+
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
|
|
1388
|
+
|
|
1389
|
+
|
|
1390
|
+
|
|
1391
|
+
|
|
1392
|
+
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
|
|
1401
|
+
|
|
1402
|
+
|
|
1403
|
+
|
|
1404
|
+
* @example
|
|
1405
|
+
* // Sort elements using heap
|
|
1406
|
+
* const heap = new Heap<number>([5, 1, 3, 2, 4]);
|
|
1407
|
+
* const sorted = heap.sort();
|
|
1408
|
+
* console.log(sorted); // [1, 2, 3, 4, 5];
|
|
1409
|
+
*/
|
|
748
1410
|
sort() {
|
|
749
1411
|
const visited = [];
|
|
750
1412
|
const cloned = this._createInstance();
|
|
@@ -756,22 +1418,94 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
756
1418
|
return visited;
|
|
757
1419
|
}
|
|
758
1420
|
/**
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
1421
|
+
* Deep clone this heap.
|
|
1422
|
+
* @remarks Time O(N), Space O(N)
|
|
1423
|
+
* @returns A new heap with the same elements.
|
|
1424
|
+
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
|
|
1452
|
+
|
|
1453
|
+
|
|
1454
|
+
* @example
|
|
1455
|
+
* // Create independent copy
|
|
1456
|
+
* const heap = new Heap<number>([3, 1, 4], { comparator: (a, b) => a - b });
|
|
1457
|
+
* const copy = heap.clone();
|
|
1458
|
+
* copy.poll();
|
|
1459
|
+
* console.log(heap.size); // 3;
|
|
1460
|
+
* console.log(copy.size); // 2;
|
|
1461
|
+
*/
|
|
763
1462
|
clone() {
|
|
764
1463
|
const next = this._createInstance();
|
|
765
1464
|
for (const x of this.elements) next.add(x);
|
|
766
1465
|
return next;
|
|
767
1466
|
}
|
|
768
1467
|
/**
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
1468
|
+
* Filter elements into a new heap of the same class.
|
|
1469
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1470
|
+
* @param callback - Predicate (element, index, heap) → boolean to keep element.
|
|
1471
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1472
|
+
* @returns A new heap with the kept elements.
|
|
1473
|
+
|
|
1474
|
+
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
|
|
1478
|
+
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
|
|
1482
|
+
|
|
1483
|
+
|
|
1484
|
+
|
|
1485
|
+
|
|
1486
|
+
|
|
1487
|
+
|
|
1488
|
+
|
|
1489
|
+
|
|
1490
|
+
|
|
1491
|
+
|
|
1492
|
+
|
|
1493
|
+
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
|
|
1497
|
+
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
|
|
1503
|
+
* @example
|
|
1504
|
+
* // Filter elements
|
|
1505
|
+
* const heap = new Heap<number>([1, 2, 3, 4, 5], { comparator: (a, b) => a - b });
|
|
1506
|
+
* const evens = heap.filter(x => x % 2 === 0);
|
|
1507
|
+
* console.log(evens.size); // 2;
|
|
1508
|
+
*/
|
|
775
1509
|
filter(callback, thisArg) {
|
|
776
1510
|
const out = this._createInstance();
|
|
777
1511
|
let i = 0;
|
|
@@ -785,15 +1519,49 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
785
1519
|
return out;
|
|
786
1520
|
}
|
|
787
1521
|
/**
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
1522
|
+
* Map elements into a new heap of possibly different element type.
|
|
1523
|
+
* @remarks Time O(N log N), Space O(N)
|
|
1524
|
+
* @template EM
|
|
1525
|
+
* @template RM
|
|
1526
|
+
* @param callback - Mapping function (element, index, heap) → newElement.
|
|
1527
|
+
* @param options - Options for the output heap, including comparator for EM.
|
|
1528
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1529
|
+
* @returns A new heap with mapped elements.
|
|
1530
|
+
|
|
1531
|
+
|
|
1532
|
+
|
|
1533
|
+
|
|
1534
|
+
|
|
1535
|
+
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
|
|
1551
|
+
|
|
1552
|
+
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
|
|
1556
|
+
|
|
1557
|
+
|
|
1558
|
+
|
|
1559
|
+
* @example
|
|
1560
|
+
* // Transform elements
|
|
1561
|
+
* const heap = new Heap<number>([1, 2, 3], { comparator: (a, b) => a - b });
|
|
1562
|
+
* const doubled = heap.map(x => x * 2, { comparator: (a, b) => a - b });
|
|
1563
|
+
* console.log(doubled.peek()); // 2;
|
|
1564
|
+
*/
|
|
797
1565
|
map(callback, options, thisArg) {
|
|
798
1566
|
const { comparator, toElementFn, ...rest } = options ?? {};
|
|
799
1567
|
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
@@ -906,199 +1674,6 @@ var Heap = class _Heap extends IterableElementBase {
|
|
|
906
1674
|
}
|
|
907
1675
|
};
|
|
908
1676
|
|
|
909
|
-
// src/data-structures/base/linear-base.ts
|
|
910
|
-
var LinearBase = class _LinearBase extends IterableElementBase {
|
|
911
|
-
static {
|
|
912
|
-
__name(this, "LinearBase");
|
|
913
|
-
}
|
|
914
|
-
/**
|
|
915
|
-
* Construct a linear container with runtime options.
|
|
916
|
-
* @param options - `{ maxLen?, ... }` bounds/behavior options.
|
|
917
|
-
* @remarks Time O(1), Space O(1)
|
|
918
|
-
*/
|
|
919
|
-
constructor(options) {
|
|
920
|
-
super(options);
|
|
921
|
-
if (options) {
|
|
922
|
-
const { maxLen } = options;
|
|
923
|
-
if (typeof maxLen === "number" && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
_maxLen = -1;
|
|
927
|
-
/**
|
|
928
|
-
* Upper bound for length (if positive), or `-1` when unbounded.
|
|
929
|
-
* @returns Maximum allowed length.
|
|
930
|
-
* @remarks Time O(1), Space O(1)
|
|
931
|
-
*/
|
|
932
|
-
get maxLen() {
|
|
933
|
-
return this._maxLen;
|
|
934
|
-
}
|
|
935
|
-
/**
|
|
936
|
-
* First index of a value from the left.
|
|
937
|
-
* @param searchElement - Value to match.
|
|
938
|
-
* @param fromIndex - Start position (supports negative index).
|
|
939
|
-
* @returns Index or `-1` if not found.
|
|
940
|
-
* @remarks Time O(n), Space O(1)
|
|
941
|
-
*/
|
|
942
|
-
indexOf(searchElement, fromIndex = 0) {
|
|
943
|
-
if (this.length === 0) return -1;
|
|
944
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
945
|
-
if (fromIndex < 0) fromIndex = 0;
|
|
946
|
-
for (let i = fromIndex; i < this.length; i++) {
|
|
947
|
-
const element = this.at(i);
|
|
948
|
-
if (element === searchElement) return i;
|
|
949
|
-
}
|
|
950
|
-
return -1;
|
|
951
|
-
}
|
|
952
|
-
/**
|
|
953
|
-
* Last index of a value from the right.
|
|
954
|
-
* @param searchElement - Value to match.
|
|
955
|
-
* @param fromIndex - Start position (supports negative index).
|
|
956
|
-
* @returns Index or `-1` if not found.
|
|
957
|
-
* @remarks Time O(n), Space O(1)
|
|
958
|
-
*/
|
|
959
|
-
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
960
|
-
if (this.length === 0) return -1;
|
|
961
|
-
if (fromIndex >= this.length) fromIndex = this.length - 1;
|
|
962
|
-
if (fromIndex < 0) fromIndex = this.length + fromIndex;
|
|
963
|
-
for (let i = fromIndex; i >= 0; i--) {
|
|
964
|
-
const element = this.at(i);
|
|
965
|
-
if (element === searchElement) return i;
|
|
966
|
-
}
|
|
967
|
-
return -1;
|
|
968
|
-
}
|
|
969
|
-
/**
|
|
970
|
-
* Find the first index matching a predicate.
|
|
971
|
-
* @param predicate - `(element, index, self) => boolean`.
|
|
972
|
-
* @param thisArg - Optional `this` for callback.
|
|
973
|
-
* @returns Index or `-1`.
|
|
974
|
-
* @remarks Time O(n), Space O(1)
|
|
975
|
-
*/
|
|
976
|
-
findIndex(predicate, thisArg) {
|
|
977
|
-
for (let i = 0; i < this.length; i++) {
|
|
978
|
-
const item = this.at(i);
|
|
979
|
-
if (item !== void 0 && predicate.call(thisArg, item, i, this)) return i;
|
|
980
|
-
}
|
|
981
|
-
return -1;
|
|
982
|
-
}
|
|
983
|
-
/**
|
|
984
|
-
* Concatenate elements and/or containers.
|
|
985
|
-
* @param items - Elements or other containers.
|
|
986
|
-
* @returns New container with combined elements (`this` type).
|
|
987
|
-
* @remarks Time O(sum(length)), Space O(sum(length))
|
|
988
|
-
*/
|
|
989
|
-
concat(...items) {
|
|
990
|
-
const newList = this.clone();
|
|
991
|
-
for (const item of items) {
|
|
992
|
-
if (item instanceof _LinearBase) {
|
|
993
|
-
newList.pushMany(item);
|
|
994
|
-
} else {
|
|
995
|
-
newList.push(item);
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
return newList;
|
|
999
|
-
}
|
|
1000
|
-
/**
|
|
1001
|
-
* In-place stable order via array sort semantics.
|
|
1002
|
-
* @param compareFn - Comparator `(a, b) => number`.
|
|
1003
|
-
* @returns This container.
|
|
1004
|
-
* @remarks Time O(n log n), Space O(n) (materializes to array temporarily)
|
|
1005
|
-
*/
|
|
1006
|
-
sort(compareFn) {
|
|
1007
|
-
const arr = this.toArray();
|
|
1008
|
-
arr.sort(compareFn);
|
|
1009
|
-
this.clear();
|
|
1010
|
-
for (const item of arr) this.push(item);
|
|
1011
|
-
return this;
|
|
1012
|
-
}
|
|
1013
|
-
/**
|
|
1014
|
-
* Remove and/or insert elements at a position (array-compatible).
|
|
1015
|
-
* @param start - Start index (supports negative index).
|
|
1016
|
-
* @param deleteCount - How many to remove.
|
|
1017
|
-
* @param items - Elements to insert.
|
|
1018
|
-
* @returns Removed elements as a new list (`this` type).
|
|
1019
|
-
* @remarks Time O(n + m), Space O(min(n, m)) where `m = items.length`
|
|
1020
|
-
*/
|
|
1021
|
-
splice(start, deleteCount = 0, ...items) {
|
|
1022
|
-
const removedList = this._createInstance();
|
|
1023
|
-
start = start < 0 ? this.length + start : start;
|
|
1024
|
-
start = Math.max(0, Math.min(start, this.length));
|
|
1025
|
-
deleteCount = Math.max(0, Math.min(deleteCount, this.length - start));
|
|
1026
|
-
for (let i = 0; i < deleteCount; i++) {
|
|
1027
|
-
const removed = this.deleteAt(start);
|
|
1028
|
-
if (removed !== void 0) {
|
|
1029
|
-
removedList.push(removed);
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
for (let i = 0; i < items.length; i++) {
|
|
1033
|
-
this.addAt(start + i, items[i]);
|
|
1034
|
-
}
|
|
1035
|
-
return removedList;
|
|
1036
|
-
}
|
|
1037
|
-
/**
|
|
1038
|
-
* Join all elements into a string.
|
|
1039
|
-
* @param separator - Separator string.
|
|
1040
|
-
* @returns Concatenated string.
|
|
1041
|
-
* @remarks Time O(n), Space O(n)
|
|
1042
|
-
*/
|
|
1043
|
-
join(separator = ",") {
|
|
1044
|
-
return this.toArray().join(separator);
|
|
1045
|
-
}
|
|
1046
|
-
/**
|
|
1047
|
-
* Snapshot elements into a reversed array.
|
|
1048
|
-
* @returns New reversed array.
|
|
1049
|
-
* @remarks Time O(n), Space O(n)
|
|
1050
|
-
*/
|
|
1051
|
-
toReversedArray() {
|
|
1052
|
-
const array = [];
|
|
1053
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1054
|
-
array.push(this.at(i));
|
|
1055
|
-
}
|
|
1056
|
-
return array;
|
|
1057
|
-
}
|
|
1058
|
-
reduceRight(callbackfn, initialValue) {
|
|
1059
|
-
let accumulator = initialValue ?? 0;
|
|
1060
|
-
for (let i = this.length - 1; i >= 0; i--) {
|
|
1061
|
-
accumulator = callbackfn(accumulator, this.at(i), i, this);
|
|
1062
|
-
}
|
|
1063
|
-
return accumulator;
|
|
1064
|
-
}
|
|
1065
|
-
/**
|
|
1066
|
-
* Create a shallow copy of a subrange.
|
|
1067
|
-
* @param start - Inclusive start (supports negative index).
|
|
1068
|
-
* @param end - Exclusive end (supports negative index).
|
|
1069
|
-
* @returns New list with the range (`this` type).
|
|
1070
|
-
* @remarks Time O(n), Space O(n)
|
|
1071
|
-
*/
|
|
1072
|
-
slice(start = 0, end = this.length) {
|
|
1073
|
-
start = start < 0 ? this.length + start : start;
|
|
1074
|
-
end = end < 0 ? this.length + end : end;
|
|
1075
|
-
const newList = this._createInstance();
|
|
1076
|
-
for (let i = start; i < end; i++) {
|
|
1077
|
-
newList.push(this.at(i));
|
|
1078
|
-
}
|
|
1079
|
-
return newList;
|
|
1080
|
-
}
|
|
1081
|
-
/**
|
|
1082
|
-
* Fill a range with a value.
|
|
1083
|
-
* @param value - Value to set.
|
|
1084
|
-
* @param start - Inclusive start.
|
|
1085
|
-
* @param end - Exclusive end.
|
|
1086
|
-
* @returns This list.
|
|
1087
|
-
* @remarks Time O(n), Space O(1)
|
|
1088
|
-
*/
|
|
1089
|
-
fill(value, start = 0, end = this.length) {
|
|
1090
|
-
start = start < 0 ? this.length + start : start;
|
|
1091
|
-
end = end < 0 ? this.length + end : end;
|
|
1092
|
-
if (start < 0) start = 0;
|
|
1093
|
-
if (end > this.length) end = this.length;
|
|
1094
|
-
if (start >= end) return this;
|
|
1095
|
-
for (let i = start; i < end; i++) {
|
|
1096
|
-
this.setAt(i, value);
|
|
1097
|
-
}
|
|
1098
|
-
return this;
|
|
1099
|
-
}
|
|
1100
|
-
};
|
|
1101
|
-
|
|
1102
1677
|
// src/data-structures/queue/queue.ts
|
|
1103
1678
|
var Queue = class _Queue extends LinearBase {
|
|
1104
1679
|
static {
|
|
@@ -1156,18 +1731,94 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1156
1731
|
this._autoCompactRatio = value;
|
|
1157
1732
|
}
|
|
1158
1733
|
/**
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1734
|
+
* Get the number of elements currently in the queue.
|
|
1735
|
+
* @remarks Time O(1), Space O(1)
|
|
1736
|
+
* @returns Current length.
|
|
1737
|
+
|
|
1738
|
+
|
|
1739
|
+
|
|
1740
|
+
|
|
1741
|
+
|
|
1742
|
+
|
|
1743
|
+
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
|
|
1747
|
+
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
|
|
1758
|
+
|
|
1759
|
+
|
|
1760
|
+
|
|
1761
|
+
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
|
|
1765
|
+
|
|
1766
|
+
|
|
1767
|
+
|
|
1768
|
+
|
|
1769
|
+
* @example
|
|
1770
|
+
* // Track queue length
|
|
1771
|
+
* const q = new Queue<number>();
|
|
1772
|
+
* console.log(q.length); // 0;
|
|
1773
|
+
* q.push(1);
|
|
1774
|
+
* q.push(2);
|
|
1775
|
+
* console.log(q.length); // 2;
|
|
1776
|
+
*/
|
|
1163
1777
|
get length() {
|
|
1164
1778
|
return this.elements.length - this._offset;
|
|
1165
1779
|
}
|
|
1166
1780
|
/**
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1781
|
+
* Get the first element (front) without removing it.
|
|
1782
|
+
* @remarks Time O(1), Space O(1)
|
|
1783
|
+
* @returns Front element or undefined.
|
|
1784
|
+
|
|
1785
|
+
|
|
1786
|
+
|
|
1787
|
+
|
|
1788
|
+
|
|
1789
|
+
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
|
|
1796
|
+
|
|
1797
|
+
|
|
1798
|
+
|
|
1799
|
+
|
|
1800
|
+
|
|
1801
|
+
|
|
1802
|
+
|
|
1803
|
+
|
|
1804
|
+
|
|
1805
|
+
|
|
1806
|
+
|
|
1807
|
+
|
|
1808
|
+
|
|
1809
|
+
|
|
1810
|
+
|
|
1811
|
+
|
|
1812
|
+
|
|
1813
|
+
|
|
1814
|
+
|
|
1815
|
+
|
|
1816
|
+
* @example
|
|
1817
|
+
* // View the front element
|
|
1818
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
1819
|
+
* console.log(q.first); // 'first';
|
|
1820
|
+
* console.log(q.length); // 3;
|
|
1821
|
+
*/
|
|
1171
1822
|
get first() {
|
|
1172
1823
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
1173
1824
|
}
|
|
@@ -1190,19 +1841,111 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1190
1841
|
return new _Queue(elements);
|
|
1191
1842
|
}
|
|
1192
1843
|
/**
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1844
|
+
* Check whether the queue is empty.
|
|
1845
|
+
* @remarks Time O(1), Space O(1)
|
|
1846
|
+
* @returns True if length is 0.
|
|
1847
|
+
|
|
1848
|
+
|
|
1849
|
+
|
|
1850
|
+
|
|
1851
|
+
|
|
1852
|
+
|
|
1853
|
+
|
|
1854
|
+
|
|
1855
|
+
|
|
1856
|
+
|
|
1857
|
+
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
|
|
1861
|
+
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
|
|
1865
|
+
|
|
1866
|
+
|
|
1867
|
+
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
|
|
1871
|
+
|
|
1872
|
+
|
|
1873
|
+
|
|
1874
|
+
|
|
1875
|
+
|
|
1876
|
+
|
|
1877
|
+
|
|
1878
|
+
|
|
1879
|
+
* @example
|
|
1880
|
+
* // Queue for...of iteration and isEmpty check
|
|
1881
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
1882
|
+
*
|
|
1883
|
+
* const elements: string[] = [];
|
|
1884
|
+
* for (const item of queue) {
|
|
1885
|
+
* elements.push(item);
|
|
1886
|
+
* }
|
|
1887
|
+
*
|
|
1888
|
+
* // Verify all elements are iterated in order
|
|
1889
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
1890
|
+
*
|
|
1891
|
+
* // Process all elements
|
|
1892
|
+
* while (queue.length > 0) {
|
|
1893
|
+
* queue.shift();
|
|
1894
|
+
* }
|
|
1895
|
+
*
|
|
1896
|
+
* console.log(queue.length); // 0;
|
|
1897
|
+
*/
|
|
1197
1898
|
isEmpty() {
|
|
1198
1899
|
return this.length === 0;
|
|
1199
1900
|
}
|
|
1200
1901
|
/**
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1902
|
+
* Enqueue one element at the back.
|
|
1903
|
+
* @remarks Time O(1), Space O(1)
|
|
1904
|
+
* @param element - Element to enqueue.
|
|
1905
|
+
* @returns True on success.
|
|
1906
|
+
|
|
1907
|
+
|
|
1908
|
+
|
|
1909
|
+
|
|
1910
|
+
|
|
1911
|
+
|
|
1912
|
+
|
|
1913
|
+
|
|
1914
|
+
|
|
1915
|
+
|
|
1916
|
+
|
|
1917
|
+
|
|
1918
|
+
|
|
1919
|
+
|
|
1920
|
+
|
|
1921
|
+
|
|
1922
|
+
|
|
1923
|
+
|
|
1924
|
+
|
|
1925
|
+
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
|
|
1933
|
+
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
|
|
1937
|
+
|
|
1938
|
+
* @example
|
|
1939
|
+
* // basic Queue creation and push operation
|
|
1940
|
+
* // Create a simple Queue with initial values
|
|
1941
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
1942
|
+
*
|
|
1943
|
+
* // Verify the queue maintains insertion order
|
|
1944
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
1945
|
+
*
|
|
1946
|
+
* // Check length
|
|
1947
|
+
* console.log(queue.length); // 5;
|
|
1948
|
+
*/
|
|
1206
1949
|
push(element) {
|
|
1207
1950
|
this.elements.push(element);
|
|
1208
1951
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -1223,10 +1966,56 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1223
1966
|
return ans;
|
|
1224
1967
|
}
|
|
1225
1968
|
/**
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1969
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1970
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1971
|
+
* @returns Removed element or undefined.
|
|
1972
|
+
|
|
1973
|
+
|
|
1974
|
+
|
|
1975
|
+
|
|
1976
|
+
|
|
1977
|
+
|
|
1978
|
+
|
|
1979
|
+
|
|
1980
|
+
|
|
1981
|
+
|
|
1982
|
+
|
|
1983
|
+
|
|
1984
|
+
|
|
1985
|
+
|
|
1986
|
+
|
|
1987
|
+
|
|
1988
|
+
|
|
1989
|
+
|
|
1990
|
+
|
|
1991
|
+
|
|
1992
|
+
|
|
1993
|
+
|
|
1994
|
+
|
|
1995
|
+
|
|
1996
|
+
|
|
1997
|
+
|
|
1998
|
+
|
|
1999
|
+
|
|
2000
|
+
|
|
2001
|
+
|
|
2002
|
+
|
|
2003
|
+
|
|
2004
|
+
* @example
|
|
2005
|
+
* // Queue shift and peek operations
|
|
2006
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
2007
|
+
*
|
|
2008
|
+
* // Peek at the front element without removing it
|
|
2009
|
+
* console.log(queue.first); // 10;
|
|
2010
|
+
*
|
|
2011
|
+
* // Remove and get the first element (FIFO)
|
|
2012
|
+
* const first = queue.shift();
|
|
2013
|
+
* console.log(first); // 10;
|
|
2014
|
+
*
|
|
2015
|
+
* // Verify remaining elements and length decreased
|
|
2016
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
2017
|
+
* console.log(queue.length); // 3;
|
|
2018
|
+
*/
|
|
1230
2019
|
shift() {
|
|
1231
2020
|
if (this.length === 0) return void 0;
|
|
1232
2021
|
const first = this.first;
|
|
@@ -1235,11 +2024,45 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1235
2024
|
return first;
|
|
1236
2025
|
}
|
|
1237
2026
|
/**
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
2027
|
+
* Delete the first occurrence of a specific element.
|
|
2028
|
+
* @remarks Time O(N), Space O(1)
|
|
2029
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
2030
|
+
* @returns True if an element was removed.
|
|
2031
|
+
|
|
2032
|
+
|
|
2033
|
+
|
|
2034
|
+
|
|
2035
|
+
|
|
2036
|
+
|
|
2037
|
+
|
|
2038
|
+
|
|
2039
|
+
|
|
2040
|
+
|
|
2041
|
+
|
|
2042
|
+
|
|
2043
|
+
|
|
2044
|
+
|
|
2045
|
+
|
|
2046
|
+
|
|
2047
|
+
|
|
2048
|
+
|
|
2049
|
+
|
|
2050
|
+
|
|
2051
|
+
|
|
2052
|
+
|
|
2053
|
+
|
|
2054
|
+
|
|
2055
|
+
|
|
2056
|
+
|
|
2057
|
+
|
|
2058
|
+
|
|
2059
|
+
|
|
2060
|
+
* @example
|
|
2061
|
+
* // Remove specific element
|
|
2062
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
2063
|
+
* q.delete(2);
|
|
2064
|
+
* console.log(q.length); // 3;
|
|
2065
|
+
*/
|
|
1243
2066
|
delete(element) {
|
|
1244
2067
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
1245
2068
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -1250,11 +2073,45 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1250
2073
|
return false;
|
|
1251
2074
|
}
|
|
1252
2075
|
/**
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
2076
|
+
* Get the element at a given logical index.
|
|
2077
|
+
* @remarks Time O(1), Space O(1)
|
|
2078
|
+
* @param index - Zero-based index from the front.
|
|
2079
|
+
* @returns Element or undefined.
|
|
2080
|
+
|
|
2081
|
+
|
|
2082
|
+
|
|
2083
|
+
|
|
2084
|
+
|
|
2085
|
+
|
|
2086
|
+
|
|
2087
|
+
|
|
2088
|
+
|
|
2089
|
+
|
|
2090
|
+
|
|
2091
|
+
|
|
2092
|
+
|
|
2093
|
+
|
|
2094
|
+
|
|
2095
|
+
|
|
2096
|
+
|
|
2097
|
+
|
|
2098
|
+
|
|
2099
|
+
|
|
2100
|
+
|
|
2101
|
+
|
|
2102
|
+
|
|
2103
|
+
|
|
2104
|
+
|
|
2105
|
+
|
|
2106
|
+
|
|
2107
|
+
|
|
2108
|
+
|
|
2109
|
+
* @example
|
|
2110
|
+
* // Access element by index
|
|
2111
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
2112
|
+
* console.log(q.at(0)); // 'a';
|
|
2113
|
+
* console.log(q.at(2)); // 'c';
|
|
2114
|
+
*/
|
|
1258
2115
|
at(index) {
|
|
1259
2116
|
if (index < 0 || index >= this.length) return void 0;
|
|
1260
2117
|
return this._elements[this._offset + index];
|
|
@@ -1306,19 +2163,90 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1306
2163
|
return this;
|
|
1307
2164
|
}
|
|
1308
2165
|
/**
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
2166
|
+
* Remove all elements and reset offset.
|
|
2167
|
+
* @remarks Time O(1), Space O(1)
|
|
2168
|
+
* @returns void
|
|
2169
|
+
|
|
2170
|
+
|
|
2171
|
+
|
|
2172
|
+
|
|
2173
|
+
|
|
2174
|
+
|
|
2175
|
+
|
|
2176
|
+
|
|
2177
|
+
|
|
2178
|
+
|
|
2179
|
+
|
|
2180
|
+
|
|
2181
|
+
|
|
2182
|
+
|
|
2183
|
+
|
|
2184
|
+
|
|
2185
|
+
|
|
2186
|
+
|
|
2187
|
+
|
|
2188
|
+
|
|
2189
|
+
|
|
2190
|
+
|
|
2191
|
+
|
|
2192
|
+
|
|
2193
|
+
|
|
2194
|
+
|
|
2195
|
+
|
|
2196
|
+
|
|
2197
|
+
|
|
2198
|
+
|
|
2199
|
+
* @example
|
|
2200
|
+
* // Remove all elements
|
|
2201
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2202
|
+
* q.clear();
|
|
2203
|
+
* console.log(q.length); // 0;
|
|
2204
|
+
*/
|
|
1313
2205
|
clear() {
|
|
1314
2206
|
this._elements = [];
|
|
1315
2207
|
this._offset = 0;
|
|
1316
2208
|
}
|
|
1317
2209
|
/**
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
2210
|
+
* Compact storage by discarding consumed head elements.
|
|
2211
|
+
* @remarks Time O(N), Space O(N)
|
|
2212
|
+
* @returns True when compaction performed.
|
|
2213
|
+
|
|
2214
|
+
|
|
2215
|
+
|
|
2216
|
+
|
|
2217
|
+
|
|
2218
|
+
|
|
2219
|
+
|
|
2220
|
+
|
|
2221
|
+
|
|
2222
|
+
|
|
2223
|
+
|
|
2224
|
+
|
|
2225
|
+
|
|
2226
|
+
|
|
2227
|
+
|
|
2228
|
+
|
|
2229
|
+
|
|
2230
|
+
|
|
2231
|
+
|
|
2232
|
+
|
|
2233
|
+
|
|
2234
|
+
|
|
2235
|
+
|
|
2236
|
+
|
|
2237
|
+
|
|
2238
|
+
|
|
2239
|
+
|
|
2240
|
+
|
|
2241
|
+
|
|
2242
|
+
* @example
|
|
2243
|
+
* // Reclaim unused memory
|
|
2244
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2245
|
+
* q.shift();
|
|
2246
|
+
* q.shift();
|
|
2247
|
+
* q.compact();
|
|
2248
|
+
* console.log(q.length); // 3;
|
|
2249
|
+
*/
|
|
1322
2250
|
compact() {
|
|
1323
2251
|
this._elements = this.elements.slice(this._offset);
|
|
1324
2252
|
this._offset = 0;
|
|
@@ -1344,10 +2272,47 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1344
2272
|
return removed;
|
|
1345
2273
|
}
|
|
1346
2274
|
/**
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
2275
|
+
* Deep clone this queue and its parameters.
|
|
2276
|
+
* @remarks Time O(N), Space O(N)
|
|
2277
|
+
* @returns A new queue with the same content and options.
|
|
2278
|
+
|
|
2279
|
+
|
|
2280
|
+
|
|
2281
|
+
|
|
2282
|
+
|
|
2283
|
+
|
|
2284
|
+
|
|
2285
|
+
|
|
2286
|
+
|
|
2287
|
+
|
|
2288
|
+
|
|
2289
|
+
|
|
2290
|
+
|
|
2291
|
+
|
|
2292
|
+
|
|
2293
|
+
|
|
2294
|
+
|
|
2295
|
+
|
|
2296
|
+
|
|
2297
|
+
|
|
2298
|
+
|
|
2299
|
+
|
|
2300
|
+
|
|
2301
|
+
|
|
2302
|
+
|
|
2303
|
+
|
|
2304
|
+
|
|
2305
|
+
|
|
2306
|
+
|
|
2307
|
+
|
|
2308
|
+
* @example
|
|
2309
|
+
* // Create independent copy
|
|
2310
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2311
|
+
* const copy = q.clone();
|
|
2312
|
+
* copy.shift();
|
|
2313
|
+
* console.log(q.length); // 3;
|
|
2314
|
+
* console.log(copy.length); // 2;
|
|
2315
|
+
*/
|
|
1351
2316
|
clone() {
|
|
1352
2317
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1353
2318
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1355,12 +2320,47 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1355
2320
|
return out;
|
|
1356
2321
|
}
|
|
1357
2322
|
/**
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
2323
|
+
* Filter elements into a new queue of the same class.
|
|
2324
|
+
* @remarks Time O(N), Space O(N)
|
|
2325
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
2326
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
2327
|
+
* @returns A new queue with kept elements.
|
|
2328
|
+
|
|
2329
|
+
|
|
2330
|
+
|
|
2331
|
+
|
|
2332
|
+
|
|
2333
|
+
|
|
2334
|
+
|
|
2335
|
+
|
|
2336
|
+
|
|
2337
|
+
|
|
2338
|
+
|
|
2339
|
+
|
|
2340
|
+
|
|
2341
|
+
|
|
2342
|
+
|
|
2343
|
+
|
|
2344
|
+
|
|
2345
|
+
|
|
2346
|
+
|
|
2347
|
+
|
|
2348
|
+
|
|
2349
|
+
|
|
2350
|
+
|
|
2351
|
+
|
|
2352
|
+
|
|
2353
|
+
|
|
2354
|
+
|
|
2355
|
+
|
|
2356
|
+
|
|
2357
|
+
|
|
2358
|
+
* @example
|
|
2359
|
+
* // Filter elements
|
|
2360
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
2361
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
2362
|
+
* console.log(evens.length); // 2;
|
|
2363
|
+
*/
|
|
1364
2364
|
filter(predicate, thisArg) {
|
|
1365
2365
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
1366
2366
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -1372,15 +2372,49 @@ var Queue = class _Queue extends LinearBase {
|
|
|
1372
2372
|
return out;
|
|
1373
2373
|
}
|
|
1374
2374
|
/**
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
2375
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
2376
|
+
* @remarks Time O(N), Space O(N)
|
|
2377
|
+
* @template EM
|
|
2378
|
+
* @template RM
|
|
2379
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
2380
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
2381
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
2382
|
+
* @returns A new Queue with mapped elements.
|
|
2383
|
+
|
|
2384
|
+
|
|
2385
|
+
|
|
2386
|
+
|
|
2387
|
+
|
|
2388
|
+
|
|
2389
|
+
|
|
2390
|
+
|
|
2391
|
+
|
|
2392
|
+
|
|
2393
|
+
|
|
2394
|
+
|
|
2395
|
+
|
|
2396
|
+
|
|
2397
|
+
|
|
2398
|
+
|
|
2399
|
+
|
|
2400
|
+
|
|
2401
|
+
|
|
2402
|
+
|
|
2403
|
+
|
|
2404
|
+
|
|
2405
|
+
|
|
2406
|
+
|
|
2407
|
+
|
|
2408
|
+
|
|
2409
|
+
|
|
2410
|
+
|
|
2411
|
+
|
|
2412
|
+
* @example
|
|
2413
|
+
* // Transform elements
|
|
2414
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
2415
|
+
* const doubled = q.map(x => x * 2);
|
|
2416
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
2417
|
+
*/
|
|
1384
2418
|
map(callback, options, thisArg) {
|
|
1385
2419
|
const out = new this.constructor([], {
|
|
1386
2420
|
toElementFn: options?.toElementFn,
|
|
@@ -2477,12 +3511,49 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2477
3511
|
return new DirectedEdge(src, dest, weight ?? this.options.defaultEdgeWeight ?? 1, value);
|
|
2478
3512
|
}
|
|
2479
3513
|
/**
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
3514
|
+
* Get the unique edge from `src` to `dest`, if present.
|
|
3515
|
+
* @param srcOrKey - Source vertex or key.
|
|
3516
|
+
* @param destOrKey - Destination vertex or key.
|
|
3517
|
+
* @returns Edge instance or `undefined`.
|
|
3518
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3519
|
+
|
|
3520
|
+
|
|
3521
|
+
|
|
3522
|
+
|
|
3523
|
+
|
|
3524
|
+
|
|
3525
|
+
|
|
3526
|
+
|
|
3527
|
+
|
|
3528
|
+
|
|
3529
|
+
|
|
3530
|
+
|
|
3531
|
+
|
|
3532
|
+
|
|
3533
|
+
|
|
3534
|
+
|
|
3535
|
+
|
|
3536
|
+
|
|
3537
|
+
|
|
3538
|
+
|
|
3539
|
+
|
|
3540
|
+
|
|
3541
|
+
|
|
3542
|
+
|
|
3543
|
+
|
|
3544
|
+
|
|
3545
|
+
|
|
3546
|
+
|
|
3547
|
+
|
|
3548
|
+
* @example
|
|
3549
|
+
* // Get edge between vertices
|
|
3550
|
+
* const g = new DirectedGraph();
|
|
3551
|
+
* g.addVertex('A');
|
|
3552
|
+
* g.addVertex('B');
|
|
3553
|
+
* g.addEdge('A', 'B', 5);
|
|
3554
|
+
* const edge = g.getEdge('A', 'B');
|
|
3555
|
+
* console.log(edge?.weight); // 5;
|
|
3556
|
+
*/
|
|
2486
3557
|
getEdge(srcOrKey, destOrKey) {
|
|
2487
3558
|
let edgeMap = [];
|
|
2488
3559
|
if (srcOrKey !== void 0 && destOrKey !== void 0) {
|
|
@@ -2522,12 +3593,69 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2522
3593
|
return removed;
|
|
2523
3594
|
}
|
|
2524
3595
|
/**
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
3596
|
+
* Delete an edge by instance or by `(srcKey, destKey)`.
|
|
3597
|
+
* @param edgeOrSrcVertexKey - Edge instance or source vertex/key.
|
|
3598
|
+
* @param destVertexKey - Optional destination vertex/key when deleting by pair.
|
|
3599
|
+
* @returns Removed edge or `undefined`.
|
|
3600
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
3601
|
+
|
|
3602
|
+
|
|
3603
|
+
|
|
3604
|
+
|
|
3605
|
+
|
|
3606
|
+
|
|
3607
|
+
|
|
3608
|
+
|
|
3609
|
+
|
|
3610
|
+
|
|
3611
|
+
|
|
3612
|
+
|
|
3613
|
+
|
|
3614
|
+
|
|
3615
|
+
|
|
3616
|
+
|
|
3617
|
+
|
|
3618
|
+
|
|
3619
|
+
|
|
3620
|
+
|
|
3621
|
+
|
|
3622
|
+
|
|
3623
|
+
|
|
3624
|
+
|
|
3625
|
+
|
|
3626
|
+
|
|
3627
|
+
|
|
3628
|
+
|
|
3629
|
+
|
|
3630
|
+
|
|
3631
|
+
|
|
3632
|
+
|
|
3633
|
+
* @example
|
|
3634
|
+
* // DirectedGraph deleteEdge and vertex operations
|
|
3635
|
+
* const graph = new DirectedGraph<string>();
|
|
3636
|
+
*
|
|
3637
|
+
* // Build a small graph
|
|
3638
|
+
* graph.addVertex('X');
|
|
3639
|
+
* graph.addVertex('Y');
|
|
3640
|
+
* graph.addVertex('Z');
|
|
3641
|
+
* graph.addEdge('X', 'Y', 1);
|
|
3642
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
3643
|
+
*
|
|
3644
|
+
* // Delete an edge
|
|
3645
|
+
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
3646
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
3647
|
+
*
|
|
3648
|
+
* // Edge in other direction should not exist
|
|
3649
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
3650
|
+
*
|
|
3651
|
+
* // Other edges should remain
|
|
3652
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
3653
|
+
*
|
|
3654
|
+
* // Delete a vertex
|
|
3655
|
+
* graph.deleteVertex('Y');
|
|
3656
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
3657
|
+
* console.log(graph.size); // 2;
|
|
3658
|
+
*/
|
|
2531
3659
|
deleteEdge(edgeOrSrcVertexKey, destVertexKey) {
|
|
2532
3660
|
let removed = void 0;
|
|
2533
3661
|
let src, dest;
|
|
@@ -2554,6 +3682,47 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2554
3682
|
}
|
|
2555
3683
|
return removed;
|
|
2556
3684
|
}
|
|
3685
|
+
/**
|
|
3686
|
+
* Remove a vertex
|
|
3687
|
+
|
|
3688
|
+
|
|
3689
|
+
|
|
3690
|
+
|
|
3691
|
+
|
|
3692
|
+
|
|
3693
|
+
|
|
3694
|
+
|
|
3695
|
+
|
|
3696
|
+
|
|
3697
|
+
|
|
3698
|
+
|
|
3699
|
+
|
|
3700
|
+
|
|
3701
|
+
|
|
3702
|
+
|
|
3703
|
+
|
|
3704
|
+
|
|
3705
|
+
|
|
3706
|
+
|
|
3707
|
+
|
|
3708
|
+
|
|
3709
|
+
|
|
3710
|
+
|
|
3711
|
+
|
|
3712
|
+
|
|
3713
|
+
|
|
3714
|
+
|
|
3715
|
+
|
|
3716
|
+
* @example
|
|
3717
|
+
* // Remove a vertex
|
|
3718
|
+
* const g = new DirectedGraph();
|
|
3719
|
+
* g.addVertex('A');
|
|
3720
|
+
* g.addVertex('B');
|
|
3721
|
+
* g.addEdge('A', 'B');
|
|
3722
|
+
* g.deleteVertex('A');
|
|
3723
|
+
* console.log(g.hasVertex('A')); // false;
|
|
3724
|
+
* console.log(g.hasEdge('A', 'B')); // false;
|
|
3725
|
+
*/
|
|
2557
3726
|
deleteVertex(vertexOrKey) {
|
|
2558
3727
|
let vertexKey;
|
|
2559
3728
|
let vertex;
|
|
@@ -2585,11 +3754,49 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2585
3754
|
return removed;
|
|
2586
3755
|
}
|
|
2587
3756
|
/**
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
3757
|
+
* Incoming edges of a vertex.
|
|
3758
|
+
* @param vertexOrKey - Vertex or key.
|
|
3759
|
+
* @returns Array of incoming edges.
|
|
3760
|
+
* @remarks Time O(deg_in), Space O(deg_in)
|
|
3761
|
+
|
|
3762
|
+
|
|
3763
|
+
|
|
3764
|
+
|
|
3765
|
+
|
|
3766
|
+
|
|
3767
|
+
|
|
3768
|
+
|
|
3769
|
+
|
|
3770
|
+
|
|
3771
|
+
|
|
3772
|
+
|
|
3773
|
+
|
|
3774
|
+
|
|
3775
|
+
|
|
3776
|
+
|
|
3777
|
+
|
|
3778
|
+
|
|
3779
|
+
|
|
3780
|
+
|
|
3781
|
+
|
|
3782
|
+
|
|
3783
|
+
|
|
3784
|
+
|
|
3785
|
+
|
|
3786
|
+
|
|
3787
|
+
|
|
3788
|
+
|
|
3789
|
+
|
|
3790
|
+
* @example
|
|
3791
|
+
* // Get incoming edges
|
|
3792
|
+
* const g = new DirectedGraph();
|
|
3793
|
+
* g.addVertex('A');
|
|
3794
|
+
* g.addVertex('B');
|
|
3795
|
+
* g.addVertex('C');
|
|
3796
|
+
* g.addEdge('A', 'C');
|
|
3797
|
+
* g.addEdge('B', 'C');
|
|
3798
|
+
* console.log(g.incomingEdgesOf('C').length); // 2;
|
|
3799
|
+
*/
|
|
2593
3800
|
incomingEdgesOf(vertexOrKey) {
|
|
2594
3801
|
const target = this._getVertex(vertexOrKey);
|
|
2595
3802
|
if (target) {
|
|
@@ -2598,11 +3805,49 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2598
3805
|
return [];
|
|
2599
3806
|
}
|
|
2600
3807
|
/**
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
3808
|
+
* Outgoing edges of a vertex.
|
|
3809
|
+
* @param vertexOrKey - Vertex or key.
|
|
3810
|
+
* @returns Array of outgoing edges.
|
|
3811
|
+
* @remarks Time O(deg_out), Space O(deg_out)
|
|
3812
|
+
|
|
3813
|
+
|
|
3814
|
+
|
|
3815
|
+
|
|
3816
|
+
|
|
3817
|
+
|
|
3818
|
+
|
|
3819
|
+
|
|
3820
|
+
|
|
3821
|
+
|
|
3822
|
+
|
|
3823
|
+
|
|
3824
|
+
|
|
3825
|
+
|
|
3826
|
+
|
|
3827
|
+
|
|
3828
|
+
|
|
3829
|
+
|
|
3830
|
+
|
|
3831
|
+
|
|
3832
|
+
|
|
3833
|
+
|
|
3834
|
+
|
|
3835
|
+
|
|
3836
|
+
|
|
3837
|
+
|
|
3838
|
+
|
|
3839
|
+
|
|
3840
|
+
|
|
3841
|
+
* @example
|
|
3842
|
+
* // Get outgoing edges
|
|
3843
|
+
* const g = new DirectedGraph();
|
|
3844
|
+
* g.addVertex('A');
|
|
3845
|
+
* g.addVertex('B');
|
|
3846
|
+
* g.addVertex('C');
|
|
3847
|
+
* g.addEdge('A', 'B');
|
|
3848
|
+
* g.addEdge('A', 'C');
|
|
3849
|
+
* console.log(g.outgoingEdgesOf('A').length); // 2;
|
|
3850
|
+
*/
|
|
2606
3851
|
outgoingEdgesOf(vertexOrKey) {
|
|
2607
3852
|
const target = this._getVertex(vertexOrKey);
|
|
2608
3853
|
if (target) {
|
|
@@ -2661,11 +3906,65 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2661
3906
|
return destinations;
|
|
2662
3907
|
}
|
|
2663
3908
|
/**
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
3909
|
+
* Topological sort if DAG; returns `undefined` if a cycle exists.
|
|
3910
|
+
* @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
|
|
3911
|
+
* @returns Array of keys/vertices, or `undefined` when cycle is found.
|
|
3912
|
+
* @remarks Time O(V + E), Space O(V)
|
|
3913
|
+
|
|
3914
|
+
|
|
3915
|
+
|
|
3916
|
+
|
|
3917
|
+
|
|
3918
|
+
|
|
3919
|
+
|
|
3920
|
+
|
|
3921
|
+
|
|
3922
|
+
|
|
3923
|
+
|
|
3924
|
+
|
|
3925
|
+
|
|
3926
|
+
|
|
3927
|
+
|
|
3928
|
+
|
|
3929
|
+
|
|
3930
|
+
|
|
3931
|
+
|
|
3932
|
+
|
|
3933
|
+
|
|
3934
|
+
|
|
3935
|
+
|
|
3936
|
+
|
|
3937
|
+
|
|
3938
|
+
|
|
3939
|
+
|
|
3940
|
+
|
|
3941
|
+
|
|
3942
|
+
|
|
3943
|
+
|
|
3944
|
+
|
|
3945
|
+
* @example
|
|
3946
|
+
* // DirectedGraph topologicalSort for task scheduling
|
|
3947
|
+
* const graph = new DirectedGraph<string>();
|
|
3948
|
+
*
|
|
3949
|
+
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
3950
|
+
* graph.addVertex('Design');
|
|
3951
|
+
* graph.addVertex('Implement');
|
|
3952
|
+
* graph.addVertex('Test');
|
|
3953
|
+
* graph.addVertex('Deploy');
|
|
3954
|
+
*
|
|
3955
|
+
* // Add dependency edges
|
|
3956
|
+
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
3957
|
+
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
3958
|
+
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
3959
|
+
*
|
|
3960
|
+
* // Topological sort gives valid execution order
|
|
3961
|
+
* const executionOrder = graph.topologicalSort();
|
|
3962
|
+
* console.log(executionOrder); // defined;
|
|
3963
|
+
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
3964
|
+
*
|
|
3965
|
+
* // All vertices should be included
|
|
3966
|
+
* console.log(executionOrder?.length); // 4;
|
|
3967
|
+
*/
|
|
2669
3968
|
topologicalSort(propertyName) {
|
|
2670
3969
|
propertyName = propertyName ?? "key";
|
|
2671
3970
|
const statusMap = /* @__PURE__ */ new Map();
|
|
@@ -2697,6 +3996,45 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2697
3996
|
if (propertyName === "key") sorted = sorted.map((vertex) => vertex instanceof DirectedVertex ? vertex.key : vertex);
|
|
2698
3997
|
return sorted.reverse();
|
|
2699
3998
|
}
|
|
3999
|
+
/**
|
|
4000
|
+
* Get all edges
|
|
4001
|
+
|
|
4002
|
+
|
|
4003
|
+
|
|
4004
|
+
|
|
4005
|
+
|
|
4006
|
+
|
|
4007
|
+
|
|
4008
|
+
|
|
4009
|
+
|
|
4010
|
+
|
|
4011
|
+
|
|
4012
|
+
|
|
4013
|
+
|
|
4014
|
+
|
|
4015
|
+
|
|
4016
|
+
|
|
4017
|
+
|
|
4018
|
+
|
|
4019
|
+
|
|
4020
|
+
|
|
4021
|
+
|
|
4022
|
+
|
|
4023
|
+
|
|
4024
|
+
|
|
4025
|
+
|
|
4026
|
+
|
|
4027
|
+
|
|
4028
|
+
|
|
4029
|
+
|
|
4030
|
+
* @example
|
|
4031
|
+
* // Get all edges
|
|
4032
|
+
* const g = new DirectedGraph();
|
|
4033
|
+
* g.addVertex('A');
|
|
4034
|
+
* g.addVertex('B');
|
|
4035
|
+
* g.addEdge('A', 'B', 3);
|
|
4036
|
+
* console.log(g.edgeSet().length); // 1;
|
|
4037
|
+
*/
|
|
2700
4038
|
edgeSet() {
|
|
2701
4039
|
let edgeMap = [];
|
|
2702
4040
|
this._outEdgeMap.forEach((outEdges) => {
|
|
@@ -2704,6 +4042,49 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2704
4042
|
});
|
|
2705
4043
|
return edgeMap;
|
|
2706
4044
|
}
|
|
4045
|
+
/**
|
|
4046
|
+
* Get outgoing neighbors
|
|
4047
|
+
|
|
4048
|
+
|
|
4049
|
+
|
|
4050
|
+
|
|
4051
|
+
|
|
4052
|
+
|
|
4053
|
+
|
|
4054
|
+
|
|
4055
|
+
|
|
4056
|
+
|
|
4057
|
+
|
|
4058
|
+
|
|
4059
|
+
|
|
4060
|
+
|
|
4061
|
+
|
|
4062
|
+
|
|
4063
|
+
|
|
4064
|
+
|
|
4065
|
+
|
|
4066
|
+
|
|
4067
|
+
|
|
4068
|
+
|
|
4069
|
+
|
|
4070
|
+
|
|
4071
|
+
|
|
4072
|
+
|
|
4073
|
+
|
|
4074
|
+
|
|
4075
|
+
|
|
4076
|
+
|
|
4077
|
+
* @example
|
|
4078
|
+
* // Get outgoing neighbors
|
|
4079
|
+
* const g = new DirectedGraph();
|
|
4080
|
+
* g.addVertex('A');
|
|
4081
|
+
* g.addVertex('B');
|
|
4082
|
+
* g.addVertex('C');
|
|
4083
|
+
* g.addEdge('A', 'B');
|
|
4084
|
+
* g.addEdge('A', 'C');
|
|
4085
|
+
* const neighbors = g.getNeighbors('A');
|
|
4086
|
+
* console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
|
|
4087
|
+
*/
|
|
2707
4088
|
getNeighbors(vertexOrKey) {
|
|
2708
4089
|
const neighbors = [];
|
|
2709
4090
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -2761,10 +4142,52 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2761
4142
|
return super.clone();
|
|
2762
4143
|
}
|
|
2763
4144
|
/**
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
4145
|
+
* Tarjan's algorithm for strongly connected components.
|
|
4146
|
+
* @returns `{ dfnMap, lowMap, SCCs }`.
|
|
4147
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
4148
|
+
|
|
4149
|
+
|
|
4150
|
+
|
|
4151
|
+
|
|
4152
|
+
|
|
4153
|
+
|
|
4154
|
+
|
|
4155
|
+
|
|
4156
|
+
|
|
4157
|
+
|
|
4158
|
+
|
|
4159
|
+
|
|
4160
|
+
|
|
4161
|
+
|
|
4162
|
+
|
|
4163
|
+
|
|
4164
|
+
|
|
4165
|
+
|
|
4166
|
+
|
|
4167
|
+
|
|
4168
|
+
|
|
4169
|
+
|
|
4170
|
+
|
|
4171
|
+
|
|
4172
|
+
|
|
4173
|
+
|
|
4174
|
+
|
|
4175
|
+
|
|
4176
|
+
|
|
4177
|
+
* @example
|
|
4178
|
+
* // Find strongly connected components
|
|
4179
|
+
* const g = new DirectedGraph();
|
|
4180
|
+
* g.addVertex('A');
|
|
4181
|
+
* g.addVertex('B');
|
|
4182
|
+
* g.addVertex('C');
|
|
4183
|
+
* g.addEdge('A', 'B');
|
|
4184
|
+
* g.addEdge('B', 'C');
|
|
4185
|
+
* g.addEdge('C', 'A');
|
|
4186
|
+
* const { SCCs } = g.tarjan();
|
|
4187
|
+
* // A→B→C→A forms one SCC with 3 members
|
|
4188
|
+
* const sccArrays = [...SCCs.values()];
|
|
4189
|
+
* console.log(sccArrays.some(scc => scc.length === 3)); // true;
|
|
4190
|
+
*/
|
|
2768
4191
|
tarjan() {
|
|
2769
4192
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
2770
4193
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -2822,10 +4245,50 @@ var DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
2822
4245
|
return this.tarjan().lowMap;
|
|
2823
4246
|
}
|
|
2824
4247
|
/**
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
4248
|
+
* Strongly connected components computed by `tarjan()`.
|
|
4249
|
+
* @returns Map from SCC id to vertices.
|
|
4250
|
+
* @remarks Time O(#SCC + V), Space O(V)
|
|
4251
|
+
|
|
4252
|
+
|
|
4253
|
+
|
|
4254
|
+
|
|
4255
|
+
|
|
4256
|
+
|
|
4257
|
+
|
|
4258
|
+
|
|
4259
|
+
|
|
4260
|
+
|
|
4261
|
+
|
|
4262
|
+
|
|
4263
|
+
|
|
4264
|
+
|
|
4265
|
+
|
|
4266
|
+
|
|
4267
|
+
|
|
4268
|
+
|
|
4269
|
+
|
|
4270
|
+
|
|
4271
|
+
|
|
4272
|
+
|
|
4273
|
+
|
|
4274
|
+
|
|
4275
|
+
|
|
4276
|
+
|
|
4277
|
+
|
|
4278
|
+
|
|
4279
|
+
|
|
4280
|
+
* @example
|
|
4281
|
+
* // Get strongly connected components
|
|
4282
|
+
* const g = new DirectedGraph();
|
|
4283
|
+
* g.addVertex(1);
|
|
4284
|
+
* g.addVertex(2);
|
|
4285
|
+
* g.addVertex(3);
|
|
4286
|
+
* g.addEdge(1, 2);
|
|
4287
|
+
* g.addEdge(2, 3);
|
|
4288
|
+
* g.addEdge(3, 1);
|
|
4289
|
+
* const sccs = g.getSCCs(); // Map<number, VO[]>
|
|
4290
|
+
* console.log(sccs.size); // >= 1;
|
|
4291
|
+
*/
|
|
2829
4292
|
getSCCs() {
|
|
2830
4293
|
return this.tarjan().SCCs;
|
|
2831
4294
|
}
|
|
@@ -2949,12 +4412,48 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2949
4412
|
return new UndirectedEdge(v1, v2, weight ?? this.options.defaultEdgeWeight ?? 1, value);
|
|
2950
4413
|
}
|
|
2951
4414
|
/**
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
4415
|
+
* Get an undirected edge between two vertices, if present.
|
|
4416
|
+
* @param v1 - One vertex or key.
|
|
4417
|
+
* @param v2 - The other vertex or key.
|
|
4418
|
+
* @returns Edge instance or `undefined`.
|
|
4419
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
4420
|
+
|
|
4421
|
+
|
|
4422
|
+
|
|
4423
|
+
|
|
4424
|
+
|
|
4425
|
+
|
|
4426
|
+
|
|
4427
|
+
|
|
4428
|
+
|
|
4429
|
+
|
|
4430
|
+
|
|
4431
|
+
|
|
4432
|
+
|
|
4433
|
+
|
|
4434
|
+
|
|
4435
|
+
|
|
4436
|
+
|
|
4437
|
+
|
|
4438
|
+
|
|
4439
|
+
|
|
4440
|
+
|
|
4441
|
+
|
|
4442
|
+
|
|
4443
|
+
|
|
4444
|
+
|
|
4445
|
+
|
|
4446
|
+
|
|
4447
|
+
|
|
4448
|
+
|
|
4449
|
+
* @example
|
|
4450
|
+
* // Get edge between vertices
|
|
4451
|
+
* const g = new UndirectedGraph();
|
|
4452
|
+
* g.addVertex('A');
|
|
4453
|
+
* g.addVertex('B');
|
|
4454
|
+
* g.addEdge('A', 'B', 7);
|
|
4455
|
+
* console.log(g.getEdge('A', 'B')?.weight); // 7;
|
|
4456
|
+
*/
|
|
2958
4457
|
getEdge(v1, v2) {
|
|
2959
4458
|
let edgeMap = [];
|
|
2960
4459
|
if (v1 !== void 0 && v2 !== void 0) {
|
|
@@ -2991,12 +4490,71 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
2991
4490
|
return removed;
|
|
2992
4491
|
}
|
|
2993
4492
|
/**
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
4493
|
+
* Delete an edge by instance or by a pair of keys.
|
|
4494
|
+
* @param edgeOrOneSideVertexKey - Edge instance or one endpoint vertex/key.
|
|
4495
|
+
* @param otherSideVertexKey - Required second endpoint when deleting by pair.
|
|
4496
|
+
* @returns Removed edge or `undefined`.
|
|
4497
|
+
* @remarks Time O(1) avg, Space O(1)
|
|
4498
|
+
|
|
4499
|
+
|
|
4500
|
+
|
|
4501
|
+
|
|
4502
|
+
|
|
4503
|
+
|
|
4504
|
+
|
|
4505
|
+
|
|
4506
|
+
|
|
4507
|
+
|
|
4508
|
+
|
|
4509
|
+
|
|
4510
|
+
|
|
4511
|
+
|
|
4512
|
+
|
|
4513
|
+
|
|
4514
|
+
|
|
4515
|
+
|
|
4516
|
+
|
|
4517
|
+
|
|
4518
|
+
|
|
4519
|
+
|
|
4520
|
+
|
|
4521
|
+
|
|
4522
|
+
|
|
4523
|
+
|
|
4524
|
+
|
|
4525
|
+
|
|
4526
|
+
|
|
4527
|
+
|
|
4528
|
+
|
|
4529
|
+
|
|
4530
|
+
* @example
|
|
4531
|
+
* // UndirectedGraph deleteEdge and vertex operations
|
|
4532
|
+
* const graph = new UndirectedGraph<string>();
|
|
4533
|
+
*
|
|
4534
|
+
* // Build a simple undirected graph
|
|
4535
|
+
* graph.addVertex('X');
|
|
4536
|
+
* graph.addVertex('Y');
|
|
4537
|
+
* graph.addVertex('Z');
|
|
4538
|
+
* graph.addEdge('X', 'Y', 1);
|
|
4539
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
4540
|
+
* graph.addEdge('X', 'Z', 3);
|
|
4541
|
+
*
|
|
4542
|
+
* // Delete an edge
|
|
4543
|
+
* graph.deleteEdge('X', 'Y');
|
|
4544
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
4545
|
+
*
|
|
4546
|
+
* // Bidirectional deletion confirmed
|
|
4547
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
4548
|
+
*
|
|
4549
|
+
* // Other edges should remain
|
|
4550
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
4551
|
+
* console.log(graph.hasEdge('Z', 'Y')); // true;
|
|
4552
|
+
*
|
|
4553
|
+
* // Delete a vertex
|
|
4554
|
+
* graph.deleteVertex('Y');
|
|
4555
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
4556
|
+
* console.log(graph.size); // 2;
|
|
4557
|
+
*/
|
|
3000
4558
|
deleteEdge(edgeOrOneSideVertexKey, otherSideVertexKey) {
|
|
3001
4559
|
let oneSide, otherSide;
|
|
3002
4560
|
if (this.isVertexKey(edgeOrOneSideVertexKey)) {
|
|
@@ -3017,11 +4575,48 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3017
4575
|
}
|
|
3018
4576
|
}
|
|
3019
4577
|
/**
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
4578
|
+
* Delete a vertex and remove it from all neighbor lists.
|
|
4579
|
+
* @param vertexOrKey - Vertex or key.
|
|
4580
|
+
* @returns `true` if removed; otherwise `false`.
|
|
4581
|
+
* @remarks Time O(deg), Space O(1)
|
|
4582
|
+
|
|
4583
|
+
|
|
4584
|
+
|
|
4585
|
+
|
|
4586
|
+
|
|
4587
|
+
|
|
4588
|
+
|
|
4589
|
+
|
|
4590
|
+
|
|
4591
|
+
|
|
4592
|
+
|
|
4593
|
+
|
|
4594
|
+
|
|
4595
|
+
|
|
4596
|
+
|
|
4597
|
+
|
|
4598
|
+
|
|
4599
|
+
|
|
4600
|
+
|
|
4601
|
+
|
|
4602
|
+
|
|
4603
|
+
|
|
4604
|
+
|
|
4605
|
+
|
|
4606
|
+
|
|
4607
|
+
|
|
4608
|
+
|
|
4609
|
+
|
|
4610
|
+
|
|
4611
|
+
* @example
|
|
4612
|
+
* // Remove vertex and edges
|
|
4613
|
+
* const g = new UndirectedGraph();
|
|
4614
|
+
* g.addVertex('A');
|
|
4615
|
+
* g.addVertex('B');
|
|
4616
|
+
* g.addEdge('A', 'B');
|
|
4617
|
+
* g.deleteVertex('A');
|
|
4618
|
+
* console.log(g.hasVertex('A')); // false;
|
|
4619
|
+
*/
|
|
3025
4620
|
deleteVertex(vertexOrKey) {
|
|
3026
4621
|
let vertexKey;
|
|
3027
4622
|
let vertex;
|
|
@@ -3076,10 +4671,46 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3076
4671
|
}
|
|
3077
4672
|
}
|
|
3078
4673
|
/**
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
4674
|
+
* Unique set of undirected edges across endpoints.
|
|
4675
|
+
* @returns Array of edges.
|
|
4676
|
+
* @remarks Time O(E), Space O(E)
|
|
4677
|
+
|
|
4678
|
+
|
|
4679
|
+
|
|
4680
|
+
|
|
4681
|
+
|
|
4682
|
+
|
|
4683
|
+
|
|
4684
|
+
|
|
4685
|
+
|
|
4686
|
+
|
|
4687
|
+
|
|
4688
|
+
|
|
4689
|
+
|
|
4690
|
+
|
|
4691
|
+
|
|
4692
|
+
|
|
4693
|
+
|
|
4694
|
+
|
|
4695
|
+
|
|
4696
|
+
|
|
4697
|
+
|
|
4698
|
+
|
|
4699
|
+
|
|
4700
|
+
|
|
4701
|
+
|
|
4702
|
+
|
|
4703
|
+
|
|
4704
|
+
|
|
4705
|
+
|
|
4706
|
+
* @example
|
|
4707
|
+
* // Get all edges
|
|
4708
|
+
* const g = new UndirectedGraph();
|
|
4709
|
+
* g.addVertex('A');
|
|
4710
|
+
* g.addVertex('B');
|
|
4711
|
+
* g.addEdge('A', 'B');
|
|
4712
|
+
* console.log(g.edgeSet().length); // 1;
|
|
4713
|
+
*/
|
|
3083
4714
|
edgeSet() {
|
|
3084
4715
|
const edgeSet = /* @__PURE__ */ new Set();
|
|
3085
4716
|
this._edgeMap.forEach((edgeMap) => {
|
|
@@ -3089,6 +4720,73 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3089
4720
|
});
|
|
3090
4721
|
return [...edgeSet];
|
|
3091
4722
|
}
|
|
4723
|
+
/**
|
|
4724
|
+
* UndirectedGraph connectivity and neighbors
|
|
4725
|
+
|
|
4726
|
+
|
|
4727
|
+
|
|
4728
|
+
|
|
4729
|
+
|
|
4730
|
+
|
|
4731
|
+
|
|
4732
|
+
|
|
4733
|
+
|
|
4734
|
+
|
|
4735
|
+
|
|
4736
|
+
|
|
4737
|
+
|
|
4738
|
+
|
|
4739
|
+
|
|
4740
|
+
|
|
4741
|
+
|
|
4742
|
+
|
|
4743
|
+
|
|
4744
|
+
|
|
4745
|
+
|
|
4746
|
+
|
|
4747
|
+
|
|
4748
|
+
|
|
4749
|
+
|
|
4750
|
+
|
|
4751
|
+
|
|
4752
|
+
|
|
4753
|
+
|
|
4754
|
+
|
|
4755
|
+
|
|
4756
|
+
|
|
4757
|
+
* @example
|
|
4758
|
+
* // UndirectedGraph connectivity and neighbors
|
|
4759
|
+
* const graph = new UndirectedGraph<string>();
|
|
4760
|
+
*
|
|
4761
|
+
* // Build a friendship network
|
|
4762
|
+
* const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
|
|
4763
|
+
* for (const person of people) {
|
|
4764
|
+
* graph.addVertex(person);
|
|
4765
|
+
* }
|
|
4766
|
+
*
|
|
4767
|
+
* // Add friendships (undirected edges)
|
|
4768
|
+
* graph.addEdge('Alice', 'Bob', 1);
|
|
4769
|
+
* graph.addEdge('Alice', 'Charlie', 1);
|
|
4770
|
+
* graph.addEdge('Bob', 'Diana', 1);
|
|
4771
|
+
* graph.addEdge('Charlie', 'Eve', 1);
|
|
4772
|
+
* graph.addEdge('Diana', 'Eve', 1);
|
|
4773
|
+
*
|
|
4774
|
+
* // Get friends of each person
|
|
4775
|
+
* const aliceFriends = graph.getNeighbors('Alice');
|
|
4776
|
+
* console.log(aliceFriends[0].key); // 'Bob';
|
|
4777
|
+
* console.log(aliceFriends[1].key); // 'Charlie';
|
|
4778
|
+
* console.log(aliceFriends.length); // 2;
|
|
4779
|
+
*
|
|
4780
|
+
* const dianaFriends = graph.getNeighbors('Diana');
|
|
4781
|
+
* console.log(dianaFriends[0].key); // 'Bob';
|
|
4782
|
+
* console.log(dianaFriends[1].key); // 'Eve';
|
|
4783
|
+
* console.log(dianaFriends.length); // 2;
|
|
4784
|
+
*
|
|
4785
|
+
* // Verify bidirectional friendship
|
|
4786
|
+
* const bobFriends = graph.getNeighbors('Bob');
|
|
4787
|
+
* console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
|
|
4788
|
+
* console.log(bobFriends[1].key); // 'Diana';
|
|
4789
|
+
*/
|
|
3092
4790
|
getNeighbors(vertexOrKey) {
|
|
3093
4791
|
const neighbors = [];
|
|
3094
4792
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -3145,10 +4843,49 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3145
4843
|
return super.clone();
|
|
3146
4844
|
}
|
|
3147
4845
|
/**
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
4846
|
+
* Tarjan-based bridge and articulation point detection.
|
|
4847
|
+
* @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
|
|
4848
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
4849
|
+
|
|
4850
|
+
|
|
4851
|
+
|
|
4852
|
+
|
|
4853
|
+
|
|
4854
|
+
|
|
4855
|
+
|
|
4856
|
+
|
|
4857
|
+
|
|
4858
|
+
|
|
4859
|
+
|
|
4860
|
+
|
|
4861
|
+
|
|
4862
|
+
|
|
4863
|
+
|
|
4864
|
+
|
|
4865
|
+
|
|
4866
|
+
|
|
4867
|
+
|
|
4868
|
+
|
|
4869
|
+
|
|
4870
|
+
|
|
4871
|
+
|
|
4872
|
+
|
|
4873
|
+
|
|
4874
|
+
|
|
4875
|
+
|
|
4876
|
+
|
|
4877
|
+
|
|
4878
|
+
* @example
|
|
4879
|
+
* // Find articulation points and bridges
|
|
4880
|
+
* const g = new UndirectedGraph();
|
|
4881
|
+
* g.addVertex('A');
|
|
4882
|
+
* g.addVertex('B');
|
|
4883
|
+
* g.addVertex('C');
|
|
4884
|
+
* g.addEdge('A', 'B');
|
|
4885
|
+
* g.addEdge('B', 'C');
|
|
4886
|
+
* const result = g.tarjan();
|
|
4887
|
+
* console.log(result); // defined;
|
|
4888
|
+
*/
|
|
3152
4889
|
tarjan() {
|
|
3153
4890
|
const dfnMap = /* @__PURE__ */ new Map();
|
|
3154
4891
|
const lowMap = /* @__PURE__ */ new Map();
|
|
@@ -3248,11 +4985,51 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3248
4985
|
return components;
|
|
3249
4986
|
}
|
|
3250
4987
|
/**
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
4988
|
+
* Detect whether the graph contains a cycle.
|
|
4989
|
+
* Uses DFS with parent tracking.
|
|
4990
|
+
* @returns `true` if a cycle exists, `false` otherwise.
|
|
4991
|
+
* @remarks Time O(V + E), Space O(V)
|
|
4992
|
+
|
|
4993
|
+
|
|
4994
|
+
|
|
4995
|
+
|
|
4996
|
+
|
|
4997
|
+
|
|
4998
|
+
|
|
4999
|
+
|
|
5000
|
+
|
|
5001
|
+
|
|
5002
|
+
|
|
5003
|
+
|
|
5004
|
+
|
|
5005
|
+
|
|
5006
|
+
|
|
5007
|
+
|
|
5008
|
+
|
|
5009
|
+
|
|
5010
|
+
|
|
5011
|
+
|
|
5012
|
+
|
|
5013
|
+
|
|
5014
|
+
|
|
5015
|
+
|
|
5016
|
+
|
|
5017
|
+
|
|
5018
|
+
|
|
5019
|
+
|
|
5020
|
+
|
|
5021
|
+
* @example
|
|
5022
|
+
* // Detect cycle
|
|
5023
|
+
* const g = new UndirectedGraph();
|
|
5024
|
+
* g.addVertex('A');
|
|
5025
|
+
* g.addVertex('B');
|
|
5026
|
+
* g.addVertex('C');
|
|
5027
|
+
* g.addEdge('A', 'B');
|
|
5028
|
+
* g.addEdge('B', 'C');
|
|
5029
|
+
* console.log(g.hasCycle()); // false;
|
|
5030
|
+
* g.addEdge('C', 'A');
|
|
5031
|
+
* console.log(g.hasCycle()); // true;
|
|
5032
|
+
*/
|
|
3256
5033
|
hasCycle() {
|
|
3257
5034
|
const visited = /* @__PURE__ */ new Set();
|
|
3258
5035
|
const dfs = /* @__PURE__ */ __name((vertex, parent) => {
|
|
@@ -3274,18 +5051,97 @@ var UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
3274
5051
|
return false;
|
|
3275
5052
|
}
|
|
3276
5053
|
/**
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
5054
|
+
* Get bridges discovered by `tarjan()`.
|
|
5055
|
+
* @returns Array of edges that are bridges.
|
|
5056
|
+
* @remarks Time O(B), Space O(1)
|
|
5057
|
+
|
|
5058
|
+
|
|
5059
|
+
|
|
5060
|
+
|
|
5061
|
+
|
|
5062
|
+
|
|
5063
|
+
|
|
5064
|
+
|
|
5065
|
+
|
|
5066
|
+
|
|
5067
|
+
|
|
5068
|
+
|
|
5069
|
+
|
|
5070
|
+
|
|
5071
|
+
|
|
5072
|
+
|
|
5073
|
+
|
|
5074
|
+
|
|
5075
|
+
|
|
5076
|
+
|
|
5077
|
+
|
|
5078
|
+
|
|
5079
|
+
|
|
5080
|
+
|
|
5081
|
+
|
|
5082
|
+
|
|
5083
|
+
|
|
5084
|
+
|
|
5085
|
+
|
|
5086
|
+
* @example
|
|
5087
|
+
* // Find bridge edges
|
|
5088
|
+
* const g = new UndirectedGraph();
|
|
5089
|
+
* g.addVertex('A');
|
|
5090
|
+
* g.addVertex('B');
|
|
5091
|
+
* g.addVertex('C');
|
|
5092
|
+
* g.addEdge('A', 'B');
|
|
5093
|
+
* g.addEdge('B', 'C');
|
|
5094
|
+
* const bridges = g.getBridges();
|
|
5095
|
+
* console.log(bridges.length); // 2;
|
|
5096
|
+
*/
|
|
3281
5097
|
getBridges() {
|
|
3282
5098
|
return this.tarjan().bridges;
|
|
3283
5099
|
}
|
|
3284
5100
|
/**
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
5101
|
+
* Get articulation points discovered by `tarjan()`.
|
|
5102
|
+
* @returns Array of cut vertices.
|
|
5103
|
+
* @remarks Time O(C), Space O(1)
|
|
5104
|
+
|
|
5105
|
+
|
|
5106
|
+
|
|
5107
|
+
|
|
5108
|
+
|
|
5109
|
+
|
|
5110
|
+
|
|
5111
|
+
|
|
5112
|
+
|
|
5113
|
+
|
|
5114
|
+
|
|
5115
|
+
|
|
5116
|
+
|
|
5117
|
+
|
|
5118
|
+
|
|
5119
|
+
|
|
5120
|
+
|
|
5121
|
+
|
|
5122
|
+
|
|
5123
|
+
|
|
5124
|
+
|
|
5125
|
+
|
|
5126
|
+
|
|
5127
|
+
|
|
5128
|
+
|
|
5129
|
+
|
|
5130
|
+
|
|
5131
|
+
|
|
5132
|
+
|
|
5133
|
+
* @example
|
|
5134
|
+
* // Find articulation points
|
|
5135
|
+
* const g = new UndirectedGraph();
|
|
5136
|
+
* g.addVertex('A');
|
|
5137
|
+
* g.addVertex('B');
|
|
5138
|
+
* g.addVertex('C');
|
|
5139
|
+
* g.addEdge('A', 'B');
|
|
5140
|
+
* g.addEdge('B', 'C');
|
|
5141
|
+
* const cuts = g.getCutVertices();
|
|
5142
|
+
* console.log(cuts.length); // 1;
|
|
5143
|
+
* console.log(cuts[0].key); // 'B';
|
|
5144
|
+
*/
|
|
3289
5145
|
getCutVertices() {
|
|
3290
5146
|
return this.tarjan().cutVertices;
|
|
3291
5147
|
}
|