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
package/dist/esm/index.mjs
CHANGED
|
@@ -57,55 +57,6 @@ function makeTrampoline(fn) {
|
|
|
57
57
|
}
|
|
58
58
|
__name(makeTrampoline, "makeTrampoline");
|
|
59
59
|
|
|
60
|
-
// src/common/error.ts
|
|
61
|
-
var ERR = {
|
|
62
|
-
// Range / index
|
|
63
|
-
indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
|
|
64
|
-
invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
|
|
65
|
-
// Type / argument
|
|
66
|
-
invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
|
|
67
|
-
comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
|
|
68
|
-
invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
|
|
69
|
-
notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
|
|
70
|
-
invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
|
|
71
|
-
invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
|
|
72
|
-
invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
|
|
73
|
-
reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
|
|
74
|
-
callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
|
|
75
|
-
// State / operation
|
|
76
|
-
invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
|
|
77
|
-
// Matrix
|
|
78
|
-
matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
|
|
79
|
-
matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
|
|
80
|
-
matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
|
|
81
|
-
matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
|
|
82
|
-
matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// src/common/index.ts
|
|
86
|
-
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
87
|
-
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
88
|
-
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
89
|
-
return DFSOperation2;
|
|
90
|
-
})(DFSOperation || {});
|
|
91
|
-
var Range = class {
|
|
92
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
93
|
-
this.low = low;
|
|
94
|
-
this.high = high;
|
|
95
|
-
this.includeLow = includeLow;
|
|
96
|
-
this.includeHigh = includeHigh;
|
|
97
|
-
}
|
|
98
|
-
static {
|
|
99
|
-
__name(this, "Range");
|
|
100
|
-
}
|
|
101
|
-
// Determine whether a key is within the range
|
|
102
|
-
isInRange(key, comparator) {
|
|
103
|
-
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
104
|
-
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
105
|
-
return lowCheck && highCheck;
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
60
|
// src/data-structures/base/iterable-element-base.ts
|
|
110
61
|
var IterableElementBase = class {
|
|
111
62
|
static {
|
|
@@ -124,7 +75,7 @@ var IterableElementBase = class {
|
|
|
124
75
|
if (options) {
|
|
125
76
|
const { toElementFn } = options;
|
|
126
77
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
127
|
-
else if (toElementFn) throw new TypeError(
|
|
78
|
+
else if (toElementFn) throw new TypeError("toElementFn must be a function type");
|
|
128
79
|
}
|
|
129
80
|
}
|
|
130
81
|
/**
|
|
@@ -287,7 +238,7 @@ var IterableElementBase = class {
|
|
|
287
238
|
acc = initialValue;
|
|
288
239
|
} else {
|
|
289
240
|
const first = iter.next();
|
|
290
|
-
if (first.done) throw new TypeError(
|
|
241
|
+
if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
|
|
291
242
|
acc = first.value;
|
|
292
243
|
index = 1;
|
|
293
244
|
}
|
|
@@ -522,6 +473,237 @@ var LinearBase = class _LinearBase extends IterableElementBase {
|
|
|
522
473
|
}
|
|
523
474
|
};
|
|
524
475
|
|
|
476
|
+
// src/common/error.ts
|
|
477
|
+
var ERR = {
|
|
478
|
+
// Range / index
|
|
479
|
+
indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
|
|
480
|
+
invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
|
|
481
|
+
// Type / argument
|
|
482
|
+
invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
|
|
483
|
+
comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
|
|
484
|
+
invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
|
|
485
|
+
notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
|
|
486
|
+
invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
|
|
487
|
+
invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
|
|
488
|
+
invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
|
|
489
|
+
reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
|
|
490
|
+
callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
|
|
491
|
+
// State / operation
|
|
492
|
+
invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
|
|
493
|
+
// Matrix
|
|
494
|
+
matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
|
|
495
|
+
matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
|
|
496
|
+
matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
|
|
497
|
+
matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
|
|
498
|
+
matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
// src/common/index.ts
|
|
502
|
+
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
503
|
+
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
504
|
+
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
505
|
+
return DFSOperation2;
|
|
506
|
+
})(DFSOperation || {});
|
|
507
|
+
var Range = class {
|
|
508
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
509
|
+
this.low = low;
|
|
510
|
+
this.high = high;
|
|
511
|
+
this.includeLow = includeLow;
|
|
512
|
+
this.includeHigh = includeHigh;
|
|
513
|
+
}
|
|
514
|
+
static {
|
|
515
|
+
__name(this, "Range");
|
|
516
|
+
}
|
|
517
|
+
// Determine whether a key is within the range
|
|
518
|
+
isInRange(key, comparator) {
|
|
519
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
520
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
521
|
+
return lowCheck && highCheck;
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// src/data-structures/base/iterable-entry-base.ts
|
|
526
|
+
var IterableEntryBase = class {
|
|
527
|
+
static {
|
|
528
|
+
__name(this, "IterableEntryBase");
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Default iterator yielding `[key, value]` entries.
|
|
532
|
+
* @returns Iterator of `[K, V]`.
|
|
533
|
+
* @remarks Time O(n) to iterate, Space O(1)
|
|
534
|
+
*/
|
|
535
|
+
*[Symbol.iterator](...args) {
|
|
536
|
+
yield* this._getIterator(...args);
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Iterate over `[key, value]` pairs (may yield `undefined` values).
|
|
540
|
+
* @returns Iterator of `[K, V | undefined]`.
|
|
541
|
+
* @remarks Time O(n), Space O(1)
|
|
542
|
+
*/
|
|
543
|
+
*entries() {
|
|
544
|
+
for (const item of this) {
|
|
545
|
+
yield item;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Iterate over keys only.
|
|
550
|
+
* @returns Iterator of keys.
|
|
551
|
+
* @remarks Time O(n), Space O(1)
|
|
552
|
+
*/
|
|
553
|
+
*keys() {
|
|
554
|
+
for (const item of this) {
|
|
555
|
+
yield item[0];
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Iterate over values only.
|
|
560
|
+
* @returns Iterator of values.
|
|
561
|
+
* @remarks Time O(n), Space O(1)
|
|
562
|
+
*/
|
|
563
|
+
*values() {
|
|
564
|
+
for (const item of this) {
|
|
565
|
+
yield item[1];
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Test whether all entries satisfy the predicate.
|
|
570
|
+
* @param predicate - `(key, value, index, self) => boolean`.
|
|
571
|
+
* @param thisArg - Optional `this` for callback.
|
|
572
|
+
* @returns `true` if all pass; otherwise `false`.
|
|
573
|
+
* @remarks Time O(n), Space O(1)
|
|
574
|
+
*/
|
|
575
|
+
every(predicate, thisArg) {
|
|
576
|
+
let index = 0;
|
|
577
|
+
for (const item of this) {
|
|
578
|
+
if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return true;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Test whether any entry satisfies the predicate.
|
|
586
|
+
* @param predicate - `(key, value, index, self) => boolean`.
|
|
587
|
+
* @param thisArg - Optional `this` for callback.
|
|
588
|
+
* @returns `true` if any passes; otherwise `false`.
|
|
589
|
+
* @remarks Time O(n), Space O(1)
|
|
590
|
+
*/
|
|
591
|
+
some(predicate, thisArg) {
|
|
592
|
+
let index = 0;
|
|
593
|
+
for (const item of this) {
|
|
594
|
+
if (predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return false;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Visit each entry, left-to-right.
|
|
602
|
+
* @param callbackfn - `(key, value, index, self) => void`.
|
|
603
|
+
* @param thisArg - Optional `this` for callback.
|
|
604
|
+
* @remarks Time O(n), Space O(1)
|
|
605
|
+
*/
|
|
606
|
+
forEach(callbackfn, thisArg) {
|
|
607
|
+
let index = 0;
|
|
608
|
+
for (const item of this) {
|
|
609
|
+
const [key, value] = item;
|
|
610
|
+
callbackfn.call(thisArg, value, key, index++, this);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Find the first entry that matches a predicate.
|
|
615
|
+
* @param callbackfn - `(key, value, index, self) => boolean`.
|
|
616
|
+
* @param thisArg - Optional `this` for callback.
|
|
617
|
+
* @returns Matching `[key, value]` or `undefined`.
|
|
618
|
+
* @remarks Time O(n), Space O(1)
|
|
619
|
+
*/
|
|
620
|
+
find(callbackfn, thisArg) {
|
|
621
|
+
let index = 0;
|
|
622
|
+
for (const item of this) {
|
|
623
|
+
const [key, value] = item;
|
|
624
|
+
if (callbackfn.call(thisArg, value, key, index++, this)) return item;
|
|
625
|
+
}
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Whether the given key exists.
|
|
630
|
+
* @param key - Key to test.
|
|
631
|
+
* @returns `true` if found; otherwise `false`.
|
|
632
|
+
* @remarks Time O(n) generic, Space O(1)
|
|
633
|
+
*/
|
|
634
|
+
has(key) {
|
|
635
|
+
for (const item of this) {
|
|
636
|
+
const [itemKey] = item;
|
|
637
|
+
if (itemKey === key) return true;
|
|
638
|
+
}
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Whether there exists an entry with the given value.
|
|
643
|
+
* @param value - Value to test.
|
|
644
|
+
* @returns `true` if found; otherwise `false`.
|
|
645
|
+
* @remarks Time O(n), Space O(1)
|
|
646
|
+
*/
|
|
647
|
+
hasValue(value) {
|
|
648
|
+
for (const [, elementValue] of this) {
|
|
649
|
+
if (elementValue === value) return true;
|
|
650
|
+
}
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Get the value under a key.
|
|
655
|
+
* @param key - Key to look up.
|
|
656
|
+
* @returns Value or `undefined`.
|
|
657
|
+
* @remarks Time O(n) generic, Space O(1)
|
|
658
|
+
*/
|
|
659
|
+
get(key) {
|
|
660
|
+
for (const item of this) {
|
|
661
|
+
const [itemKey, value] = item;
|
|
662
|
+
if (itemKey === key) return value;
|
|
663
|
+
}
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Reduce entries into a single accumulator.
|
|
668
|
+
* @param callbackfn - `(acc, value, key, index, self) => acc`.
|
|
669
|
+
* @param initialValue - Initial accumulator.
|
|
670
|
+
* @returns Final accumulator.
|
|
671
|
+
* @remarks Time O(n), Space O(1)
|
|
672
|
+
*/
|
|
673
|
+
reduce(callbackfn, initialValue) {
|
|
674
|
+
let accumulator = initialValue;
|
|
675
|
+
let index = 0;
|
|
676
|
+
for (const item of this) {
|
|
677
|
+
const [key, value] = item;
|
|
678
|
+
accumulator = callbackfn(accumulator, value, key, index++, this);
|
|
679
|
+
}
|
|
680
|
+
return accumulator;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Converts data structure to `[key, value]` pairs.
|
|
684
|
+
* @returns Array of entries.
|
|
685
|
+
* @remarks Time O(n), Space O(n)
|
|
686
|
+
*/
|
|
687
|
+
toArray() {
|
|
688
|
+
return [...this];
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
|
|
692
|
+
* @returns Array of entries (default) or a string.
|
|
693
|
+
* @remarks Time O(n), Space O(n)
|
|
694
|
+
*/
|
|
695
|
+
toVisual() {
|
|
696
|
+
return [...this];
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Print a human-friendly representation to the console.
|
|
700
|
+
* @remarks Time O(n), Space O(n)
|
|
701
|
+
*/
|
|
702
|
+
print() {
|
|
703
|
+
console.log(this.toVisual());
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
|
|
525
707
|
// src/data-structures/queue/queue.ts
|
|
526
708
|
var Queue = class _Queue extends LinearBase {
|
|
527
709
|
static {
|
|
@@ -578,19 +760,95 @@ var Queue = class _Queue extends LinearBase {
|
|
|
578
760
|
set autoCompactRatio(value) {
|
|
579
761
|
this._autoCompactRatio = value;
|
|
580
762
|
}
|
|
581
|
-
/**
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
763
|
+
/**
|
|
764
|
+
* Get the number of elements currently in the queue.
|
|
765
|
+
* @remarks Time O(1), Space O(1)
|
|
766
|
+
* @returns Current length.
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
* @example
|
|
800
|
+
* // Track queue length
|
|
801
|
+
* const q = new Queue<number>();
|
|
802
|
+
* console.log(q.length); // 0;
|
|
803
|
+
* q.push(1);
|
|
804
|
+
* q.push(2);
|
|
805
|
+
* console.log(q.length); // 2;
|
|
806
|
+
*/
|
|
586
807
|
get length() {
|
|
587
808
|
return this.elements.length - this._offset;
|
|
588
809
|
}
|
|
589
810
|
/**
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
811
|
+
* Get the first element (front) without removing it.
|
|
812
|
+
* @remarks Time O(1), Space O(1)
|
|
813
|
+
* @returns Front element or undefined.
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
* @example
|
|
847
|
+
* // View the front element
|
|
848
|
+
* const q = new Queue<string>(['first', 'second', 'third']);
|
|
849
|
+
* console.log(q.first); // 'first';
|
|
850
|
+
* console.log(q.length); // 3;
|
|
851
|
+
*/
|
|
594
852
|
get first() {
|
|
595
853
|
return this.length > 0 ? this.elements[this._offset] : void 0;
|
|
596
854
|
}
|
|
@@ -613,19 +871,111 @@ var Queue = class _Queue extends LinearBase {
|
|
|
613
871
|
return new _Queue(elements);
|
|
614
872
|
}
|
|
615
873
|
/**
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
874
|
+
* Check whether the queue is empty.
|
|
875
|
+
* @remarks Time O(1), Space O(1)
|
|
876
|
+
* @returns True if length is 0.
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
|
|
909
|
+
* @example
|
|
910
|
+
* // Queue for...of iteration and isEmpty check
|
|
911
|
+
* const queue = new Queue<string>(['A', 'B', 'C', 'D']);
|
|
912
|
+
*
|
|
913
|
+
* const elements: string[] = [];
|
|
914
|
+
* for (const item of queue) {
|
|
915
|
+
* elements.push(item);
|
|
916
|
+
* }
|
|
917
|
+
*
|
|
918
|
+
* // Verify all elements are iterated in order
|
|
919
|
+
* console.log(elements); // ['A', 'B', 'C', 'D'];
|
|
920
|
+
*
|
|
921
|
+
* // Process all elements
|
|
922
|
+
* while (queue.length > 0) {
|
|
923
|
+
* queue.shift();
|
|
924
|
+
* }
|
|
925
|
+
*
|
|
926
|
+
* console.log(queue.length); // 0;
|
|
927
|
+
*/
|
|
620
928
|
isEmpty() {
|
|
621
929
|
return this.length === 0;
|
|
622
930
|
}
|
|
623
931
|
/**
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
932
|
+
* Enqueue one element at the back.
|
|
933
|
+
* @remarks Time O(1), Space O(1)
|
|
934
|
+
* @param element - Element to enqueue.
|
|
935
|
+
* @returns True on success.
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
* @example
|
|
969
|
+
* // basic Queue creation and push operation
|
|
970
|
+
* // Create a simple Queue with initial values
|
|
971
|
+
* const queue = new Queue([1, 2, 3, 4, 5]);
|
|
972
|
+
*
|
|
973
|
+
* // Verify the queue maintains insertion order
|
|
974
|
+
* console.log([...queue]); // [1, 2, 3, 4, 5];
|
|
975
|
+
*
|
|
976
|
+
* // Check length
|
|
977
|
+
* console.log(queue.length); // 5;
|
|
978
|
+
*/
|
|
629
979
|
push(element) {
|
|
630
980
|
this.elements.push(element);
|
|
631
981
|
if (this._maxLen > 0 && this.length > this._maxLen) this.shift();
|
|
@@ -646,10 +996,56 @@ var Queue = class _Queue extends LinearBase {
|
|
|
646
996
|
return ans;
|
|
647
997
|
}
|
|
648
998
|
/**
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
999
|
+
* Dequeue one element from the front (amortized via offset).
|
|
1000
|
+
* @remarks Time O(1) amortized, Space O(1)
|
|
1001
|
+
* @returns Removed element or undefined.
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
* @example
|
|
1035
|
+
* // Queue shift and peek operations
|
|
1036
|
+
* const queue = new Queue<number>([10, 20, 30, 40]);
|
|
1037
|
+
*
|
|
1038
|
+
* // Peek at the front element without removing it
|
|
1039
|
+
* console.log(queue.first); // 10;
|
|
1040
|
+
*
|
|
1041
|
+
* // Remove and get the first element (FIFO)
|
|
1042
|
+
* const first = queue.shift();
|
|
1043
|
+
* console.log(first); // 10;
|
|
1044
|
+
*
|
|
1045
|
+
* // Verify remaining elements and length decreased
|
|
1046
|
+
* console.log([...queue]); // [20, 30, 40];
|
|
1047
|
+
* console.log(queue.length); // 3;
|
|
1048
|
+
*/
|
|
653
1049
|
shift() {
|
|
654
1050
|
if (this.length === 0) return void 0;
|
|
655
1051
|
const first = this.first;
|
|
@@ -658,11 +1054,45 @@ var Queue = class _Queue extends LinearBase {
|
|
|
658
1054
|
return first;
|
|
659
1055
|
}
|
|
660
1056
|
/**
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
1057
|
+
* Delete the first occurrence of a specific element.
|
|
1058
|
+
* @remarks Time O(N), Space O(1)
|
|
1059
|
+
* @param element - Element to remove (strict equality via Object.is).
|
|
1060
|
+
* @returns True if an element was removed.
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
* @example
|
|
1091
|
+
* // Remove specific element
|
|
1092
|
+
* const q = new Queue<number>([1, 2, 3, 2]);
|
|
1093
|
+
* q.delete(2);
|
|
1094
|
+
* console.log(q.length); // 3;
|
|
1095
|
+
*/
|
|
666
1096
|
delete(element) {
|
|
667
1097
|
for (let i = this._offset; i < this.elements.length; i++) {
|
|
668
1098
|
if (Object.is(this.elements[i], element)) {
|
|
@@ -673,11 +1103,45 @@ var Queue = class _Queue extends LinearBase {
|
|
|
673
1103
|
return false;
|
|
674
1104
|
}
|
|
675
1105
|
/**
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
1106
|
+
* Get the element at a given logical index.
|
|
1107
|
+
* @remarks Time O(1), Space O(1)
|
|
1108
|
+
* @param index - Zero-based index from the front.
|
|
1109
|
+
* @returns Element or undefined.
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
* @example
|
|
1140
|
+
* // Access element by index
|
|
1141
|
+
* const q = new Queue<string>(['a', 'b', 'c']);
|
|
1142
|
+
* console.log(q.at(0)); // 'a';
|
|
1143
|
+
* console.log(q.at(2)); // 'c';
|
|
1144
|
+
*/
|
|
681
1145
|
at(index) {
|
|
682
1146
|
if (index < 0 || index >= this.length) return void 0;
|
|
683
1147
|
return this._elements[this._offset + index];
|
|
@@ -729,19 +1193,90 @@ var Queue = class _Queue extends LinearBase {
|
|
|
729
1193
|
return this;
|
|
730
1194
|
}
|
|
731
1195
|
/**
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
1196
|
+
* Remove all elements and reset offset.
|
|
1197
|
+
* @remarks Time O(1), Space O(1)
|
|
1198
|
+
* @returns void
|
|
1199
|
+
|
|
1200
|
+
|
|
1201
|
+
|
|
1202
|
+
|
|
1203
|
+
|
|
1204
|
+
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
* @example
|
|
1230
|
+
* // Remove all elements
|
|
1231
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1232
|
+
* q.clear();
|
|
1233
|
+
* console.log(q.length); // 0;
|
|
1234
|
+
*/
|
|
736
1235
|
clear() {
|
|
737
1236
|
this._elements = [];
|
|
738
1237
|
this._offset = 0;
|
|
739
1238
|
}
|
|
740
1239
|
/**
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
1240
|
+
* Compact storage by discarding consumed head elements.
|
|
1241
|
+
* @remarks Time O(N), Space O(N)
|
|
1242
|
+
* @returns True when compaction performed.
|
|
1243
|
+
|
|
1244
|
+
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
|
|
1270
|
+
|
|
1271
|
+
|
|
1272
|
+
* @example
|
|
1273
|
+
* // Reclaim unused memory
|
|
1274
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1275
|
+
* q.shift();
|
|
1276
|
+
* q.shift();
|
|
1277
|
+
* q.compact();
|
|
1278
|
+
* console.log(q.length); // 3;
|
|
1279
|
+
*/
|
|
745
1280
|
compact() {
|
|
746
1281
|
this._elements = this.elements.slice(this._offset);
|
|
747
1282
|
this._offset = 0;
|
|
@@ -767,10 +1302,47 @@ var Queue = class _Queue extends LinearBase {
|
|
|
767
1302
|
return removed;
|
|
768
1303
|
}
|
|
769
1304
|
/**
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
1305
|
+
* Deep clone this queue and its parameters.
|
|
1306
|
+
* @remarks Time O(N), Space O(N)
|
|
1307
|
+
* @returns A new queue with the same content and options.
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
* @example
|
|
1339
|
+
* // Create independent copy
|
|
1340
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1341
|
+
* const copy = q.clone();
|
|
1342
|
+
* copy.shift();
|
|
1343
|
+
* console.log(q.length); // 3;
|
|
1344
|
+
* console.log(copy.length); // 2;
|
|
1345
|
+
*/
|
|
774
1346
|
clone() {
|
|
775
1347
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
776
1348
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -778,12 +1350,47 @@ var Queue = class _Queue extends LinearBase {
|
|
|
778
1350
|
return out;
|
|
779
1351
|
}
|
|
780
1352
|
/**
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
1353
|
+
* Filter elements into a new queue of the same class.
|
|
1354
|
+
* @remarks Time O(N), Space O(N)
|
|
1355
|
+
* @param predicate - Predicate (element, index, queue) → boolean to keep element.
|
|
1356
|
+
* @param [thisArg] - Value for `this` inside the predicate.
|
|
1357
|
+
* @returns A new queue with kept elements.
|
|
1358
|
+
|
|
1359
|
+
|
|
1360
|
+
|
|
1361
|
+
|
|
1362
|
+
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
|
|
1367
|
+
|
|
1368
|
+
|
|
1369
|
+
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
|
|
1374
|
+
|
|
1375
|
+
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
|
|
1380
|
+
|
|
1381
|
+
|
|
1382
|
+
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
|
|
1388
|
+
* @example
|
|
1389
|
+
* // Filter elements
|
|
1390
|
+
* const q = new Queue<number>([1, 2, 3, 4, 5]);
|
|
1391
|
+
* const evens = q.filter(x => x % 2 === 0);
|
|
1392
|
+
* console.log(evens.length); // 2;
|
|
1393
|
+
*/
|
|
787
1394
|
filter(predicate, thisArg) {
|
|
788
1395
|
const out = this._createInstance({ toElementFn: this.toElementFn, maxLen: this._maxLen });
|
|
789
1396
|
out._setAutoCompactRatio(this._autoCompactRatio);
|
|
@@ -795,15 +1402,49 @@ var Queue = class _Queue extends LinearBase {
|
|
|
795
1402
|
return out;
|
|
796
1403
|
}
|
|
797
1404
|
/**
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
1405
|
+
* Map each element to a new element in a possibly different-typed queue.
|
|
1406
|
+
* @remarks Time O(N), Space O(N)
|
|
1407
|
+
* @template EM
|
|
1408
|
+
* @template RM
|
|
1409
|
+
* @param callback - Mapping function (element, index, queue) → newElement.
|
|
1410
|
+
* @param [options] - Options for the output queue (e.g., toElementFn, maxLen, autoCompactRatio).
|
|
1411
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
1412
|
+
* @returns A new Queue with mapped elements.
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
|
|
1421
|
+
|
|
1422
|
+
|
|
1423
|
+
|
|
1424
|
+
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
* @example
|
|
1443
|
+
* // Transform elements
|
|
1444
|
+
* const q = new Queue<number>([1, 2, 3]);
|
|
1445
|
+
* const doubled = q.map(x => x * 2);
|
|
1446
|
+
* console.log(doubled.toArray()); // [2, 4, 6];
|
|
1447
|
+
*/
|
|
807
1448
|
map(callback, options, thisArg) {
|
|
808
1449
|
const out = new this.constructor([], {
|
|
809
1450
|
toElementFn: options?.toElementFn,
|
|
@@ -890,188 +1531,6 @@ var Queue = class _Queue extends LinearBase {
|
|
|
890
1531
|
}
|
|
891
1532
|
};
|
|
892
1533
|
|
|
893
|
-
// src/data-structures/base/iterable-entry-base.ts
|
|
894
|
-
var IterableEntryBase = class {
|
|
895
|
-
static {
|
|
896
|
-
__name(this, "IterableEntryBase");
|
|
897
|
-
}
|
|
898
|
-
/**
|
|
899
|
-
* Default iterator yielding `[key, value]` entries.
|
|
900
|
-
* @returns Iterator of `[K, V]`.
|
|
901
|
-
* @remarks Time O(n) to iterate, Space O(1)
|
|
902
|
-
*/
|
|
903
|
-
*[Symbol.iterator](...args) {
|
|
904
|
-
yield* this._getIterator(...args);
|
|
905
|
-
}
|
|
906
|
-
/**
|
|
907
|
-
* Iterate over `[key, value]` pairs (may yield `undefined` values).
|
|
908
|
-
* @returns Iterator of `[K, V | undefined]`.
|
|
909
|
-
* @remarks Time O(n), Space O(1)
|
|
910
|
-
*/
|
|
911
|
-
*entries() {
|
|
912
|
-
for (const item of this) {
|
|
913
|
-
yield item;
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
/**
|
|
917
|
-
* Iterate over keys only.
|
|
918
|
-
* @returns Iterator of keys.
|
|
919
|
-
* @remarks Time O(n), Space O(1)
|
|
920
|
-
*/
|
|
921
|
-
*keys() {
|
|
922
|
-
for (const item of this) {
|
|
923
|
-
yield item[0];
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
/**
|
|
927
|
-
* Iterate over values only.
|
|
928
|
-
* @returns Iterator of values.
|
|
929
|
-
* @remarks Time O(n), Space O(1)
|
|
930
|
-
*/
|
|
931
|
-
*values() {
|
|
932
|
-
for (const item of this) {
|
|
933
|
-
yield item[1];
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
/**
|
|
937
|
-
* Test whether all entries satisfy the predicate.
|
|
938
|
-
* @param predicate - `(key, value, index, self) => boolean`.
|
|
939
|
-
* @param thisArg - Optional `this` for callback.
|
|
940
|
-
* @returns `true` if all pass; otherwise `false`.
|
|
941
|
-
* @remarks Time O(n), Space O(1)
|
|
942
|
-
*/
|
|
943
|
-
every(predicate, thisArg) {
|
|
944
|
-
let index = 0;
|
|
945
|
-
for (const item of this) {
|
|
946
|
-
if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
947
|
-
return false;
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
return true;
|
|
951
|
-
}
|
|
952
|
-
/**
|
|
953
|
-
* Test whether any entry satisfies the predicate.
|
|
954
|
-
* @param predicate - `(key, value, index, self) => boolean`.
|
|
955
|
-
* @param thisArg - Optional `this` for callback.
|
|
956
|
-
* @returns `true` if any passes; otherwise `false`.
|
|
957
|
-
* @remarks Time O(n), Space O(1)
|
|
958
|
-
*/
|
|
959
|
-
some(predicate, thisArg) {
|
|
960
|
-
let index = 0;
|
|
961
|
-
for (const item of this) {
|
|
962
|
-
if (predicate.call(thisArg, item[1], item[0], index++, this)) {
|
|
963
|
-
return true;
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
return false;
|
|
967
|
-
}
|
|
968
|
-
/**
|
|
969
|
-
* Visit each entry, left-to-right.
|
|
970
|
-
* @param callbackfn - `(key, value, index, self) => void`.
|
|
971
|
-
* @param thisArg - Optional `this` for callback.
|
|
972
|
-
* @remarks Time O(n), Space O(1)
|
|
973
|
-
*/
|
|
974
|
-
forEach(callbackfn, thisArg) {
|
|
975
|
-
let index = 0;
|
|
976
|
-
for (const item of this) {
|
|
977
|
-
const [key, value] = item;
|
|
978
|
-
callbackfn.call(thisArg, value, key, index++, this);
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
/**
|
|
982
|
-
* Find the first entry that matches a predicate.
|
|
983
|
-
* @param callbackfn - `(key, value, index, self) => boolean`.
|
|
984
|
-
* @param thisArg - Optional `this` for callback.
|
|
985
|
-
* @returns Matching `[key, value]` or `undefined`.
|
|
986
|
-
* @remarks Time O(n), Space O(1)
|
|
987
|
-
*/
|
|
988
|
-
find(callbackfn, thisArg) {
|
|
989
|
-
let index = 0;
|
|
990
|
-
for (const item of this) {
|
|
991
|
-
const [key, value] = item;
|
|
992
|
-
if (callbackfn.call(thisArg, value, key, index++, this)) return item;
|
|
993
|
-
}
|
|
994
|
-
return;
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* Whether the given key exists.
|
|
998
|
-
* @param key - Key to test.
|
|
999
|
-
* @returns `true` if found; otherwise `false`.
|
|
1000
|
-
* @remarks Time O(n) generic, Space O(1)
|
|
1001
|
-
*/
|
|
1002
|
-
has(key) {
|
|
1003
|
-
for (const item of this) {
|
|
1004
|
-
const [itemKey] = item;
|
|
1005
|
-
if (itemKey === key) return true;
|
|
1006
|
-
}
|
|
1007
|
-
return false;
|
|
1008
|
-
}
|
|
1009
|
-
/**
|
|
1010
|
-
* Whether there exists an entry with the given value.
|
|
1011
|
-
* @param value - Value to test.
|
|
1012
|
-
* @returns `true` if found; otherwise `false`.
|
|
1013
|
-
* @remarks Time O(n), Space O(1)
|
|
1014
|
-
*/
|
|
1015
|
-
hasValue(value) {
|
|
1016
|
-
for (const [, elementValue] of this) {
|
|
1017
|
-
if (elementValue === value) return true;
|
|
1018
|
-
}
|
|
1019
|
-
return false;
|
|
1020
|
-
}
|
|
1021
|
-
/**
|
|
1022
|
-
* Get the value under a key.
|
|
1023
|
-
* @param key - Key to look up.
|
|
1024
|
-
* @returns Value or `undefined`.
|
|
1025
|
-
* @remarks Time O(n) generic, Space O(1)
|
|
1026
|
-
*/
|
|
1027
|
-
get(key) {
|
|
1028
|
-
for (const item of this) {
|
|
1029
|
-
const [itemKey, value] = item;
|
|
1030
|
-
if (itemKey === key) return value;
|
|
1031
|
-
}
|
|
1032
|
-
return;
|
|
1033
|
-
}
|
|
1034
|
-
/**
|
|
1035
|
-
* Reduce entries into a single accumulator.
|
|
1036
|
-
* @param callbackfn - `(acc, value, key, index, self) => acc`.
|
|
1037
|
-
* @param initialValue - Initial accumulator.
|
|
1038
|
-
* @returns Final accumulator.
|
|
1039
|
-
* @remarks Time O(n), Space O(1)
|
|
1040
|
-
*/
|
|
1041
|
-
reduce(callbackfn, initialValue) {
|
|
1042
|
-
let accumulator = initialValue;
|
|
1043
|
-
let index = 0;
|
|
1044
|
-
for (const item of this) {
|
|
1045
|
-
const [key, value] = item;
|
|
1046
|
-
accumulator = callbackfn(accumulator, value, key, index++, this);
|
|
1047
|
-
}
|
|
1048
|
-
return accumulator;
|
|
1049
|
-
}
|
|
1050
|
-
/**
|
|
1051
|
-
* Converts data structure to `[key, value]` pairs.
|
|
1052
|
-
* @returns Array of entries.
|
|
1053
|
-
* @remarks Time O(n), Space O(n)
|
|
1054
|
-
*/
|
|
1055
|
-
toArray() {
|
|
1056
|
-
return [...this];
|
|
1057
|
-
}
|
|
1058
|
-
/**
|
|
1059
|
-
* Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
|
|
1060
|
-
* @returns Array of entries (default) or a string.
|
|
1061
|
-
* @remarks Time O(n), Space O(n)
|
|
1062
|
-
*/
|
|
1063
|
-
toVisual() {
|
|
1064
|
-
return [...this];
|
|
1065
|
-
}
|
|
1066
|
-
/**
|
|
1067
|
-
* Print a human-friendly representation to the console.
|
|
1068
|
-
* @remarks Time O(n), Space O(n)
|
|
1069
|
-
*/
|
|
1070
|
-
print() {
|
|
1071
|
-
console.log(this.toVisual());
|
|
1072
|
-
}
|
|
1073
|
-
};
|
|
1074
|
-
|
|
1075
1534
|
// src/data-structures/binary-tree/binary-tree.ts
|
|
1076
1535
|
var BinaryTreeNode = class {
|
|
1077
1536
|
static {
|
|
@@ -1445,23 +1904,113 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1445
1904
|
return isComparable(key);
|
|
1446
1905
|
}
|
|
1447
1906
|
/**
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1907
|
+
* Adds a new node to the tree.
|
|
1908
|
+
* @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).
|
|
1909
|
+
*
|
|
1910
|
+
* @param keyNodeOrEntry - The key, node, or entry to add.
|
|
1911
|
+
* @returns True if the addition was successful, false otherwise.
|
|
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
|
+
|
|
1939
|
+
* @example
|
|
1940
|
+
* // Add a single node
|
|
1941
|
+
* const tree = new BinaryTree<number>();
|
|
1942
|
+
* tree.add(1);
|
|
1943
|
+
* tree.add(2);
|
|
1944
|
+
* tree.add(3);
|
|
1945
|
+
* console.log(tree.size); // 3;
|
|
1946
|
+
* console.log(tree.has(1)); // true;
|
|
1947
|
+
*/
|
|
1454
1948
|
add(keyNodeOrEntry) {
|
|
1455
1949
|
return this.set(keyNodeOrEntry);
|
|
1456
1950
|
}
|
|
1457
1951
|
/**
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1952
|
+
* Adds or updates a new node to the tree.
|
|
1953
|
+
* @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).
|
|
1954
|
+
*
|
|
1955
|
+
* @param keyNodeOrEntry - The key, node, or entry to set or update.
|
|
1956
|
+
* @param [value] - The value, if providing just a key.
|
|
1957
|
+
* @returns True if the addition was successful, false otherwise.
|
|
1958
|
+
|
|
1959
|
+
|
|
1960
|
+
|
|
1961
|
+
|
|
1962
|
+
|
|
1963
|
+
|
|
1964
|
+
|
|
1965
|
+
|
|
1966
|
+
|
|
1967
|
+
|
|
1968
|
+
|
|
1969
|
+
|
|
1970
|
+
|
|
1971
|
+
|
|
1972
|
+
|
|
1973
|
+
|
|
1974
|
+
|
|
1975
|
+
|
|
1976
|
+
|
|
1977
|
+
|
|
1978
|
+
|
|
1979
|
+
|
|
1980
|
+
|
|
1981
|
+
|
|
1982
|
+
|
|
1983
|
+
|
|
1984
|
+
|
|
1985
|
+
|
|
1986
|
+
|
|
1987
|
+
|
|
1988
|
+
|
|
1989
|
+
|
|
1990
|
+
* @example
|
|
1991
|
+
* // basic BinaryTree creation and insertion
|
|
1992
|
+
* // Create a BinaryTree with entries
|
|
1993
|
+
* const entries: [number, string][] = [
|
|
1994
|
+
* [6, 'six'],
|
|
1995
|
+
* [1, 'one'],
|
|
1996
|
+
* [2, 'two'],
|
|
1997
|
+
* [7, 'seven'],
|
|
1998
|
+
* [5, 'five'],
|
|
1999
|
+
* [3, 'three'],
|
|
2000
|
+
* [4, 'four'],
|
|
2001
|
+
* [9, 'nine'],
|
|
2002
|
+
* [8, 'eight']
|
|
2003
|
+
* ];
|
|
2004
|
+
*
|
|
2005
|
+
* const tree = new BinaryTree(entries);
|
|
2006
|
+
*
|
|
2007
|
+
* // Verify size
|
|
2008
|
+
* console.log(tree.size); // 9;
|
|
2009
|
+
*
|
|
2010
|
+
* // Add new element
|
|
2011
|
+
* tree.set(10, 'ten');
|
|
2012
|
+
* console.log(tree.size); // 10;
|
|
2013
|
+
*/
|
|
1465
2014
|
set(keyNodeOrEntry, value) {
|
|
1466
2015
|
const [newNode] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
|
|
1467
2016
|
if (newNode === void 0) return false;
|
|
@@ -1506,23 +2055,86 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1506
2055
|
return false;
|
|
1507
2056
|
}
|
|
1508
2057
|
/**
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
2058
|
+
* Adds multiple items to the tree.
|
|
2059
|
+
* @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).
|
|
2060
|
+
*
|
|
2061
|
+
* @param keysNodesEntriesOrRaws - An iterable of items to set.
|
|
2062
|
+
* @returns An array of booleans indicating the success of each individual `set` operation.
|
|
2063
|
+
|
|
2064
|
+
|
|
2065
|
+
|
|
2066
|
+
|
|
2067
|
+
|
|
2068
|
+
|
|
2069
|
+
|
|
2070
|
+
|
|
2071
|
+
|
|
2072
|
+
|
|
2073
|
+
|
|
2074
|
+
|
|
2075
|
+
|
|
2076
|
+
|
|
2077
|
+
|
|
2078
|
+
|
|
2079
|
+
|
|
2080
|
+
|
|
2081
|
+
|
|
2082
|
+
|
|
2083
|
+
|
|
2084
|
+
|
|
2085
|
+
|
|
2086
|
+
|
|
2087
|
+
|
|
2088
|
+
|
|
2089
|
+
|
|
2090
|
+
|
|
2091
|
+
|
|
2092
|
+
|
|
2093
|
+
* @example
|
|
2094
|
+
* // Bulk add
|
|
2095
|
+
* const tree = new BinaryTree<number>();
|
|
2096
|
+
* tree.addMany([1, 2, 3, 4, 5]);
|
|
2097
|
+
* console.log(tree.size); // 5;
|
|
2098
|
+
*/
|
|
1515
2099
|
addMany(keysNodesEntriesOrRaws) {
|
|
1516
2100
|
return this.setMany(keysNodesEntriesOrRaws);
|
|
1517
2101
|
}
|
|
1518
2102
|
/**
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
2103
|
+
* Adds or updates multiple items to the tree.
|
|
2104
|
+
* @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).
|
|
2105
|
+
*
|
|
2106
|
+
* @param keysNodesEntriesOrRaws - An iterable of items to set or update.
|
|
2107
|
+
* @param [values] - An optional parallel iterable of values.
|
|
2108
|
+
* @returns An array of booleans indicating the success of each individual `set` operation.
|
|
2109
|
+
|
|
2110
|
+
|
|
2111
|
+
|
|
2112
|
+
|
|
2113
|
+
|
|
2114
|
+
|
|
2115
|
+
|
|
2116
|
+
|
|
2117
|
+
|
|
2118
|
+
|
|
2119
|
+
|
|
2120
|
+
|
|
2121
|
+
|
|
2122
|
+
|
|
2123
|
+
|
|
2124
|
+
|
|
2125
|
+
|
|
2126
|
+
|
|
2127
|
+
|
|
2128
|
+
|
|
2129
|
+
|
|
2130
|
+
|
|
2131
|
+
|
|
2132
|
+
* @example
|
|
2133
|
+
* // Set multiple entries
|
|
2134
|
+
* const tree = new BinaryTree<number, string>();
|
|
2135
|
+
* tree.setMany([[1, 'a'], [2, 'b'], [3, 'c']]);
|
|
2136
|
+
* console.log(tree.size); // 3;
|
|
2137
|
+
*/
|
|
1526
2138
|
setMany(keysNodesEntriesOrRaws, values) {
|
|
1527
2139
|
const inserted = [];
|
|
1528
2140
|
let valuesIterator;
|
|
@@ -1543,11 +2155,47 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1543
2155
|
return inserted;
|
|
1544
2156
|
}
|
|
1545
2157
|
/**
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
2158
|
+
* Merges another tree into this one by seting all its nodes.
|
|
2159
|
+
* @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`).
|
|
2160
|
+
*
|
|
2161
|
+
* @param anotherTree - The tree to merge.
|
|
2162
|
+
|
|
2163
|
+
|
|
2164
|
+
|
|
2165
|
+
|
|
2166
|
+
|
|
2167
|
+
|
|
2168
|
+
|
|
2169
|
+
|
|
2170
|
+
|
|
2171
|
+
|
|
2172
|
+
|
|
2173
|
+
|
|
2174
|
+
|
|
2175
|
+
|
|
2176
|
+
|
|
2177
|
+
|
|
2178
|
+
|
|
2179
|
+
|
|
2180
|
+
|
|
2181
|
+
|
|
2182
|
+
|
|
2183
|
+
|
|
2184
|
+
|
|
2185
|
+
|
|
2186
|
+
|
|
2187
|
+
|
|
2188
|
+
|
|
2189
|
+
|
|
2190
|
+
|
|
2191
|
+
|
|
2192
|
+
* @example
|
|
2193
|
+
* // Combine trees
|
|
2194
|
+
* const t1 = new BinaryTree<number>([1, 2]);
|
|
2195
|
+
* const t2 = new BinaryTree<number>([3, 4]);
|
|
2196
|
+
* t1.merge(t2);
|
|
2197
|
+
* console.log(t1.size); // 4;
|
|
2198
|
+
*/
|
|
1551
2199
|
merge(anotherTree) {
|
|
1552
2200
|
this.setMany(anotherTree, []);
|
|
1553
2201
|
}
|
|
@@ -1563,12 +2211,50 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1563
2211
|
this.setMany(keysNodesEntriesOrRaws, values);
|
|
1564
2212
|
}
|
|
1565
2213
|
/**
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
2214
|
+
* Deletes a node from the tree.
|
|
2215
|
+
* @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).
|
|
2216
|
+
*
|
|
2217
|
+
* @param keyNodeEntryRawOrPredicate - The node to delete.
|
|
2218
|
+
* @returns An array containing deletion results (for compatibility with self-balancing trees).
|
|
2219
|
+
|
|
2220
|
+
|
|
2221
|
+
|
|
2222
|
+
|
|
2223
|
+
|
|
2224
|
+
|
|
2225
|
+
|
|
2226
|
+
|
|
2227
|
+
|
|
2228
|
+
|
|
2229
|
+
|
|
2230
|
+
|
|
2231
|
+
|
|
2232
|
+
|
|
2233
|
+
|
|
2234
|
+
|
|
2235
|
+
|
|
2236
|
+
|
|
2237
|
+
|
|
2238
|
+
|
|
2239
|
+
|
|
2240
|
+
|
|
2241
|
+
|
|
2242
|
+
|
|
2243
|
+
|
|
2244
|
+
|
|
2245
|
+
|
|
2246
|
+
|
|
2247
|
+
|
|
2248
|
+
|
|
2249
|
+
|
|
2250
|
+
|
|
2251
|
+
* @example
|
|
2252
|
+
* // Remove a node
|
|
2253
|
+
* const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
|
|
2254
|
+
* tree.delete(3);
|
|
2255
|
+
* console.log(tree.has(3)); // false;
|
|
2256
|
+
* console.log(tree.size); // 4;
|
|
2257
|
+
*/
|
|
1572
2258
|
delete(keyNodeEntryRawOrPredicate) {
|
|
1573
2259
|
const deletedResult = [];
|
|
1574
2260
|
if (!this._root) return deletedResult;
|
|
@@ -1662,14 +2348,48 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1662
2348
|
return this.search(keyNodeEntryOrPredicate, onlyOne, (node) => node, startNode, iterationType);
|
|
1663
2349
|
}
|
|
1664
2350
|
/**
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
2351
|
+
* Gets the first node matching a predicate.
|
|
2352
|
+
* @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`).
|
|
2353
|
+
*
|
|
2354
|
+
* @param keyNodeEntryOrPredicate - The key, node, entry, or predicate function to search for.
|
|
2355
|
+
* @param [startNode=this._root] - The node to start the search from.
|
|
2356
|
+
* @param [iterationType=this.iterationType] - The traversal method.
|
|
2357
|
+
* @returns The first matching node, or undefined if not found.
|
|
2358
|
+
|
|
2359
|
+
|
|
2360
|
+
|
|
2361
|
+
|
|
2362
|
+
|
|
2363
|
+
|
|
2364
|
+
|
|
2365
|
+
|
|
2366
|
+
|
|
2367
|
+
|
|
2368
|
+
|
|
2369
|
+
|
|
2370
|
+
|
|
2371
|
+
|
|
2372
|
+
|
|
2373
|
+
|
|
2374
|
+
|
|
2375
|
+
|
|
2376
|
+
|
|
2377
|
+
|
|
2378
|
+
|
|
2379
|
+
|
|
2380
|
+
|
|
2381
|
+
|
|
2382
|
+
|
|
2383
|
+
|
|
2384
|
+
|
|
2385
|
+
|
|
2386
|
+
|
|
2387
|
+
|
|
2388
|
+
* @example
|
|
2389
|
+
* // Get node by key
|
|
2390
|
+
* const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'child']]);
|
|
2391
|
+
* console.log(tree.getNode(2)?.value); // 'child';
|
|
2392
|
+
*/
|
|
1673
2393
|
getNode(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1674
2394
|
if (this._isMapMode && keyNodeEntryOrPredicate !== null && keyNodeEntryOrPredicate !== void 0) {
|
|
1675
2395
|
if (!this._isPredicate(keyNodeEntryOrPredicate)) {
|
|
@@ -1681,14 +2401,51 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1681
2401
|
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType)[0];
|
|
1682
2402
|
}
|
|
1683
2403
|
/**
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
2404
|
+
* Gets the value associated with a key.
|
|
2405
|
+
* @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.
|
|
2406
|
+
*
|
|
2407
|
+
* @param keyNodeEntryOrPredicate - The key, node, or entry to get the value for.
|
|
2408
|
+
* @param [startNode=this._root] - The node to start searching from (if not in Map mode).
|
|
2409
|
+
* @param [iterationType=this.iterationType] - The traversal method (if not in Map mode).
|
|
2410
|
+
* @returns The associated value, or undefined.
|
|
2411
|
+
|
|
2412
|
+
|
|
2413
|
+
|
|
2414
|
+
|
|
2415
|
+
|
|
2416
|
+
|
|
2417
|
+
|
|
2418
|
+
|
|
2419
|
+
|
|
2420
|
+
|
|
2421
|
+
|
|
2422
|
+
|
|
2423
|
+
|
|
2424
|
+
|
|
2425
|
+
|
|
2426
|
+
|
|
2427
|
+
|
|
2428
|
+
|
|
2429
|
+
|
|
2430
|
+
|
|
2431
|
+
|
|
2432
|
+
|
|
2433
|
+
|
|
2434
|
+
|
|
2435
|
+
|
|
2436
|
+
|
|
2437
|
+
|
|
2438
|
+
|
|
2439
|
+
|
|
2440
|
+
|
|
2441
|
+
|
|
2442
|
+
|
|
2443
|
+
* @example
|
|
2444
|
+
* // Retrieve value by key
|
|
2445
|
+
* const tree = new BinaryTree<number, string>([[1, 'root'], [2, 'left'], [3, 'right']]);
|
|
2446
|
+
* console.log(tree.get(2)); // 'left';
|
|
2447
|
+
* console.log(tree.get(99)); // undefined;
|
|
2448
|
+
*/
|
|
1692
2449
|
get(keyNodeEntryOrPredicate, startNode = this._root, iterationType = this.iterationType) {
|
|
1693
2450
|
if (this._isMapMode) {
|
|
1694
2451
|
const key = this._extractKey(keyNodeEntryOrPredicate);
|
|
@@ -1708,19 +2465,87 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1708
2465
|
return this.search(keyNodeEntryOrPredicate, true, (node) => node, startNode, iterationType).length > 0;
|
|
1709
2466
|
}
|
|
1710
2467
|
/**
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
2468
|
+
* Clears the tree of all nodes and values.
|
|
2469
|
+
* @remarks Time O(N) if in Map mode (due to `_store.clear()`), O(1) otherwise. Space O(1)
|
|
2470
|
+
|
|
2471
|
+
|
|
2472
|
+
|
|
2473
|
+
|
|
2474
|
+
|
|
2475
|
+
|
|
2476
|
+
|
|
2477
|
+
|
|
2478
|
+
|
|
2479
|
+
|
|
2480
|
+
|
|
2481
|
+
|
|
2482
|
+
|
|
2483
|
+
|
|
2484
|
+
|
|
2485
|
+
|
|
2486
|
+
|
|
2487
|
+
|
|
2488
|
+
|
|
2489
|
+
|
|
2490
|
+
|
|
2491
|
+
|
|
2492
|
+
|
|
2493
|
+
|
|
2494
|
+
|
|
2495
|
+
|
|
2496
|
+
|
|
2497
|
+
|
|
2498
|
+
|
|
2499
|
+
|
|
2500
|
+
* @example
|
|
2501
|
+
* // Remove all nodes
|
|
2502
|
+
* const tree = new BinaryTree<number>([1, 2, 3]);
|
|
2503
|
+
* tree.clear();
|
|
2504
|
+
* console.log(tree.isEmpty()); // true;
|
|
2505
|
+
*/
|
|
1714
2506
|
clear() {
|
|
1715
2507
|
this._clearNodes();
|
|
1716
2508
|
if (this._isMapMode) this._clearValues();
|
|
1717
2509
|
}
|
|
1718
2510
|
/**
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
2511
|
+
* Checks if the tree is empty.
|
|
2512
|
+
* @remarks Time O(1), Space O(1)
|
|
2513
|
+
*
|
|
2514
|
+
* @returns True if the tree has no nodes, false otherwise.
|
|
2515
|
+
|
|
2516
|
+
|
|
2517
|
+
|
|
2518
|
+
|
|
2519
|
+
|
|
2520
|
+
|
|
2521
|
+
|
|
2522
|
+
|
|
2523
|
+
|
|
2524
|
+
|
|
2525
|
+
|
|
2526
|
+
|
|
2527
|
+
|
|
2528
|
+
|
|
2529
|
+
|
|
2530
|
+
|
|
2531
|
+
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
|
|
2535
|
+
|
|
2536
|
+
|
|
2537
|
+
|
|
2538
|
+
|
|
2539
|
+
|
|
2540
|
+
|
|
2541
|
+
|
|
2542
|
+
|
|
2543
|
+
|
|
2544
|
+
|
|
2545
|
+
* @example
|
|
2546
|
+
* // Check empty
|
|
2547
|
+
* console.log(new BinaryTree().isEmpty()); // true;
|
|
2548
|
+
*/
|
|
1724
2549
|
isEmpty() {
|
|
1725
2550
|
return this._size === 0;
|
|
1726
2551
|
}
|
|
@@ -1735,13 +2560,48 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1735
2560
|
return this.getMinHeight(startNode) + 1 >= this.getHeight(startNode);
|
|
1736
2561
|
}
|
|
1737
2562
|
/**
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
2563
|
+
* Checks if the tree is a valid Binary Search Tree (BST).
|
|
2564
|
+
* @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).
|
|
2565
|
+
*
|
|
2566
|
+
* @param [startNode=this._root] - The node to start checking from.
|
|
2567
|
+
* @param [iterationType=this.iterationType] - The traversal method.
|
|
2568
|
+
* @returns True if it's a valid BST, false otherwise.
|
|
2569
|
+
|
|
2570
|
+
|
|
2571
|
+
|
|
2572
|
+
|
|
2573
|
+
|
|
2574
|
+
|
|
2575
|
+
|
|
2576
|
+
|
|
2577
|
+
|
|
2578
|
+
|
|
2579
|
+
|
|
2580
|
+
|
|
2581
|
+
|
|
2582
|
+
|
|
2583
|
+
|
|
2584
|
+
|
|
2585
|
+
|
|
2586
|
+
|
|
2587
|
+
|
|
2588
|
+
|
|
2589
|
+
|
|
2590
|
+
|
|
2591
|
+
|
|
2592
|
+
|
|
2593
|
+
|
|
2594
|
+
|
|
2595
|
+
|
|
2596
|
+
|
|
2597
|
+
|
|
2598
|
+
|
|
2599
|
+
* @example
|
|
2600
|
+
* // Check BST property
|
|
2601
|
+
* const tree = new BinaryTree<number>([1, 2, 3]);
|
|
2602
|
+
* // BinaryTree doesn't guarantee BST order
|
|
2603
|
+
* console.log(typeof tree.isBST()); // 'boolean';
|
|
2604
|
+
*/
|
|
1745
2605
|
isBST(startNode = this._root, iterationType = this.iterationType) {
|
|
1746
2606
|
const startNodeSired = this.ensureNode(startNode);
|
|
1747
2607
|
if (!startNodeSired) return true;
|
|
@@ -1779,13 +2639,50 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1779
2639
|
}
|
|
1780
2640
|
}
|
|
1781
2641
|
/**
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
2642
|
+
* Gets the depth of a node (distance from `startNode`).
|
|
2643
|
+
* @remarks Time O(H), where H is the depth of the `dist` node relative to `startNode`. O(N) worst-case. Space O(1).
|
|
2644
|
+
*
|
|
2645
|
+
* @param dist - The node to find the depth of.
|
|
2646
|
+
* @param [startNode=this._root] - The node to measure depth from (defaults to root).
|
|
2647
|
+
* @returns The depth (0 if `dist` is `startNode`).
|
|
2648
|
+
|
|
2649
|
+
|
|
2650
|
+
|
|
2651
|
+
|
|
2652
|
+
|
|
2653
|
+
|
|
2654
|
+
|
|
2655
|
+
|
|
2656
|
+
|
|
2657
|
+
|
|
2658
|
+
|
|
2659
|
+
|
|
2660
|
+
|
|
2661
|
+
|
|
2662
|
+
|
|
2663
|
+
|
|
2664
|
+
|
|
2665
|
+
|
|
2666
|
+
|
|
2667
|
+
|
|
2668
|
+
|
|
2669
|
+
|
|
2670
|
+
|
|
2671
|
+
|
|
2672
|
+
|
|
2673
|
+
|
|
2674
|
+
|
|
2675
|
+
|
|
2676
|
+
|
|
2677
|
+
|
|
2678
|
+
|
|
2679
|
+
|
|
2680
|
+
* @example
|
|
2681
|
+
* // Get depth of a node
|
|
2682
|
+
* const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
|
|
2683
|
+
* const node = tree.getNode(4);
|
|
2684
|
+
* console.log(tree.getDepth(node!)); // 2;
|
|
2685
|
+
*/
|
|
1789
2686
|
getDepth(dist, startNode = this._root) {
|
|
1790
2687
|
let distEnsured = this.ensureNode(dist);
|
|
1791
2688
|
const beginRootEnsured = this.ensureNode(startNode);
|
|
@@ -1800,13 +2697,49 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1800
2697
|
return depth;
|
|
1801
2698
|
}
|
|
1802
2699
|
/**
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
2700
|
+
* Gets the maximum height of the tree (longest path from startNode to a leaf).
|
|
2701
|
+
* @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).
|
|
2702
|
+
*
|
|
2703
|
+
* @param [startNode=this._root] - The node to start measuring from.
|
|
2704
|
+
* @param [iterationType=this.iterationType] - The traversal method.
|
|
2705
|
+
* @returns The height ( -1 for an empty tree, 0 for a single-node tree).
|
|
2706
|
+
|
|
2707
|
+
|
|
2708
|
+
|
|
2709
|
+
|
|
2710
|
+
|
|
2711
|
+
|
|
2712
|
+
|
|
2713
|
+
|
|
2714
|
+
|
|
2715
|
+
|
|
2716
|
+
|
|
2717
|
+
|
|
2718
|
+
|
|
2719
|
+
|
|
2720
|
+
|
|
2721
|
+
|
|
2722
|
+
|
|
2723
|
+
|
|
2724
|
+
|
|
2725
|
+
|
|
2726
|
+
|
|
2727
|
+
|
|
2728
|
+
|
|
2729
|
+
|
|
2730
|
+
|
|
2731
|
+
|
|
2732
|
+
|
|
2733
|
+
|
|
2734
|
+
|
|
2735
|
+
|
|
2736
|
+
|
|
2737
|
+
|
|
2738
|
+
* @example
|
|
2739
|
+
* // Get tree height
|
|
2740
|
+
* const tree = new BinaryTree<number>([1, 2, 3, 4, 5]);
|
|
2741
|
+
* console.log(tree.getHeight()); // 2;
|
|
2742
|
+
*/
|
|
1810
2743
|
getHeight(startNode = this._root, iterationType = this.iterationType) {
|
|
1811
2744
|
startNode = this.ensureNode(startNode);
|
|
1812
2745
|
if (!this.isRealNode(startNode)) return -1;
|
|
@@ -2242,24 +3175,95 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
2242
3175
|
return ans;
|
|
2243
3176
|
}
|
|
2244
3177
|
/**
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
3178
|
+
* Clones the tree.
|
|
3179
|
+
* @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.
|
|
3180
|
+
*
|
|
3181
|
+
* @returns A new, cloned instance of the tree.
|
|
3182
|
+
|
|
3183
|
+
|
|
3184
|
+
|
|
3185
|
+
|
|
3186
|
+
|
|
3187
|
+
|
|
3188
|
+
|
|
3189
|
+
|
|
3190
|
+
|
|
3191
|
+
|
|
3192
|
+
|
|
3193
|
+
|
|
3194
|
+
|
|
3195
|
+
|
|
3196
|
+
|
|
3197
|
+
|
|
3198
|
+
|
|
3199
|
+
|
|
3200
|
+
|
|
3201
|
+
|
|
3202
|
+
|
|
3203
|
+
|
|
3204
|
+
|
|
3205
|
+
|
|
3206
|
+
|
|
3207
|
+
|
|
3208
|
+
|
|
3209
|
+
|
|
3210
|
+
|
|
3211
|
+
|
|
3212
|
+
* @example
|
|
3213
|
+
* // Deep copy
|
|
3214
|
+
* const tree = new BinaryTree<number>([1, 2, 3]);
|
|
3215
|
+
* const copy = tree.clone();
|
|
3216
|
+
* copy.delete(1);
|
|
3217
|
+
* console.log(tree.has(1)); // true;
|
|
3218
|
+
*/
|
|
2250
3219
|
clone() {
|
|
2251
3220
|
const out = this._createInstance();
|
|
2252
3221
|
this._clone(out);
|
|
2253
3222
|
return out;
|
|
2254
3223
|
}
|
|
2255
3224
|
/**
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
3225
|
+
* Creates a new tree containing only the entries that satisfy the predicate.
|
|
3226
|
+
* @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.
|
|
3227
|
+
*
|
|
3228
|
+
* @param predicate - A function to test each [key, value] pair.
|
|
3229
|
+
* @param [thisArg] - `this` context for the predicate.
|
|
3230
|
+
* @returns A new, filtered tree.
|
|
3231
|
+
|
|
3232
|
+
|
|
3233
|
+
|
|
3234
|
+
|
|
3235
|
+
|
|
3236
|
+
|
|
3237
|
+
|
|
3238
|
+
|
|
3239
|
+
|
|
3240
|
+
|
|
3241
|
+
|
|
3242
|
+
|
|
3243
|
+
|
|
3244
|
+
|
|
3245
|
+
|
|
3246
|
+
|
|
3247
|
+
|
|
3248
|
+
|
|
3249
|
+
|
|
3250
|
+
|
|
3251
|
+
|
|
3252
|
+
|
|
3253
|
+
|
|
3254
|
+
|
|
3255
|
+
|
|
3256
|
+
|
|
3257
|
+
|
|
3258
|
+
|
|
3259
|
+
|
|
3260
|
+
|
|
3261
|
+
* @example
|
|
3262
|
+
* // Filter nodes by condition
|
|
3263
|
+
* const tree = new BinaryTree<number>([1, 2, 3, 4]);
|
|
3264
|
+
* const result = tree.filter((_, key) => key > 2);
|
|
3265
|
+
* console.log(result.size); // 2;
|
|
3266
|
+
*/
|
|
2263
3267
|
filter(predicate, thisArg) {
|
|
2264
3268
|
const out = this._createInstance();
|
|
2265
3269
|
let i = 0;
|
|
@@ -2267,17 +3271,52 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
2267
3271
|
return out;
|
|
2268
3272
|
}
|
|
2269
3273
|
/**
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
3274
|
+
* Creates a new tree by mapping each [key, value] pair to a new entry.
|
|
3275
|
+
* @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.
|
|
3276
|
+
*
|
|
3277
|
+
* @template MK - New key type.
|
|
3278
|
+
* @template MV - New value type.
|
|
3279
|
+
* @template MR - New raw type.
|
|
3280
|
+
* @param cb - A function to map each [key, value] pair.
|
|
3281
|
+
* @param [options] - Options for the new tree.
|
|
3282
|
+
* @param [thisArg] - `this` context for the callback.
|
|
3283
|
+
* @returns A new, mapped tree.
|
|
3284
|
+
|
|
3285
|
+
|
|
3286
|
+
|
|
3287
|
+
|
|
3288
|
+
|
|
3289
|
+
|
|
3290
|
+
|
|
3291
|
+
|
|
3292
|
+
|
|
3293
|
+
|
|
3294
|
+
|
|
3295
|
+
|
|
3296
|
+
|
|
3297
|
+
|
|
3298
|
+
|
|
3299
|
+
|
|
3300
|
+
|
|
3301
|
+
|
|
3302
|
+
|
|
3303
|
+
|
|
3304
|
+
|
|
3305
|
+
|
|
3306
|
+
|
|
3307
|
+
|
|
3308
|
+
|
|
3309
|
+
|
|
3310
|
+
|
|
3311
|
+
|
|
3312
|
+
|
|
3313
|
+
|
|
3314
|
+
* @example
|
|
3315
|
+
* // Transform to new tree
|
|
3316
|
+
* const tree = new BinaryTree<number, number>([[1, 10], [2, 20]]);
|
|
3317
|
+
* const mapped = tree.map((v, key) => [key, (v ?? 0) + 1] as [number, number]);
|
|
3318
|
+
* console.log([...mapped.values()]); // contains 11;
|
|
3319
|
+
*/
|
|
2281
3320
|
map(cb, options, thisArg) {
|
|
2282
3321
|
const out = this._createLike([], options);
|
|
2283
3322
|
let i = 0;
|
|
@@ -2315,12 +3354,46 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
2315
3354
|
return output;
|
|
2316
3355
|
}
|
|
2317
3356
|
/**
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
3357
|
+
* Prints a visual representation of the tree to the console.
|
|
3358
|
+
* @remarks Time O(N) (via `toVisual`). Space O(N*H) or O(N^2) (via `toVisual`).
|
|
3359
|
+
*
|
|
3360
|
+
* @param [options] - Options to control the output.
|
|
3361
|
+
* @param [startNode=this._root] - The node to start printing from.
|
|
3362
|
+
|
|
3363
|
+
|
|
3364
|
+
|
|
3365
|
+
|
|
3366
|
+
|
|
3367
|
+
|
|
3368
|
+
|
|
3369
|
+
|
|
3370
|
+
|
|
3371
|
+
|
|
3372
|
+
|
|
3373
|
+
|
|
3374
|
+
|
|
3375
|
+
|
|
3376
|
+
|
|
3377
|
+
|
|
3378
|
+
|
|
3379
|
+
|
|
3380
|
+
|
|
3381
|
+
|
|
3382
|
+
|
|
3383
|
+
|
|
3384
|
+
|
|
3385
|
+
|
|
3386
|
+
|
|
3387
|
+
|
|
3388
|
+
|
|
3389
|
+
|
|
3390
|
+
|
|
3391
|
+
|
|
3392
|
+
* @example
|
|
3393
|
+
* // Display tree
|
|
3394
|
+
* const tree = new BinaryTree<number>([1, 2, 3]);
|
|
3395
|
+
* expect(() => tree.print()).not.toThrow();
|
|
3396
|
+
*/
|
|
2324
3397
|
print(options, startNode = this._root) {
|
|
2325
3398
|
console.log(this.toVisual(startNode, options));
|
|
2326
3399
|
}
|
|
@@ -2559,7 +3632,6 @@ var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
2559
3632
|
* @returns Layout information for this subtree.
|
|
2560
3633
|
*/
|
|
2561
3634
|
_displayAux(node, options) {
|
|
2562
|
-
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
2563
3635
|
const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
|
|
2564
3636
|
const newFrame = /* @__PURE__ */ __name((n) => ({
|
|
2565
3637
|
node: n,
|