binary-tree-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/README.md +0 -84
- package/dist/cjs/index.cjs +1476 -404
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +1473 -401
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1476 -404
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +1473 -401
- 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/binary-tree-typed.js +1469 -397
- package/dist/umd/binary-tree-typed.js.map +1 -1
- package/dist/umd/binary-tree-typed.min.js +5 -5
- package/dist/umd/binary-tree-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
|
@@ -81,52 +81,6 @@ var binaryTreeTyped = (() => {
|
|
|
81
81
|
return (...args) => trampoline(fn(...args));
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
// src/common/error.ts
|
|
85
|
-
var ERR = {
|
|
86
|
-
// Range / index
|
|
87
|
-
indexOutOfRange: (index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`,
|
|
88
|
-
invalidIndex: (ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`,
|
|
89
|
-
// Type / argument
|
|
90
|
-
invalidArgument: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
91
|
-
comparatorRequired: (ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`,
|
|
92
|
-
invalidKey: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
93
|
-
notAFunction: (name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`,
|
|
94
|
-
invalidEntry: (ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`,
|
|
95
|
-
invalidNaN: (ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`,
|
|
96
|
-
invalidDate: (ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`,
|
|
97
|
-
reduceEmpty: (ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`,
|
|
98
|
-
callbackReturnType: (expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`,
|
|
99
|
-
// State / operation
|
|
100
|
-
invalidOperation: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
101
|
-
// Matrix
|
|
102
|
-
matrixDimensionMismatch: (op) => `Matrix: Dimensions must be compatible for ${op}.`,
|
|
103
|
-
matrixSingular: () => "Matrix: Singular matrix, inverse does not exist.",
|
|
104
|
-
matrixNotSquare: () => "Matrix: Must be square for inversion.",
|
|
105
|
-
matrixNotRectangular: () => "Matrix: Must be rectangular for transposition.",
|
|
106
|
-
matrixRowMismatch: (expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
// src/common/index.ts
|
|
110
|
-
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
111
|
-
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
112
|
-
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
113
|
-
return DFSOperation2;
|
|
114
|
-
})(DFSOperation || {});
|
|
115
|
-
var Range = class {
|
|
116
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
117
|
-
this.low = low;
|
|
118
|
-
this.high = high;
|
|
119
|
-
this.includeLow = includeLow;
|
|
120
|
-
this.includeHigh = includeHigh;
|
|
121
|
-
}
|
|
122
|
-
// Determine whether a key is within the range
|
|
123
|
-
isInRange(key, comparator) {
|
|
124
|
-
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
125
|
-
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
126
|
-
return lowCheck && highCheck;
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
|
|
130
84
|
// src/data-structures/base/iterable-element-base.ts
|
|
131
85
|
var IterableElementBase = class {
|
|
132
86
|
/**
|
|
@@ -149,7 +103,7 @@ var binaryTreeTyped = (() => {
|
|
|
149
103
|
if (options) {
|
|
150
104
|
const { toElementFn } = options;
|
|
151
105
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
152
|
-
else if (toElementFn) throw new TypeError(
|
|
106
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
153
107
|
}
|
|
154
108
|
}
|
|
155
109
|
/**
|
|
@@ -305,7 +259,7 @@ var binaryTreeTyped = (() => {
|
|
|
305
259
|
acc = initialValue;
|
|
306
260
|
} else {
|
|
307
261
|
const first = iter.next();
|
|
308
|
-
if (first.done) throw new TypeError(
|
|
262
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
309
263
|
acc = first.value;
|
|
310
264
|
index = 1;
|
|
311
265
|
}
|
|
@@ -537,6 +491,231 @@ var binaryTreeTyped = (() => {
|
|
|
537
491
|
}
|
|
538
492
|
};
|
|
539
493
|
|
|
494
|
+
// src/common/error.ts
|
|
495
|
+
var ERR = {
|
|
496
|
+
// Range / index
|
|
497
|
+
indexOutOfRange: (index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`,
|
|
498
|
+
invalidIndex: (ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`,
|
|
499
|
+
// Type / argument
|
|
500
|
+
invalidArgument: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
501
|
+
comparatorRequired: (ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`,
|
|
502
|
+
invalidKey: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
503
|
+
notAFunction: (name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`,
|
|
504
|
+
invalidEntry: (ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`,
|
|
505
|
+
invalidNaN: (ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`,
|
|
506
|
+
invalidDate: (ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`,
|
|
507
|
+
reduceEmpty: (ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`,
|
|
508
|
+
callbackReturnType: (expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`,
|
|
509
|
+
// State / operation
|
|
510
|
+
invalidOperation: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
511
|
+
// Matrix
|
|
512
|
+
matrixDimensionMismatch: (op) => `Matrix: Dimensions must be compatible for ${op}.`,
|
|
513
|
+
matrixSingular: () => "Matrix: Singular matrix, inverse does not exist.",
|
|
514
|
+
matrixNotSquare: () => "Matrix: Must be square for inversion.",
|
|
515
|
+
matrixNotRectangular: () => "Matrix: Must be rectangular for transposition.",
|
|
516
|
+
matrixRowMismatch: (expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
// src/common/index.ts
|
|
520
|
+
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
521
|
+
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
522
|
+
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
523
|
+
return DFSOperation2;
|
|
524
|
+
})(DFSOperation || {});
|
|
525
|
+
var Range = class {
|
|
526
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
527
|
+
this.low = low;
|
|
528
|
+
this.high = high;
|
|
529
|
+
this.includeLow = includeLow;
|
|
530
|
+
this.includeHigh = includeHigh;
|
|
531
|
+
}
|
|
532
|
+
// Determine whether a key is within the range
|
|
533
|
+
isInRange(key, comparator) {
|
|
534
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
535
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
536
|
+
return lowCheck && highCheck;
|
|
537
|
+
}
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
// src/data-structures/base/iterable-entry-base.ts
|
|
541
|
+
var IterableEntryBase = class {
|
|
542
|
+
/**
|
|
543
|
+
* Default iterator yielding `[key, value]` entries.
|
|
544
|
+
* @returns Iterator of `[K, V]`.
|
|
545
|
+
* @remarks Time O(n) to iterate, Space O(1)
|
|
546
|
+
*/
|
|
547
|
+
*[Symbol.iterator](...args) {
|
|
548
|
+
yield* this._getIterator(...args);
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Iterate over `[key, value]` pairs (may yield `undefined` values).
|
|
552
|
+
* @returns Iterator of `[K, V | undefined]`.
|
|
553
|
+
* @remarks Time O(n), Space O(1)
|
|
554
|
+
*/
|
|
555
|
+
*entries() {
|
|
556
|
+
for (const item of this) {
|
|
557
|
+
yield item;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Iterate over keys only.
|
|
562
|
+
* @returns Iterator of keys.
|
|
563
|
+
* @remarks Time O(n), Space O(1)
|
|
564
|
+
*/
|
|
565
|
+
*keys() {
|
|
566
|
+
for (const item of this) {
|
|
567
|
+
yield item[0];
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Iterate over values only.
|
|
572
|
+
* @returns Iterator of values.
|
|
573
|
+
* @remarks Time O(n), Space O(1)
|
|
574
|
+
*/
|
|
575
|
+
*values() {
|
|
576
|
+
for (const item of this) {
|
|
577
|
+
yield item[1];
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Test whether all entries satisfy the predicate.
|
|
582
|
+
* @param predicate - `(key, value, index, self) => boolean`.
|
|
583
|
+
* @param thisArg - Optional `this` for callback.
|
|
584
|
+
* @returns `true` if all pass; otherwise `false`.
|
|
585
|
+
* @remarks Time O(n), Space O(1)
|
|
586
|
+
*/
|
|
587
|
+
every(predicate, thisArg) {
|
|
588
|
+
let index = 0;
|
|
589
|
+
for (const item of this) {
|
|
590
|
+
if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
591
|
+
return false;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Test whether any entry satisfies the predicate.
|
|
598
|
+
* @param predicate - `(key, value, index, self) => boolean`.
|
|
599
|
+
* @param thisArg - Optional `this` for callback.
|
|
600
|
+
* @returns `true` if any passes; otherwise `false`.
|
|
601
|
+
* @remarks Time O(n), Space O(1)
|
|
602
|
+
*/
|
|
603
|
+
some(predicate, thisArg) {
|
|
604
|
+
let index = 0;
|
|
605
|
+
for (const item of this) {
|
|
606
|
+
if (predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
607
|
+
return true;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return false;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Visit each entry, left-to-right.
|
|
614
|
+
* @param callbackfn - `(key, value, index, self) => void`.
|
|
615
|
+
* @param thisArg - Optional `this` for callback.
|
|
616
|
+
* @remarks Time O(n), Space O(1)
|
|
617
|
+
*/
|
|
618
|
+
forEach(callbackfn, thisArg) {
|
|
619
|
+
let index = 0;
|
|
620
|
+
for (const item of this) {
|
|
621
|
+
const [key, value] = item;
|
|
622
|
+
callbackfn.call(thisArg, value, key, index++, this);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Find the first entry that matches a predicate.
|
|
627
|
+
* @param callbackfn - `(key, value, index, self) => boolean`.
|
|
628
|
+
* @param thisArg - Optional `this` for callback.
|
|
629
|
+
* @returns Matching `[key, value]` or `undefined`.
|
|
630
|
+
* @remarks Time O(n), Space O(1)
|
|
631
|
+
*/
|
|
632
|
+
find(callbackfn, thisArg) {
|
|
633
|
+
let index = 0;
|
|
634
|
+
for (const item of this) {
|
|
635
|
+
const [key, value] = item;
|
|
636
|
+
if (callbackfn.call(thisArg, value, key, index++, this)) return item;
|
|
637
|
+
}
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Whether the given key exists.
|
|
642
|
+
* @param key - Key to test.
|
|
643
|
+
* @returns `true` if found; otherwise `false`.
|
|
644
|
+
* @remarks Time O(n) generic, Space O(1)
|
|
645
|
+
*/
|
|
646
|
+
has(key) {
|
|
647
|
+
for (const item of this) {
|
|
648
|
+
const [itemKey] = item;
|
|
649
|
+
if (itemKey === key) return true;
|
|
650
|
+
}
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Whether there exists an entry with the given value.
|
|
655
|
+
* @param value - Value to test.
|
|
656
|
+
* @returns `true` if found; otherwise `false`.
|
|
657
|
+
* @remarks Time O(n), Space O(1)
|
|
658
|
+
*/
|
|
659
|
+
hasValue(value) {
|
|
660
|
+
for (const [, elementValue] of this) {
|
|
661
|
+
if (elementValue === value) return true;
|
|
662
|
+
}
|
|
663
|
+
return false;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Get the value under a key.
|
|
667
|
+
* @param key - Key to look up.
|
|
668
|
+
* @returns Value or `undefined`.
|
|
669
|
+
* @remarks Time O(n) generic, Space O(1)
|
|
670
|
+
*/
|
|
671
|
+
get(key) {
|
|
672
|
+
for (const item of this) {
|
|
673
|
+
const [itemKey, value] = item;
|
|
674
|
+
if (itemKey === key) return value;
|
|
675
|
+
}
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Reduce entries into a single accumulator.
|
|
680
|
+
* @param callbackfn - `(acc, value, key, index, self) => acc`.
|
|
681
|
+
* @param initialValue - Initial accumulator.
|
|
682
|
+
* @returns Final accumulator.
|
|
683
|
+
* @remarks Time O(n), Space O(1)
|
|
684
|
+
*/
|
|
685
|
+
reduce(callbackfn, initialValue) {
|
|
686
|
+
let accumulator = initialValue;
|
|
687
|
+
let index = 0;
|
|
688
|
+
for (const item of this) {
|
|
689
|
+
const [key, value] = item;
|
|
690
|
+
accumulator = callbackfn(accumulator, value, key, index++, this);
|
|
691
|
+
}
|
|
692
|
+
return accumulator;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Converts data structure to `[key, value]` pairs.
|
|
696
|
+
* @returns Array of entries.
|
|
697
|
+
* @remarks Time O(n), Space O(n)
|
|
698
|
+
*/
|
|
699
|
+
toArray() {
|
|
700
|
+
return [...this];
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
|
|
704
|
+
* @returns Array of entries (default) or a string.
|
|
705
|
+
* @remarks Time O(n), Space O(n)
|
|
706
|
+
*/
|
|
707
|
+
toVisual() {
|
|
708
|
+
return [...this];
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Print a human-friendly representation to the console.
|
|
712
|
+
* @remarks Time O(n), Space O(n)
|
|
713
|
+
*/
|
|
714
|
+
print() {
|
|
715
|
+
console.log(this.toVisual());
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
|
|
540
719
|
// src/data-structures/queue/queue.ts
|
|
541
720
|
var Queue = class _Queue extends LinearBase {
|
|
542
721
|
/**
|
|
@@ -591,18 +770,94 @@ var binaryTreeTyped = (() => {
|
|
|
591
770
|
this._autoCompactRatio = value;
|
|
592
771
|
}
|
|
593
772
|
/**
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
773
|
+
* Get the number of elements currently in the queue.
|
|
774
|
+
* @remarks Time O(1), Space O(1)
|
|
775
|
+
* @returns Current length.
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
* @example
|
|
809
|
+
* // Track queue length
|
|
810
|
+
* const q = new Queue<number>();
|
|
811
|
+
* console.log(q.length); // 0;
|
|
812
|
+
* q.push(1);
|
|
813
|
+
* q.push(2);
|
|
814
|
+
* console.log(q.length); // 2;
|
|
815
|
+
*/
|
|
598
816
|
get length() {
|
|
599
817
|
return this.elements.length - this._offset;
|
|
600
818
|
}
|
|
601
819
|
/**
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
820
|
+
* Get the first element (front) without removing it.
|
|
821
|
+
* @remarks Time O(1), Space O(1)
|
|
822
|
+
* @returns Front element or undefined.
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
* @example
|
|
856
|
+
* // View the front element
|
|
857
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
858
|
+
* console.log(q.first); // 'first';
|
|
859
|
+
* console.log(q.length); // 3;
|
|
860
|
+
*/
|
|
606
861
|
get first() {
|
|
607
862
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
608
863
|
}
|
|
@@ -625,19 +880,111 @@ var binaryTreeTyped = (() => {
|
|
|
625
880
|
return new _Queue(elements);
|
|
626
881
|
}
|
|
627
882
|
/**
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
883
|
+
* Check whether the queue is empty.
|
|
884
|
+
* @remarks Time O(1), Space O(1)
|
|
885
|
+
* @returns True if length is 0.
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
* @example
|
|
919
|
+
* // Queue for...of iteration and isEmpty check
|
|
920
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
921
|
+
*
|
|
922
|
+
* const elements: string[] = [];
|
|
923
|
+
* for (const item of queue) {
|
|
924
|
+
* elements.push(item);
|
|
925
|
+
* }
|
|
926
|
+
*
|
|
927
|
+
* // Verify all elements are iterated in order
|
|
928
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
929
|
+
*
|
|
930
|
+
* // Process all elements
|
|
931
|
+
* while (queue.length > 0) {
|
|
932
|
+
* queue.shift();
|
|
933
|
+
* }
|
|
934
|
+
*
|
|
935
|
+
* console.log(queue.length); // 0;
|
|
936
|
+
*/
|
|
632
937
|
isEmpty() {
|
|
633
938
|
return this.length === 0;
|
|
634
939
|
}
|
|
635
940
|
/**
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
941
|
+
* Enqueue one element at the back.
|
|
942
|
+
* @remarks Time O(1), Space O(1)
|
|
943
|
+
* @param element - Element to enqueue.
|
|
944
|
+
* @returns True on success.
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
* @example
|
|
978
|
+
* // basic Queue creation and push operation
|
|
979
|
+
* // Create a simple Queue with initial values
|
|
980
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
981
|
+
*
|
|
982
|
+
* // Verify the queue maintains insertion order
|
|
983
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
984
|
+
*
|
|
985
|
+
* // Check length
|
|
986
|
+
* console.log(queue.length); // 5;
|
|
987
|
+
*/
|
|
641
988
|
push(element) {
|
|
642
989
|
this.elements.push(element);
|
|
643
990
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -658,10 +1005,56 @@ var binaryTreeTyped = (() => {
|
|
|
658
1005
|
return ans;
|
|
659
1006
|
}
|
|
660
1007
|
/**
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
1008
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1009
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1010
|
+
* @returns Removed element or undefined.
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
|
|
1041
|
+
|
|
1042
|
+
|
|
1043
|
+
* @example
|
|
1044
|
+
* // Queue shift and peek operations
|
|
1045
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
1046
|
+
*
|
|
1047
|
+
* // Peek at the front element without removing it
|
|
1048
|
+
* console.log(queue.first); // 10;
|
|
1049
|
+
*
|
|
1050
|
+
* // Remove and get the first element (FIFO)
|
|
1051
|
+
* const first = queue.shift();
|
|
1052
|
+
* console.log(first); // 10;
|
|
1053
|
+
*
|
|
1054
|
+
* // Verify remaining elements and length decreased
|
|
1055
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
1056
|
+
* console.log(queue.length); // 3;
|
|
1057
|
+
*/
|
|
665
1058
|
shift() {
|
|
666
1059
|
if (this.length === 0) return void 0;
|
|
667
1060
|
const first = this.first;
|
|
@@ -670,11 +1063,45 @@ var binaryTreeTyped = (() => {
|
|
|
670
1063
|
return first;
|
|
671
1064
|
}
|
|
672
1065
|
/**
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
1066
|
+
* Delete the first occurrence of a specific element.
|
|
1067
|
+
* @remarks Time O(N), Space O(1)
|
|
1068
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
1069
|
+
* @returns True if an element was removed.
|
|
1070
|
+
|
|
1071
|
+
|
|
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
|
+
* @example
|
|
1100
|
+
* // Remove specific element
|
|
1101
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
1102
|
+
* q.delete(2);
|
|
1103
|
+
* console.log(q.length); // 3;
|
|
1104
|
+
*/
|
|
678
1105
|
delete(element) {
|
|
679
1106
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
680
1107
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -685,11 +1112,45 @@ var binaryTreeTyped = (() => {
|
|
|
685
1112
|
return false;
|
|
686
1113
|
}
|
|
687
1114
|
/**
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
1115
|
+
* Get the element at a given logical index.
|
|
1116
|
+
* @remarks Time O(1), Space O(1)
|
|
1117
|
+
* @param index - Zero-based index from the front.
|
|
1118
|
+
* @returns Element or undefined.
|
|
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
|
+
|
|
1147
|
+
|
|
1148
|
+
* @example
|
|
1149
|
+
* // Access element by index
|
|
1150
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
1151
|
+
* console.log(q.at(0)); // 'a';
|
|
1152
|
+
* console.log(q.at(2)); // 'c';
|
|
1153
|
+
*/
|
|
693
1154
|
at(index) {
|
|
694
1155
|
if (index < 0 || index >= this.length) return void 0;
|
|
695
1156
|
return this._elements[this._offset + index];
|
|
@@ -741,19 +1202,90 @@ var binaryTreeTyped = (() => {
|
|
|
741
1202
|
return this;
|
|
742
1203
|
}
|
|
743
1204
|
/**
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
1205
|
+
* Remove all elements and reset offset.
|
|
1206
|
+
* @remarks Time O(1), Space O(1)
|
|
1207
|
+
* @returns void
|
|
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
|
+
|
|
1238
|
+
* @example
|
|
1239
|
+
* // Remove all elements
|
|
1240
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1241
|
+
* q.clear();
|
|
1242
|
+
* console.log(q.length); // 0;
|
|
1243
|
+
*/
|
|
748
1244
|
clear() {
|
|
749
1245
|
this._elements = [];
|
|
750
1246
|
this._offset = 0;
|
|
751
1247
|
}
|
|
752
1248
|
/**
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
1249
|
+
* Compact storage by discarding consumed head elements.
|
|
1250
|
+
* @remarks Time O(N), Space O(N)
|
|
1251
|
+
* @returns True when compaction performed.
|
|
1252
|
+
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
|
|
1270
|
+
|
|
1271
|
+
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
|
|
1275
|
+
|
|
1276
|
+
|
|
1277
|
+
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
|
|
1281
|
+
* @example
|
|
1282
|
+
* // Reclaim unused memory
|
|
1283
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1284
|
+
* q.shift();
|
|
1285
|
+
* q.shift();
|
|
1286
|
+
* q.compact();
|
|
1287
|
+
* console.log(q.length); // 3;
|
|
1288
|
+
*/
|
|
757
1289
|
compact() {
|
|
758
1290
|
this._elements = this.elements.slice(this._offset);
|
|
759
1291
|
this._offset = 0;
|
|
@@ -779,10 +1311,47 @@ var binaryTreeTyped = (() => {
|
|
|
779
1311
|
return removed;
|
|
780
1312
|
}
|
|
781
1313
|
/**
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
1314
|
+
* Deep clone this queue and its parameters.
|
|
1315
|
+
* @remarks Time O(N), Space O(N)
|
|
1316
|
+
* @returns A new queue with the same content and options.
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
|
|
1346
|
+
|
|
1347
|
+
* @example
|
|
1348
|
+
* // Create independent copy
|
|
1349
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1350
|
+
* const copy = q.clone();
|
|
1351
|
+
* copy.shift();
|
|
1352
|
+
* console.log(q.length); // 3;
|
|
1353
|
+
* console.log(copy.length); // 2;
|
|
1354
|
+
*/
|
|
786
1355
|
clone() {
|
|
787
1356
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
788
1357
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -790,12 +1359,47 @@ var binaryTreeTyped = (() => {
|
|
|
790
1359
|
return out;
|
|
791
1360
|
}
|
|
792
1361
|
/**
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
1362
|
+
* Filter elements into a new queue of the same class.
|
|
1363
|
+
* @remarks Time O(N), Space O(N)
|
|
1364
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
1365
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
1366
|
+
* @returns A new queue with kept elements.
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
|
|
1370
|
+
|
|
1371
|
+
|
|
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
|
+
* @example
|
|
1398
|
+
* // Filter elements
|
|
1399
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1400
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
1401
|
+
* console.log(evens.length); // 2;
|
|
1402
|
+
*/
|
|
799
1403
|
filter(predicate, thisArg) {
|
|
800
1404
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
801
1405
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -807,15 +1411,49 @@ var binaryTreeTyped = (() => {
|
|
|
807
1411
|
return out;
|
|
808
1412
|
}
|
|
809
1413
|
/**
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
1414
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
1415
|
+
* @remarks Time O(N), Space O(N)
|
|
1416
|
+
* @template EM
|
|
1417
|
+
* @template RM
|
|
1418
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
1419
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
1420
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1421
|
+
* @returns A new Queue with mapped elements.
|
|
1422
|
+
|
|
1423
|
+
|
|
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
|
+
* @example
|
|
1452
|
+
* // Transform elements
|
|
1453
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1454
|
+
* const doubled = q.map(x => x * 2);
|
|
1455
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
1456
|
+
*/
|
|
819
1457
|
map(callback, options, thisArg) {
|
|
820
1458
|
var _a, _b;
|
|
821
1459
|
const out = new this.constructor([], {
|
|
@@ -904,185 +1542,6 @@ var binaryTreeTyped = (() => {
|
|
|
904
1542
|
}
|
|
905
1543
|
};
|
|
906
1544
|
|
|
907
|
-
// src/data-structures/base/iterable-entry-base.ts
|
|
908
|
-
var IterableEntryBase = class {
|
|
909
|
-
/**
|
|
910
|
-
* Default iterator yielding `[key, value]` entries.
|
|
911
|
-
* @returns Iterator of `[K, V]`.
|
|
912
|
-
* @remarks Time O(n) to iterate, Space O(1)
|
|
913
|
-
*/
|
|
914
|
-
*[Symbol.iterator](...args) {
|
|
915
|
-
yield* this._getIterator(...args);
|
|
916
|
-
}
|
|
917
|
-
/**
|
|
918
|
-
* Iterate over `[key, value]` pairs (may yield `undefined` values).
|
|
919
|
-
* @returns Iterator of `[K, V | undefined]`.
|
|
920
|
-
* @remarks Time O(n), Space O(1)
|
|
921
|
-
*/
|
|
922
|
-
*entries() {
|
|
923
|
-
for (const item of this) {
|
|
924
|
-
yield item;
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
/**
|
|
928
|
-
* Iterate over keys only.
|
|
929
|
-
* @returns Iterator of keys.
|
|
930
|
-
* @remarks Time O(n), Space O(1)
|
|
931
|
-
*/
|
|
932
|
-
*keys() {
|
|
933
|
-
for (const item of this) {
|
|
934
|
-
yield item[0];
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
/**
|
|
938
|
-
* Iterate over values only.
|
|
939
|
-
* @returns Iterator of values.
|
|
940
|
-
* @remarks Time O(n), Space O(1)
|
|
941
|
-
*/
|
|
942
|
-
*values() {
|
|
943
|
-
for (const item of this) {
|
|
944
|
-
yield item[1];
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
/**
|
|
948
|
-
* Test whether all entries satisfy the predicate.
|
|
949
|
-
* @param predicate - `(key, value, index, self) => boolean`.
|
|
950
|
-
* @param thisArg - Optional `this` for callback.
|
|
951
|
-
* @returns `true` if all pass; otherwise `false`.
|
|
952
|
-
* @remarks Time O(n), Space O(1)
|
|
953
|
-
*/
|
|
954
|
-
every(predicate, thisArg) {
|
|
955
|
-
let index = 0;
|
|
956
|
-
for (const item of this) {
|
|
957
|
-
if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
958
|
-
return false;
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
return true;
|
|
962
|
-
}
|
|
963
|
-
/**
|
|
964
|
-
* Test whether any entry satisfies the predicate.
|
|
965
|
-
* @param predicate - `(key, value, index, self) => boolean`.
|
|
966
|
-
* @param thisArg - Optional `this` for callback.
|
|
967
|
-
* @returns `true` if any passes; otherwise `false`.
|
|
968
|
-
* @remarks Time O(n), Space O(1)
|
|
969
|
-
*/
|
|
970
|
-
some(predicate, thisArg) {
|
|
971
|
-
let index = 0;
|
|
972
|
-
for (const item of this) {
|
|
973
|
-
if (predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
974
|
-
return true;
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
return false;
|
|
978
|
-
}
|
|
979
|
-
/**
|
|
980
|
-
* Visit each entry, left-to-right.
|
|
981
|
-
* @param callbackfn - `(key, value, index, self) => void`.
|
|
982
|
-
* @param thisArg - Optional `this` for callback.
|
|
983
|
-
* @remarks Time O(n), Space O(1)
|
|
984
|
-
*/
|
|
985
|
-
forEach(callbackfn, thisArg) {
|
|
986
|
-
let index = 0;
|
|
987
|
-
for (const item of this) {
|
|
988
|
-
const [key, value] = item;
|
|
989
|
-
callbackfn.call(thisArg, value, key, index++, this);
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
/**
|
|
993
|
-
* Find the first entry that matches a predicate.
|
|
994
|
-
* @param callbackfn - `(key, value, index, self) => boolean`.
|
|
995
|
-
* @param thisArg - Optional `this` for callback.
|
|
996
|
-
* @returns Matching `[key, value]` or `undefined`.
|
|
997
|
-
* @remarks Time O(n), Space O(1)
|
|
998
|
-
*/
|
|
999
|
-
find(callbackfn, thisArg) {
|
|
1000
|
-
let index = 0;
|
|
1001
|
-
for (const item of this) {
|
|
1002
|
-
const [key, value] = item;
|
|
1003
|
-
if (callbackfn.call(thisArg, value, key, index++, this)) return item;
|
|
1004
|
-
}
|
|
1005
|
-
return;
|
|
1006
|
-
}
|
|
1007
|
-
/**
|
|
1008
|
-
* Whether the given key exists.
|
|
1009
|
-
* @param key - Key to test.
|
|
1010
|
-
* @returns `true` if found; otherwise `false`.
|
|
1011
|
-
* @remarks Time O(n) generic, Space O(1)
|
|
1012
|
-
*/
|
|
1013
|
-
has(key) {
|
|
1014
|
-
for (const item of this) {
|
|
1015
|
-
const [itemKey] = item;
|
|
1016
|
-
if (itemKey === key) return true;
|
|
1017
|
-
}
|
|
1018
|
-
return false;
|
|
1019
|
-
}
|
|
1020
|
-
/**
|
|
1021
|
-
* Whether there exists an entry with the given value.
|
|
1022
|
-
* @param value - Value to test.
|
|
1023
|
-
* @returns `true` if found; otherwise `false`.
|
|
1024
|
-
* @remarks Time O(n), Space O(1)
|
|
1025
|
-
*/
|
|
1026
|
-
hasValue(value) {
|
|
1027
|
-
for (const [, elementValue] of this) {
|
|
1028
|
-
if (elementValue === value) return true;
|
|
1029
|
-
}
|
|
1030
|
-
return false;
|
|
1031
|
-
}
|
|
1032
|
-
/**
|
|
1033
|
-
* Get the value under a key.
|
|
1034
|
-
* @param key - Key to look up.
|
|
1035
|
-
* @returns Value or `undefined`.
|
|
1036
|
-
* @remarks Time O(n) generic, Space O(1)
|
|
1037
|
-
*/
|
|
1038
|
-
get(key) {
|
|
1039
|
-
for (const item of this) {
|
|
1040
|
-
const [itemKey, value] = item;
|
|
1041
|
-
if (itemKey === key) return value;
|
|
1042
|
-
}
|
|
1043
|
-
return;
|
|
1044
|
-
}
|
|
1045
|
-
/**
|
|
1046
|
-
* Reduce entries into a single accumulator.
|
|
1047
|
-
* @param callbackfn - `(acc, value, key, index, self) => acc`.
|
|
1048
|
-
* @param initialValue - Initial accumulator.
|
|
1049
|
-
* @returns Final accumulator.
|
|
1050
|
-
* @remarks Time O(n), Space O(1)
|
|
1051
|
-
*/
|
|
1052
|
-
reduce(callbackfn, initialValue) {
|
|
1053
|
-
let accumulator = initialValue;
|
|
1054
|
-
let index = 0;
|
|
1055
|
-
for (const item of this) {
|
|
1056
|
-
const [key, value] = item;
|
|
1057
|
-
accumulator = callbackfn(accumulator, value, key, index++, this);
|
|
1058
|
-
}
|
|
1059
|
-
return accumulator;
|
|
1060
|
-
}
|
|
1061
|
-
/**
|
|
1062
|
-
* Converts data structure to `[key, value]` pairs.
|
|
1063
|
-
* @returns Array of entries.
|
|
1064
|
-
* @remarks Time O(n), Space O(n)
|
|
1065
|
-
*/
|
|
1066
|
-
toArray() {
|
|
1067
|
-
return [...this];
|
|
1068
|
-
}
|
|
1069
|
-
/**
|
|
1070
|
-
* Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
|
|
1071
|
-
* @returns Array of entries (default) or a string.
|
|
1072
|
-
* @remarks Time O(n), Space O(n)
|
|
1073
|
-
*/
|
|
1074
|
-
toVisual() {
|
|
1075
|
-
return [...this];
|
|
1076
|
-
}
|
|
1077
|
-
/**
|
|
1078
|
-
* Print a human-friendly representation to the console.
|
|
1079
|
-
* @remarks Time O(n), Space O(n)
|
|
1080
|
-
*/
|
|
1081
|
-
print() {
|
|
1082
|
-
console.log(this.toVisual());
|
|
1083
|
-
}
|
|
1084
|
-
};
|
|
1085
|
-
|
|
1086
1545
|
// src/data-structures/binary-tree/binary-tree.ts
|
|
1087
1546
|
var BinaryTreeNode = class {
|
|
1088
1547
|
/**
|
|
@@ -1458,23 +1917,113 @@ var binaryTreeTyped = (() => {
|
|
|
1458
1917
|
return isComparable(key);
|
|
1459
1918
|
}
|
|
1460
1919
|
/**
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1920
|
+
* Adds a new node to the tree.
|
|
1921
|
+
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation adds the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
|
|
1922
|
+
*
|
|
1923
|
+
* @param keyNodeOrEntry - The key, node, or entry to add.
|
|
1924
|
+
* @returns True if the addition was successful, false otherwise.
|
|
1925
|
+
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
|
|
1932
|
+
|
|
1933
|
+
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
|
|
1937
|
+
|
|
1938
|
+
|
|
1939
|
+
|
|
1940
|
+
|
|
1941
|
+
|
|
1942
|
+
|
|
1943
|
+
|
|
1944
|
+
|
|
1945
|
+
|
|
1946
|
+
|
|
1947
|
+
|
|
1948
|
+
|
|
1949
|
+
|
|
1950
|
+
|
|
1951
|
+
|
|
1952
|
+
* @example
|
|
1953
|
+
* // Add a single node
|
|
1954
|
+
* const tree = new BinaryTree<number>();
|
|
1955
|
+
* tree.add(1);
|
|
1956
|
+
* tree.add(2);
|
|
1957
|
+
* tree.add(3);
|
|
1958
|
+
* console.log(tree.size); // 3;
|
|
1959
|
+
* console.log(tree.has(1)); // true;
|
|
1960
|
+
*/
|
|
1467
1961
|
add(keyNodeOrEntry) {
|
|
1468
1962
|
return this.set(keyNodeOrEntry);
|
|
1469
1963
|
}
|
|
1470
1964
|
/**
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1965
|
+
* Adds or updates a new node to the tree.
|
|
1966
|
+
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation sets the node at the first available position in a level-order (BFS) traversal. This is NOT a Binary Search Tree insertion. Time O(N), where N is the number of nodes. It must traverse level-by-level to find an empty slot. Space O(N) in the worst case for the BFS queue (e.g., a full last level).
|
|
1967
|
+
*
|
|
1968
|
+
* @param keyNodeOrEntry - The key, node, or entry to set or update.
|
|
1969
|
+
* @param [value] - The value, if providing just a key.
|
|
1970
|
+
* @returns True if the addition was successful, false otherwise.
|
|
1971
|
+
|
|
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
|
+
* @example
|
|
2004
|
+
* // basic BinaryTree creation and insertion
|
|
2005
|
+
* // Create a BinaryTree with entries
|
|
2006
|
+
* const entries: [number, string][] = [
|
|
2007
|
+
* [6, 'six'],
|
|
2008
|
+
* [1, 'one'],
|
|
2009
|
+
* [2, 'two'],
|
|
2010
|
+
* [7, 'seven'],
|
|
2011
|
+
* [5, 'five'],
|
|
2012
|
+
* [3, 'three'],
|
|
2013
|
+
* [4, 'four'],
|
|
2014
|
+
* [9, 'nine'],
|
|
2015
|
+
* [8, 'eight']
|
|
2016
|
+
* ];
|
|
2017
|
+
*
|
|
2018
|
+
* const tree = new BinaryTree(entries);
|
|
2019
|
+
*
|
|
2020
|
+
* // Verify size
|
|
2021
|
+
* console.log(tree.size); // 9;
|
|
2022
|
+
*
|
|
2023
|
+
* // Add new element
|
|
2024
|
+
* tree.set(10, 'ten');
|
|
2025
|
+
* console.log(tree.size); // 10;
|
|
2026
|
+
*/
|
|
1478
2027
|
set(keyNodeOrEntry, value) {
|
|
1479
2028
|
const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
1480
2029
|
if (newNode === void 0) return false;
|
|
@@ -1519,23 +2068,86 @@ var binaryTreeTyped = (() => {
|
|
|
1519
2068
|
return false;
|
|
1520
2069
|
}
|
|
1521
2070
|
/**
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
2071
|
+
* Adds multiple items to the tree.
|
|
2072
|
+
* @remarks Time O(N * M), where N is the number of items to set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
|
|
2073
|
+
*
|
|
2074
|
+
* @param keysNodesEntriesOrRaws - An iterable of items to set.
|
|
2075
|
+
* @returns An array of booleans indicating the success of each individual `set` operation.
|
|
2076
|
+
|
|
2077
|
+
|
|
2078
|
+
|
|
2079
|
+
|
|
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
|
+
* @example
|
|
2107
|
+
* // Bulk add
|
|
2108
|
+
* const tree = new BinaryTree<number>();
|
|
2109
|
+
* tree.addMany([1, 2, 3, 4, 5]);
|
|
2110
|
+
* console.log(tree.size); // 5;
|
|
2111
|
+
*/
|
|
1528
2112
|
addMany(keysNodesEntriesOrRaws) {
|
|
1529
2113
|
return this.setMany(keysNodesEntriesOrRaws);
|
|
1530
2114
|
}
|
|
1531
2115
|
/**
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
2116
|
+
* Adds or updates multiple items to the tree.
|
|
2117
|
+
* @remarks Time O(N * M), where N is the number of items to set and M is the size of the tree at insertion (due to O(M) `set` operation). Space O(M) (from `set`) + O(N) (for the `inserted` array).
|
|
2118
|
+
*
|
|
2119
|
+
* @param keysNodesEntriesOrRaws - An iterable of items to set or update.
|
|
2120
|
+
* @param [values] - An optional parallel iterable of values.
|
|
2121
|
+
* @returns An array of booleans indicating the success of each individual `set` operation.
|
|
2122
|
+
|
|
2123
|
+
|
|
2124
|
+
|
|
2125
|
+
|
|
2126
|
+
|
|
2127
|
+
|
|
2128
|
+
|
|
2129
|
+
|
|
2130
|
+
|
|
2131
|
+
|
|
2132
|
+
|
|
2133
|
+
|
|
2134
|
+
|
|
2135
|
+
|
|
2136
|
+
|
|
2137
|
+
|
|
2138
|
+
|
|
2139
|
+
|
|
2140
|
+
|
|
2141
|
+
|
|
2142
|
+
|
|
2143
|
+
|
|
2144
|
+
|
|
2145
|
+
* @example
|
|
2146
|
+
* // Set multiple entries
|
|
2147
|
+
* const tree = new BinaryTree<number, string>();
|
|
2148
|
+
* tree.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
2149
|
+
* console.log(tree.size); // 3;
|
|
2150
|
+
*/
|
|
1539
2151
|
setMany(keysNodesEntriesOrRaws, values) {
|
|
1540
2152
|
const inserted = [];
|
|
1541
2153
|
let valuesIterator;
|
|
@@ -1556,11 +2168,47 @@ var binaryTreeTyped = (() => {
|
|
|
1556
2168
|
return inserted;
|
|
1557
2169
|
}
|
|
1558
2170
|
/**
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
2171
|
+
* Merges another tree into this one by seting all its nodes.
|
|
2172
|
+
* @remarks Time O(N * M), same as `setMany`, where N is the size of `anotherTree` and M is the size of this tree. Space O(M) (from `set`).
|
|
2173
|
+
*
|
|
2174
|
+
* @param anotherTree - The tree to merge.
|
|
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
|
+
|
|
2200
|
+
|
|
2201
|
+
|
|
2202
|
+
|
|
2203
|
+
|
|
2204
|
+
|
|
2205
|
+
* @example
|
|
2206
|
+
* // Combine trees
|
|
2207
|
+
* const t1 = new BinaryTree<number>([1, 2]);
|
|
2208
|
+
* const t2 = new BinaryTree<number>([3, 4]);
|
|
2209
|
+
* t1.merge(t2);
|
|
2210
|
+
* console.log(t1.size); // 4;
|
|
2211
|
+
*/
|
|
1564
2212
|
merge(anotherTree) {
|
|
1565
2213
|
this.setMany(anotherTree, []);
|
|
1566
2214
|
}
|
|
@@ -1576,12 +2224,50 @@ var binaryTreeTyped = (() => {
|
|
|
1576
2224
|
this.setMany(keysNodesEntriesOrRaws, values);
|
|
1577
2225
|
}
|
|
1578
2226
|
/**
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
2227
|
+
* Deletes a node from the tree.
|
|
2228
|
+
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). This implementation finds the node, and if it has two children, swaps it with the rightmost node of its left subtree (in-order predecessor) before deleting. Time O(N) in the worst case. O(N) to find the node (`getNode`) and O(H) (which is O(N) worst-case) to find the rightmost node. Space O(1) (if `getNode` is iterative, which it is).
|
|
2229
|
+
*
|
|
2230
|
+
* @param keyNodeEntryRawOrPredicate - The node to delete.
|
|
2231
|
+
* @returns An array containing deletion results (for compatibility with self-balancing trees).
|
|
2232
|
+
|
|
2233
|
+
|
|
2234
|
+
|
|
2235
|
+
|
|
2236
|
+
|
|
2237
|
+
|
|
2238
|
+
|
|
2239
|
+
|
|
2240
|
+
|
|
2241
|
+
|
|
2242
|
+
|
|
2243
|
+
|
|
2244
|
+
|
|
2245
|
+
|
|
2246
|
+
|
|
2247
|
+
|
|
2248
|
+
|
|
2249
|
+
|
|
2250
|
+
|
|
2251
|
+
|
|
2252
|
+
|
|
2253
|
+
|
|
2254
|
+
|
|
2255
|
+
|
|
2256
|
+
|
|
2257
|
+
|
|
2258
|
+
|
|
2259
|
+
|
|
2260
|
+
|
|
2261
|
+
|
|
2262
|
+
|
|
2263
|
+
|
|
2264
|
+
* @example
|
|
2265
|
+
* // Remove a node
|
|
2266
|
+
* const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
|
|
2267
|
+
* tree.delete(3);
|
|
2268
|
+
* console.log(tree.has(3)); // false;
|
|
2269
|
+
* console.log(tree.size); // 4;
|
|
2270
|
+
*/
|
|
1585
2271
|
delete(keyNodeEntryRawOrPredicate) {
|
|
1586
2272
|
const deletedResult = [];
|
|
1587
2273
|
if (!this._root) return deletedResult;
|
|
@@ -1675,14 +2361,48 @@ var binaryTreeTyped = (() => {
|
|
|
1675
2361
|
return this.search(keyNodeEntryOrPredicate, onlyOne, (node) => node, startNode, iterationType);
|
|
1676
2362
|
}
|
|
1677
2363
|
/**
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
2364
|
+
* Gets the first node matching a predicate.
|
|
2365
|
+
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(N) in the worst case (via `search`). Space O(H) or O(N) (via `search`).
|
|
2366
|
+
*
|
|
2367
|
+
* @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
|
|
2368
|
+
* @param [startNode=this._root] - The node to start the search from.
|
|
2369
|
+
* @param [iterationType=this.iterationType] - The traversal method.
|
|
2370
|
+
* @returns The first matching node, or undefined if not found.
|
|
2371
|
+
|
|
2372
|
+
|
|
2373
|
+
|
|
2374
|
+
|
|
2375
|
+
|
|
2376
|
+
|
|
2377
|
+
|
|
2378
|
+
|
|
2379
|
+
|
|
2380
|
+
|
|
2381
|
+
|
|
2382
|
+
|
|
2383
|
+
|
|
2384
|
+
|
|
2385
|
+
|
|
2386
|
+
|
|
2387
|
+
|
|
2388
|
+
|
|
2389
|
+
|
|
2390
|
+
|
|
2391
|
+
|
|
2392
|
+
|
|
2393
|
+
|
|
2394
|
+
|
|
2395
|
+
|
|
2396
|
+
|
|
2397
|
+
|
|
2398
|
+
|
|
2399
|
+
|
|
2400
|
+
|
|
2401
|
+
* @example
|
|
2402
|
+
* // Get node by key
|
|
2403
|
+
* const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'child']]);
|
|
2404
|
+
* console.log(tree.getNode(2)?.value); // 'child';
|
|
2405
|
+
*/
|
|
1686
2406
|
getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1687
2407
|
if (this._isMapMode && keyNodeEntryOrPredicate !== null && keyNodeEntryOrPredicate !== void 0) {
|
|
1688
2408
|
if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
@@ -1694,14 +2414,51 @@ var binaryTreeTyped = (() => {
|
|
|
1694
2414
|
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType)[0];
|
|
1695
2415
|
}
|
|
1696
2416
|
/**
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
2417
|
+
* Gets the value associated with a key.
|
|
2418
|
+
* @remarks Time O(log N), For BST, Red-Black Tree, and AVL Tree subclasses, the worst-case time is O(log N). Time O(1) if in Map mode. O(N) if not in Map mode (uses `getNode`). Space O(1) if in Map mode. O(H) or O(N) otherwise.
|
|
2419
|
+
*
|
|
2420
|
+
* @param keyNodeEntryOrPredicate - The key, node, or entry to get the value for.
|
|
2421
|
+
* @param [startNode=this._root] - The node to start searching from (if not in Map mode).
|
|
2422
|
+
* @param [iterationType=this.iterationType] - The traversal method (if not in Map mode).
|
|
2423
|
+
* @returns The associated value, or undefined.
|
|
2424
|
+
|
|
2425
|
+
|
|
2426
|
+
|
|
2427
|
+
|
|
2428
|
+
|
|
2429
|
+
|
|
2430
|
+
|
|
2431
|
+
|
|
2432
|
+
|
|
2433
|
+
|
|
2434
|
+
|
|
2435
|
+
|
|
2436
|
+
|
|
2437
|
+
|
|
2438
|
+
|
|
2439
|
+
|
|
2440
|
+
|
|
2441
|
+
|
|
2442
|
+
|
|
2443
|
+
|
|
2444
|
+
|
|
2445
|
+
|
|
2446
|
+
|
|
2447
|
+
|
|
2448
|
+
|
|
2449
|
+
|
|
2450
|
+
|
|
2451
|
+
|
|
2452
|
+
|
|
2453
|
+
|
|
2454
|
+
|
|
2455
|
+
|
|
2456
|
+
* @example
|
|
2457
|
+
* // Retrieve value by key
|
|
2458
|
+
* const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'left'], [3, 'right']]);
|
|
2459
|
+
* console.log(tree.get(2)); // 'left';
|
|
2460
|
+
* console.log(tree.get(99)); // undefined;
|
|
2461
|
+
*/
|
|
1705
2462
|
get(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1706
2463
|
var _a, _b;
|
|
1707
2464
|
if (this._isMapMode) {
|
|
@@ -1722,19 +2479,87 @@ var binaryTreeTyped = (() => {
|
|
|
1722
2479
|
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType).length > 0;
|
|
1723
2480
|
}
|
|
1724
2481
|
/**
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
2482
|
+
* Clears the tree of all nodes and values.
|
|
2483
|
+
* @remarks Time O(N) if in Map mode (due to `_store.clear()`), O(1) otherwise. Space O(1)
|
|
2484
|
+
|
|
2485
|
+
|
|
2486
|
+
|
|
2487
|
+
|
|
2488
|
+
|
|
2489
|
+
|
|
2490
|
+
|
|
2491
|
+
|
|
2492
|
+
|
|
2493
|
+
|
|
2494
|
+
|
|
2495
|
+
|
|
2496
|
+
|
|
2497
|
+
|
|
2498
|
+
|
|
2499
|
+
|
|
2500
|
+
|
|
2501
|
+
|
|
2502
|
+
|
|
2503
|
+
|
|
2504
|
+
|
|
2505
|
+
|
|
2506
|
+
|
|
2507
|
+
|
|
2508
|
+
|
|
2509
|
+
|
|
2510
|
+
|
|
2511
|
+
|
|
2512
|
+
|
|
2513
|
+
|
|
2514
|
+
* @example
|
|
2515
|
+
* // Remove all nodes
|
|
2516
|
+
* const tree = new BinaryTree<number>([1, 2, 3]);
|
|
2517
|
+
* tree.clear();
|
|
2518
|
+
* console.log(tree.isEmpty()); // true;
|
|
2519
|
+
*/
|
|
1728
2520
|
clear() {
|
|
1729
2521
|
this._clearNodes();
|
|
1730
2522
|
if (this._isMapMode) this._clearValues();
|
|
1731
2523
|
}
|
|
1732
2524
|
/**
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
2525
|
+
* Checks if the tree is empty.
|
|
2526
|
+
* @remarks Time O(1), Space O(1)
|
|
2527
|
+
*
|
|
2528
|
+
* @returns True if the tree has no nodes, false otherwise.
|
|
2529
|
+
|
|
2530
|
+
|
|
2531
|
+
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
|
|
2535
|
+
|
|
2536
|
+
|
|
2537
|
+
|
|
2538
|
+
|
|
2539
|
+
|
|
2540
|
+
|
|
2541
|
+
|
|
2542
|
+
|
|
2543
|
+
|
|
2544
|
+
|
|
2545
|
+
|
|
2546
|
+
|
|
2547
|
+
|
|
2548
|
+
|
|
2549
|
+
|
|
2550
|
+
|
|
2551
|
+
|
|
2552
|
+
|
|
2553
|
+
|
|
2554
|
+
|
|
2555
|
+
|
|
2556
|
+
|
|
2557
|
+
|
|
2558
|
+
|
|
2559
|
+
* @example
|
|
2560
|
+
* // Check empty
|
|
2561
|
+
* console.log(new BinaryTree().isEmpty()); // true;
|
|
2562
|
+
*/
|
|
1738
2563
|
isEmpty() {
|
|
1739
2564
|
return this._size === 0;
|
|
1740
2565
|
}
|
|
@@ -1749,13 +2574,48 @@ var binaryTreeTyped = (() => {
|
|
|
1749
2574
|
return this.getMinHeight(startNode) + 1 >= this.getHeight(startNode);
|
|
1750
2575
|
}
|
|
1751
2576
|
/**
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
2577
|
+
* Checks if the tree is a valid Binary Search Tree (BST).
|
|
2578
|
+
* @remarks Time O(N), as it must visit every node. Space O(H) for the call stack (recursive) or explicit stack (iterative), where H is the tree height (O(N) worst-case).
|
|
2579
|
+
*
|
|
2580
|
+
* @param [startNode=this._root] - The node to start checking from.
|
|
2581
|
+
* @param [iterationType=this.iterationType] - The traversal method.
|
|
2582
|
+
* @returns True if it's a valid BST, false otherwise.
|
|
2583
|
+
|
|
2584
|
+
|
|
2585
|
+
|
|
2586
|
+
|
|
2587
|
+
|
|
2588
|
+
|
|
2589
|
+
|
|
2590
|
+
|
|
2591
|
+
|
|
2592
|
+
|
|
2593
|
+
|
|
2594
|
+
|
|
2595
|
+
|
|
2596
|
+
|
|
2597
|
+
|
|
2598
|
+
|
|
2599
|
+
|
|
2600
|
+
|
|
2601
|
+
|
|
2602
|
+
|
|
2603
|
+
|
|
2604
|
+
|
|
2605
|
+
|
|
2606
|
+
|
|
2607
|
+
|
|
2608
|
+
|
|
2609
|
+
|
|
2610
|
+
|
|
2611
|
+
|
|
2612
|
+
|
|
2613
|
+
* @example
|
|
2614
|
+
* // Check BST property
|
|
2615
|
+
* const tree = new BinaryTree<number>([1, 2, 3]);
|
|
2616
|
+
* // BinaryTree doesn't guarantee BST order
|
|
2617
|
+
* console.log(typeof tree.isBST()); // 'boolean';
|
|
2618
|
+
*/
|
|
1759
2619
|
isBST(startNode = this._root, iterationType = this.iterationType) {
|
|
1760
2620
|
const startNodeSired = this.ensureNode(startNode);
|
|
1761
2621
|
if (!startNodeSired) return true;
|
|
@@ -1793,13 +2653,50 @@ var binaryTreeTyped = (() => {
|
|
|
1793
2653
|
}
|
|
1794
2654
|
}
|
|
1795
2655
|
/**
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
2656
|
+
* Gets the depth of a node (distance from `startNode`).
|
|
2657
|
+
* @remarks Time O(H), where H is the depth of the `dist` node relative to `startNode`. O(N) worst-case. Space O(1).
|
|
2658
|
+
*
|
|
2659
|
+
* @param dist - The node to find the depth of.
|
|
2660
|
+
* @param [startNode=this._root] - The node to measure depth from (defaults to root).
|
|
2661
|
+
* @returns The depth (0 if `dist` is `startNode`).
|
|
2662
|
+
|
|
2663
|
+
|
|
2664
|
+
|
|
2665
|
+
|
|
2666
|
+
|
|
2667
|
+
|
|
2668
|
+
|
|
2669
|
+
|
|
2670
|
+
|
|
2671
|
+
|
|
2672
|
+
|
|
2673
|
+
|
|
2674
|
+
|
|
2675
|
+
|
|
2676
|
+
|
|
2677
|
+
|
|
2678
|
+
|
|
2679
|
+
|
|
2680
|
+
|
|
2681
|
+
|
|
2682
|
+
|
|
2683
|
+
|
|
2684
|
+
|
|
2685
|
+
|
|
2686
|
+
|
|
2687
|
+
|
|
2688
|
+
|
|
2689
|
+
|
|
2690
|
+
|
|
2691
|
+
|
|
2692
|
+
|
|
2693
|
+
|
|
2694
|
+
* @example
|
|
2695
|
+
* // Get depth of a node
|
|
2696
|
+
* const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
|
|
2697
|
+
* const node = tree.getNode(4);
|
|
2698
|
+
* console.log(tree.getDepth(node!)); // 2;
|
|
2699
|
+
*/
|
|
1803
2700
|
getDepth(dist, startNode = this._root) {
|
|
1804
2701
|
let distEnsured = this.ensureNode(dist);
|
|
1805
2702
|
const beginRootEnsured = this.ensureNode(startNode);
|
|
@@ -1814,13 +2711,49 @@ var binaryTreeTyped = (() => {
|
|
|
1814
2711
|
return depth;
|
|
1815
2712
|
}
|
|
1816
2713
|
/**
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
2714
|
+
* Gets the maximum height of the tree (longest path from startNode to a leaf).
|
|
2715
|
+
* @remarks Time O(N), as it must visit every node. Space O(H) for recursive stack (O(N) worst-case) or O(N) for iterative stack (storing node + depth).
|
|
2716
|
+
*
|
|
2717
|
+
* @param [startNode=this._root] - The node to start measuring from.
|
|
2718
|
+
* @param [iterationType=this.iterationType] - The traversal method.
|
|
2719
|
+
* @returns The height ( -1 for an empty tree, 0 for a single-node tree).
|
|
2720
|
+
|
|
2721
|
+
|
|
2722
|
+
|
|
2723
|
+
|
|
2724
|
+
|
|
2725
|
+
|
|
2726
|
+
|
|
2727
|
+
|
|
2728
|
+
|
|
2729
|
+
|
|
2730
|
+
|
|
2731
|
+
|
|
2732
|
+
|
|
2733
|
+
|
|
2734
|
+
|
|
2735
|
+
|
|
2736
|
+
|
|
2737
|
+
|
|
2738
|
+
|
|
2739
|
+
|
|
2740
|
+
|
|
2741
|
+
|
|
2742
|
+
|
|
2743
|
+
|
|
2744
|
+
|
|
2745
|
+
|
|
2746
|
+
|
|
2747
|
+
|
|
2748
|
+
|
|
2749
|
+
|
|
2750
|
+
|
|
2751
|
+
|
|
2752
|
+
* @example
|
|
2753
|
+
* // Get tree height
|
|
2754
|
+
* const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
|
|
2755
|
+
* console.log(tree.getHeight()); // 2;
|
|
2756
|
+
*/
|
|
1824
2757
|
getHeight(startNode = this._root, iterationType = this.iterationType) {
|
|
1825
2758
|
startNode = this.ensureNode(startNode);
|
|
1826
2759
|
if (!this.isRealNode(startNode)) return -1;
|
|
@@ -2256,24 +3189,95 @@ var binaryTreeTyped = (() => {
|
|
|
2256
3189
|
return ans;
|
|
2257
3190
|
}
|
|
2258
3191
|
/**
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
3192
|
+
* Clones the tree.
|
|
3193
|
+
* @remarks Time O(N * M), where N is the number of nodes and M is the tree size during insertion (due to `bfs` + `set`, and `set` is O(M)). Space O(N) for the new tree and the BFS queue.
|
|
3194
|
+
*
|
|
3195
|
+
* @returns A new, cloned instance of the tree.
|
|
3196
|
+
|
|
3197
|
+
|
|
3198
|
+
|
|
3199
|
+
|
|
3200
|
+
|
|
3201
|
+
|
|
3202
|
+
|
|
3203
|
+
|
|
3204
|
+
|
|
3205
|
+
|
|
3206
|
+
|
|
3207
|
+
|
|
3208
|
+
|
|
3209
|
+
|
|
3210
|
+
|
|
3211
|
+
|
|
3212
|
+
|
|
3213
|
+
|
|
3214
|
+
|
|
3215
|
+
|
|
3216
|
+
|
|
3217
|
+
|
|
3218
|
+
|
|
3219
|
+
|
|
3220
|
+
|
|
3221
|
+
|
|
3222
|
+
|
|
3223
|
+
|
|
3224
|
+
|
|
3225
|
+
|
|
3226
|
+
* @example
|
|
3227
|
+
* // Deep copy
|
|
3228
|
+
* const tree = new BinaryTree<number>([1, 2, 3]);
|
|
3229
|
+
* const copy = tree.clone();
|
|
3230
|
+
* copy.delete(1);
|
|
3231
|
+
* console.log(tree.has(1)); // true;
|
|
3232
|
+
*/
|
|
2264
3233
|
clone() {
|
|
2265
3234
|
const out = this._createInstance();
|
|
2266
3235
|
this._clone(out);
|
|
2267
3236
|
return out;
|
|
2268
3237
|
}
|
|
2269
3238
|
/**
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
3239
|
+
* Creates a new tree containing only the entries that satisfy the predicate.
|
|
3240
|
+
* @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion (O(N) iteration + O(M) `set` for each item). Space O(N) for the new tree.
|
|
3241
|
+
*
|
|
3242
|
+
* @param predicate - A function to test each [key, value] pair.
|
|
3243
|
+
* @param [thisArg] - `this` context for the predicate.
|
|
3244
|
+
* @returns A new, filtered tree.
|
|
3245
|
+
|
|
3246
|
+
|
|
3247
|
+
|
|
3248
|
+
|
|
3249
|
+
|
|
3250
|
+
|
|
3251
|
+
|
|
3252
|
+
|
|
3253
|
+
|
|
3254
|
+
|
|
3255
|
+
|
|
3256
|
+
|
|
3257
|
+
|
|
3258
|
+
|
|
3259
|
+
|
|
3260
|
+
|
|
3261
|
+
|
|
3262
|
+
|
|
3263
|
+
|
|
3264
|
+
|
|
3265
|
+
|
|
3266
|
+
|
|
3267
|
+
|
|
3268
|
+
|
|
3269
|
+
|
|
3270
|
+
|
|
3271
|
+
|
|
3272
|
+
|
|
3273
|
+
|
|
3274
|
+
|
|
3275
|
+
* @example
|
|
3276
|
+
* // Filter nodes by condition
|
|
3277
|
+
* const tree = new BinaryTree<number>([1, 2, 3, 4]);
|
|
3278
|
+
* const result = tree.filter((_, key) => key > 2);
|
|
3279
|
+
* console.log(result.size); // 2;
|
|
3280
|
+
*/
|
|
2277
3281
|
filter(predicate, thisArg) {
|
|
2278
3282
|
const out = this._createInstance();
|
|
2279
3283
|
let i = 0;
|
|
@@ -2281,17 +3285,52 @@ var binaryTreeTyped = (() => {
|
|
|
2281
3285
|
return out;
|
|
2282
3286
|
}
|
|
2283
3287
|
/**
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
3288
|
+
* Creates a new tree by mapping each [key, value] pair to a new entry.
|
|
3289
|
+
* @remarks Time O(N * M), where N is nodes in this tree, and M is size of the new tree during insertion. Space O(N) for the new tree.
|
|
3290
|
+
*
|
|
3291
|
+
* @template MK - New key type.
|
|
3292
|
+
* @template MV - New value type.
|
|
3293
|
+
* @template MR - New raw type.
|
|
3294
|
+
* @param cb - A function to map each [key, value] pair.
|
|
3295
|
+
* @param [options] - Options for the new tree.
|
|
3296
|
+
* @param [thisArg] - `this` context for the callback.
|
|
3297
|
+
* @returns A new, mapped tree.
|
|
3298
|
+
|
|
3299
|
+
|
|
3300
|
+
|
|
3301
|
+
|
|
3302
|
+
|
|
3303
|
+
|
|
3304
|
+
|
|
3305
|
+
|
|
3306
|
+
|
|
3307
|
+
|
|
3308
|
+
|
|
3309
|
+
|
|
3310
|
+
|
|
3311
|
+
|
|
3312
|
+
|
|
3313
|
+
|
|
3314
|
+
|
|
3315
|
+
|
|
3316
|
+
|
|
3317
|
+
|
|
3318
|
+
|
|
3319
|
+
|
|
3320
|
+
|
|
3321
|
+
|
|
3322
|
+
|
|
3323
|
+
|
|
3324
|
+
|
|
3325
|
+
|
|
3326
|
+
|
|
3327
|
+
|
|
3328
|
+
* @example
|
|
3329
|
+
* // Transform to new tree
|
|
3330
|
+
* const tree = new BinaryTree<number, number>([[1, 10], [2, 20]]);
|
|
3331
|
+
* const mapped = tree.map((v, key) => [key, (v ?? 0) + 1] as [number, number]);
|
|
3332
|
+
* console.log([...mapped.values()]); // contains 11;
|
|
3333
|
+
*/
|
|
2295
3334
|
map(cb, options, thisArg) {
|
|
2296
3335
|
const out = this._createLike([], options);
|
|
2297
3336
|
let i = 0;
|
|
@@ -2329,12 +3368,46 @@ var binaryTreeTyped = (() => {
|
|
|
2329
3368
|
return output;
|
|
2330
3369
|
}
|
|
2331
3370
|
/**
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
3371
|
+
* Prints a visual representation of the tree to the console.
|
|
3372
|
+
* @remarks Time O(N) (via `toVisual`). Space O(N*H) or O(N^2) (via `toVisual`).
|
|
3373
|
+
*
|
|
3374
|
+
* @param [options] - Options to control the output.
|
|
3375
|
+
* @param [startNode=this._root] - The node to start printing from.
|
|
3376
|
+
|
|
3377
|
+
|
|
3378
|
+
|
|
3379
|
+
|
|
3380
|
+
|
|
3381
|
+
|
|
3382
|
+
|
|
3383
|
+
|
|
3384
|
+
|
|
3385
|
+
|
|
3386
|
+
|
|
3387
|
+
|
|
3388
|
+
|
|
3389
|
+
|
|
3390
|
+
|
|
3391
|
+
|
|
3392
|
+
|
|
3393
|
+
|
|
3394
|
+
|
|
3395
|
+
|
|
3396
|
+
|
|
3397
|
+
|
|
3398
|
+
|
|
3399
|
+
|
|
3400
|
+
|
|
3401
|
+
|
|
3402
|
+
|
|
3403
|
+
|
|
3404
|
+
|
|
3405
|
+
|
|
3406
|
+
* @example
|
|
3407
|
+
* // Display tree
|
|
3408
|
+
* const tree = new BinaryTree<number>([1, 2, 3]);
|
|
3409
|
+
* expect(() => tree.print()).not.toThrow();
|
|
3410
|
+
*/
|
|
2338
3411
|
print(options, startNode = this._root) {
|
|
2339
3412
|
console.log(this.toVisual(startNode, options));
|
|
2340
3413
|
}
|
|
@@ -2567,7 +3640,6 @@ var binaryTreeTyped = (() => {
|
|
|
2567
3640
|
* @returns Layout information for this subtree.
|
|
2568
3641
|
*/
|
|
2569
3642
|
_displayAux(node, options) {
|
|
2570
|
-
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
2571
3643
|
const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
|
|
2572
3644
|
const newFrame = (n) => ({
|
|
2573
3645
|
node: n,
|