data-structure-typed 2.4.4 → 2.4.5
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/CHANGELOG.md +22 -1
- package/README.md +24 -1
- package/dist/cjs/index.cjs +459 -132
- package/dist/cjs-legacy/index.cjs +459 -130
- package/dist/esm/index.mjs +459 -133
- package/dist/esm-legacy/index.mjs +459 -131
- package/dist/types/common/error.d.ts +23 -0
- package/dist/types/common/index.d.ts +1 -0
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +10 -0
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +7 -1
- package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +1 -0
- package/dist/types/data-structures/graph/undirected-graph.d.ts +14 -0
- package/dist/types/data-structures/queue/deque.d.ts +41 -1
- package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
- package/dist/umd/data-structure-typed.js +458 -129
- package/dist/umd/data-structure-typed.min.js +4 -2
- package/package.json +2 -2
- package/src/common/error.ts +60 -0
- package/src/common/index.ts +2 -0
- package/src/data-structures/base/iterable-element-base.ts +3 -2
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +6 -5
- package/src/data-structures/binary-tree/binary-tree.ts +113 -42
- package/src/data-structures/binary-tree/bst.ts +11 -3
- package/src/data-structures/binary-tree/red-black-tree.ts +20 -0
- package/src/data-structures/binary-tree/tree-map.ts +8 -7
- package/src/data-structures/binary-tree/tree-multi-map.ts +4 -4
- package/src/data-structures/binary-tree/tree-multi-set.ts +5 -4
- package/src/data-structures/binary-tree/tree-set.ts +7 -6
- package/src/data-structures/graph/abstract-graph.ts +106 -1
- package/src/data-structures/graph/directed-graph.ts +4 -0
- package/src/data-structures/graph/undirected-graph.ts +95 -0
- package/src/data-structures/hash/hash-map.ts +13 -2
- package/src/data-structures/heap/heap.ts +4 -3
- package/src/data-structures/heap/max-heap.ts +2 -3
- package/src/data-structures/matrix/matrix.ts +9 -10
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -3
- package/src/data-structures/queue/deque.ts +71 -3
- package/src/data-structures/trie/trie.ts +2 -1
- package/src/types/data-structures/queue/deque.ts +7 -0
- package/src/utils/utils.ts +4 -2
|
@@ -191,6 +191,54 @@ var _IterableEntryBase = class _IterableEntryBase {
|
|
|
191
191
|
__name(_IterableEntryBase, "IterableEntryBase");
|
|
192
192
|
var IterableEntryBase = _IterableEntryBase;
|
|
193
193
|
|
|
194
|
+
// src/common/error.ts
|
|
195
|
+
var ERR = {
|
|
196
|
+
// Range / index
|
|
197
|
+
indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
|
|
198
|
+
invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
|
|
199
|
+
// Type / argument
|
|
200
|
+
invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
|
|
201
|
+
comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
|
|
202
|
+
invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
|
|
203
|
+
notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
|
|
204
|
+
invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
|
|
205
|
+
invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
|
|
206
|
+
invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
|
|
207
|
+
reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
|
|
208
|
+
callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
|
|
209
|
+
// State / operation
|
|
210
|
+
invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
|
|
211
|
+
// Matrix
|
|
212
|
+
matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
|
|
213
|
+
matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
|
|
214
|
+
matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
|
|
215
|
+
matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
|
|
216
|
+
matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// src/common/index.ts
|
|
220
|
+
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
221
|
+
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
222
|
+
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
223
|
+
return DFSOperation2;
|
|
224
|
+
})(DFSOperation || {});
|
|
225
|
+
var _Range = class _Range {
|
|
226
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
227
|
+
this.low = low;
|
|
228
|
+
this.high = high;
|
|
229
|
+
this.includeLow = includeLow;
|
|
230
|
+
this.includeHigh = includeHigh;
|
|
231
|
+
}
|
|
232
|
+
// Determine whether a key is within the range
|
|
233
|
+
isInRange(key, comparator) {
|
|
234
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
235
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
236
|
+
return lowCheck && highCheck;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
__name(_Range, "Range");
|
|
240
|
+
var Range = _Range;
|
|
241
|
+
|
|
194
242
|
// src/data-structures/base/iterable-element-base.ts
|
|
195
243
|
var _IterableElementBase = class _IterableElementBase {
|
|
196
244
|
/**
|
|
@@ -213,7 +261,7 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
213
261
|
if (options) {
|
|
214
262
|
const { toElementFn } = options;
|
|
215
263
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
216
|
-
else if (toElementFn) throw new TypeError("toElementFn
|
|
264
|
+
else if (toElementFn) throw new TypeError(ERR.notAFunction("toElementFn"));
|
|
217
265
|
}
|
|
218
266
|
}
|
|
219
267
|
/**
|
|
@@ -369,7 +417,7 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
369
417
|
acc = initialValue;
|
|
370
418
|
} else {
|
|
371
419
|
const first = iter.next();
|
|
372
|
-
if (first.done) throw new TypeError(
|
|
420
|
+
if (first.done) throw new TypeError(ERR.reduceEmpty());
|
|
373
421
|
acc = first.value;
|
|
374
422
|
index = 1;
|
|
375
423
|
}
|
|
@@ -439,8 +487,10 @@ var getMSB = /* @__PURE__ */ __name((value) => {
|
|
|
439
487
|
}
|
|
440
488
|
return 1 << 31 - Math.clz32(value);
|
|
441
489
|
}, "getMSB");
|
|
442
|
-
var rangeCheck = /* @__PURE__ */ __name((index, min, max, message
|
|
443
|
-
if (index < min || index > max)
|
|
490
|
+
var rangeCheck = /* @__PURE__ */ __name((index, min, max, message) => {
|
|
491
|
+
if (index < min || index > max) {
|
|
492
|
+
throw new RangeError(message != null ? message : `Index ${index} is out of range [${min}, ${max}].`);
|
|
493
|
+
}
|
|
444
494
|
}, "rangeCheck");
|
|
445
495
|
var throwRangeError = /* @__PURE__ */ __name((message = "The value is off-limits.") => {
|
|
446
496
|
throw new RangeError(message);
|
|
@@ -812,8 +862,8 @@ var _LinkedHashMap = class _LinkedHashMap extends IterableEntryBase {
|
|
|
812
862
|
if (this.isEntry(rawElement)) {
|
|
813
863
|
return rawElement;
|
|
814
864
|
}
|
|
815
|
-
throw new
|
|
816
|
-
"If
|
|
865
|
+
throw new TypeError(
|
|
866
|
+
ERR.invalidArgument("If elements do not adhere to [key, value], provide options.toEntryFn to transform raw records.", "HashMap")
|
|
817
867
|
);
|
|
818
868
|
}, "_toEntryFn"));
|
|
819
869
|
__publicField(this, "_size", 0);
|
|
@@ -1098,6 +1148,13 @@ var _LinkedHashMap = class _LinkedHashMap extends IterableEntryBase {
|
|
|
1098
1148
|
}
|
|
1099
1149
|
}
|
|
1100
1150
|
_deleteNode(node) {
|
|
1151
|
+
const key = node.key;
|
|
1152
|
+
if (isWeakKey(key)) {
|
|
1153
|
+
this._objMap.delete(key);
|
|
1154
|
+
} else {
|
|
1155
|
+
const hash = this._hashFn(key);
|
|
1156
|
+
delete this._noObjMap[hash];
|
|
1157
|
+
}
|
|
1101
1158
|
const { prev, next } = node;
|
|
1102
1159
|
prev.next = next;
|
|
1103
1160
|
next.prev = prev;
|
|
@@ -3605,17 +3662,16 @@ var LinkedListQueue = _LinkedListQueue;
|
|
|
3605
3662
|
|
|
3606
3663
|
// src/data-structures/queue/deque.ts
|
|
3607
3664
|
var _Deque = class _Deque extends LinearBase {
|
|
3608
|
-
/**
|
|
3609
|
-
* Create a Deque and optionally bulk-insert elements.
|
|
3610
|
-
* @remarks Time O(N), Space O(N)
|
|
3611
|
-
* @param [elements] - Iterable (or iterable-like) of elements/records to insert.
|
|
3612
|
-
* @param [options] - Options such as bucketSize, toElementFn, and maxLen.
|
|
3613
|
-
* @returns New Deque instance.
|
|
3614
|
-
*/
|
|
3615
3665
|
constructor(elements = [], options) {
|
|
3616
3666
|
super(options);
|
|
3617
3667
|
__publicField(this, "_equals", /* @__PURE__ */ __name((a, b) => Object.is(a, b), "_equals"));
|
|
3618
3668
|
__publicField(this, "_bucketSize", 1 << 12);
|
|
3669
|
+
__publicField(this, "_autoCompactRatio", 0.5);
|
|
3670
|
+
/**
|
|
3671
|
+
* Counter for shift/pop operations since last compaction check.
|
|
3672
|
+
* Only checks ratio every `_bucketSize` operations to minimize overhead.
|
|
3673
|
+
*/
|
|
3674
|
+
__publicField(this, "_compactCounter", 0);
|
|
3619
3675
|
__publicField(this, "_bucketFirst", 0);
|
|
3620
3676
|
__publicField(this, "_firstInBucket", 0);
|
|
3621
3677
|
__publicField(this, "_bucketLast", 0);
|
|
@@ -3624,8 +3680,9 @@ var _Deque = class _Deque extends LinearBase {
|
|
|
3624
3680
|
__publicField(this, "_buckets", []);
|
|
3625
3681
|
__publicField(this, "_length", 0);
|
|
3626
3682
|
if (options) {
|
|
3627
|
-
const { bucketSize } = options;
|
|
3683
|
+
const { bucketSize, autoCompactRatio } = options;
|
|
3628
3684
|
if (typeof bucketSize === "number") this._bucketSize = bucketSize;
|
|
3685
|
+
if (typeof autoCompactRatio === "number") this._autoCompactRatio = autoCompactRatio;
|
|
3629
3686
|
}
|
|
3630
3687
|
let _size;
|
|
3631
3688
|
if ("length" in elements) {
|
|
@@ -3650,6 +3707,24 @@ var _Deque = class _Deque extends LinearBase {
|
|
|
3650
3707
|
get bucketSize() {
|
|
3651
3708
|
return this._bucketSize;
|
|
3652
3709
|
}
|
|
3710
|
+
/**
|
|
3711
|
+
* Get the auto-compaction ratio.
|
|
3712
|
+
* When `elements / (bucketCount * bucketSize)` drops below this ratio after
|
|
3713
|
+
* enough shift/pop operations, the deque auto-compacts.
|
|
3714
|
+
* @remarks Time O(1), Space O(1)
|
|
3715
|
+
* @returns Current ratio threshold. 0 means auto-compact is disabled.
|
|
3716
|
+
*/
|
|
3717
|
+
get autoCompactRatio() {
|
|
3718
|
+
return this._autoCompactRatio;
|
|
3719
|
+
}
|
|
3720
|
+
/**
|
|
3721
|
+
* Set the auto-compaction ratio.
|
|
3722
|
+
* @remarks Time O(1), Space O(1)
|
|
3723
|
+
* @param value - Ratio in [0,1]. 0 disables auto-compact.
|
|
3724
|
+
*/
|
|
3725
|
+
set autoCompactRatio(value) {
|
|
3726
|
+
this._autoCompactRatio = value;
|
|
3727
|
+
}
|
|
3653
3728
|
/**
|
|
3654
3729
|
* Get the index of the first bucket in use.
|
|
3655
3730
|
* @remarks Time O(1), Space O(1)
|
|
@@ -3781,6 +3856,7 @@ var _Deque = class _Deque extends LinearBase {
|
|
|
3781
3856
|
}
|
|
3782
3857
|
}
|
|
3783
3858
|
this._length -= 1;
|
|
3859
|
+
this._autoCompact();
|
|
3784
3860
|
return element;
|
|
3785
3861
|
}
|
|
3786
3862
|
/**
|
|
@@ -3803,6 +3879,7 @@ var _Deque = class _Deque extends LinearBase {
|
|
|
3803
3879
|
}
|
|
3804
3880
|
}
|
|
3805
3881
|
this._length -= 1;
|
|
3882
|
+
this._autoCompact();
|
|
3806
3883
|
return element;
|
|
3807
3884
|
}
|
|
3808
3885
|
/**
|
|
@@ -4135,11 +4212,40 @@ var _Deque = class _Deque extends LinearBase {
|
|
|
4135
4212
|
* @remarks Time O(N), Space O(1)
|
|
4136
4213
|
* @returns void
|
|
4137
4214
|
*/
|
|
4215
|
+
/**
|
|
4216
|
+
* (Protected) Trigger auto-compaction if space utilization drops below threshold.
|
|
4217
|
+
* Only checks every `_bucketSize` operations to minimize hot-path overhead.
|
|
4218
|
+
* Uses element-based ratio: `elements / (bucketCount * bucketSize)`.
|
|
4219
|
+
*/
|
|
4220
|
+
_autoCompact() {
|
|
4221
|
+
if (this._autoCompactRatio <= 0 || this._bucketCount <= 1) return;
|
|
4222
|
+
this._compactCounter++;
|
|
4223
|
+
if (this._compactCounter < this._bucketSize) return;
|
|
4224
|
+
this._compactCounter = 0;
|
|
4225
|
+
const utilization = this._length / (this._bucketCount * this._bucketSize);
|
|
4226
|
+
if (utilization < this._autoCompactRatio) {
|
|
4227
|
+
this.shrinkToFit();
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
/**
|
|
4231
|
+
* Compact the deque by removing unused buckets.
|
|
4232
|
+
* @remarks Time O(N), Space O(1)
|
|
4233
|
+
* @returns True if compaction was performed (bucket count reduced).
|
|
4234
|
+
*/
|
|
4235
|
+
/**
|
|
4236
|
+
* Compact the deque by removing unused buckets.
|
|
4237
|
+
* @remarks Time O(N), Space O(1)
|
|
4238
|
+
* @returns True if compaction was performed (bucket count reduced).
|
|
4239
|
+
*/
|
|
4240
|
+
compact() {
|
|
4241
|
+
const before = this._bucketCount;
|
|
4242
|
+
this.shrinkToFit();
|
|
4243
|
+
return this._bucketCount < before;
|
|
4244
|
+
}
|
|
4138
4245
|
shrinkToFit() {
|
|
4139
4246
|
if (this._length === 0) return;
|
|
4140
4247
|
const newBuckets = [];
|
|
4141
|
-
if (this._bucketFirst
|
|
4142
|
-
else if (this._bucketFirst < this._bucketLast) {
|
|
4248
|
+
if (this._bucketFirst <= this._bucketLast) {
|
|
4143
4249
|
for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {
|
|
4144
4250
|
newBuckets.push(this._buckets[i]);
|
|
4145
4251
|
}
|
|
@@ -4154,6 +4260,8 @@ var _Deque = class _Deque extends LinearBase {
|
|
|
4154
4260
|
this._bucketFirst = 0;
|
|
4155
4261
|
this._bucketLast = newBuckets.length - 1;
|
|
4156
4262
|
this._buckets = newBuckets;
|
|
4263
|
+
this._bucketCount = newBuckets.length;
|
|
4264
|
+
this._compactCounter = 0;
|
|
4157
4265
|
}
|
|
4158
4266
|
/**
|
|
4159
4267
|
* Deep clone this deque, preserving options.
|
|
@@ -4351,7 +4459,7 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
4351
4459
|
__publicField(this, "_elements", []);
|
|
4352
4460
|
__publicField(this, "_DEFAULT_COMPARATOR", /* @__PURE__ */ __name((a, b) => {
|
|
4353
4461
|
if (typeof a === "object" || typeof b === "object") {
|
|
4354
|
-
throw TypeError(
|
|
4462
|
+
throw new TypeError(ERR.comparatorRequired("Heap"));
|
|
4355
4463
|
}
|
|
4356
4464
|
if (a > b) return 1;
|
|
4357
4465
|
if (a < b) return -1;
|
|
@@ -4661,7 +4769,7 @@ var _Heap = class _Heap extends IterableElementBase {
|
|
|
4661
4769
|
*/
|
|
4662
4770
|
map(callback, options, thisArg) {
|
|
4663
4771
|
const { comparator, toElementFn, ...rest } = options != null ? options : {};
|
|
4664
|
-
if (!comparator) throw new TypeError("Heap.map
|
|
4772
|
+
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
4665
4773
|
const out = this._createLike([], { ...rest, comparator, toElementFn });
|
|
4666
4774
|
let i = 0;
|
|
4667
4775
|
for (const x of this) {
|
|
@@ -4793,7 +4901,7 @@ var _FibonacciHeap = class _FibonacciHeap {
|
|
|
4793
4901
|
__publicField(this, "_comparator");
|
|
4794
4902
|
this.clear();
|
|
4795
4903
|
this._comparator = comparator || this._defaultComparator;
|
|
4796
|
-
if (typeof this.comparator !== "function") throw new
|
|
4904
|
+
if (typeof this.comparator !== "function") throw new TypeError(ERR.notAFunction("comparator", "FibonacciHeap"));
|
|
4797
4905
|
}
|
|
4798
4906
|
/**
|
|
4799
4907
|
* Get the circular root list head.
|
|
@@ -5004,9 +5112,7 @@ var _MaxHeap = class _MaxHeap extends Heap {
|
|
|
5004
5112
|
super(elements, {
|
|
5005
5113
|
comparator: /* @__PURE__ */ __name((a, b) => {
|
|
5006
5114
|
if (typeof a === "object" || typeof b === "object") {
|
|
5007
|
-
throw TypeError(
|
|
5008
|
-
`When comparing object types, a custom comparator must be defined in the constructor's options parameter.`
|
|
5009
|
-
);
|
|
5115
|
+
throw new TypeError(ERR.comparatorRequired("MaxHeap"));
|
|
5010
5116
|
}
|
|
5011
5117
|
if (a < b) return 1;
|
|
5012
5118
|
if (a > b) return -1;
|
|
@@ -5171,7 +5277,7 @@ var _AbstractGraph = class _AbstractGraph extends IterableEntryBase {
|
|
|
5171
5277
|
const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
|
|
5172
5278
|
return this._addEdge(newEdge);
|
|
5173
5279
|
} else {
|
|
5174
|
-
throw new
|
|
5280
|
+
throw new TypeError(ERR.invalidArgument("dest must be a Vertex or vertex key when srcOrEdge is an Edge.", "Graph"));
|
|
5175
5281
|
}
|
|
5176
5282
|
}
|
|
5177
5283
|
}
|
|
@@ -5855,6 +5961,94 @@ var _AbstractGraph = class _AbstractGraph extends IterableEntryBase {
|
|
|
5855
5961
|
_getVertexKey(vertexOrKey) {
|
|
5856
5962
|
return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
|
|
5857
5963
|
}
|
|
5964
|
+
/**
|
|
5965
|
+
* The edge connector string used in visual output.
|
|
5966
|
+
* Override in subclasses (e.g., '--' for undirected, '->' for directed).
|
|
5967
|
+
*/
|
|
5968
|
+
get _edgeConnector() {
|
|
5969
|
+
return "--";
|
|
5970
|
+
}
|
|
5971
|
+
/**
|
|
5972
|
+
* Generate a text-based visual representation of the graph.
|
|
5973
|
+
*
|
|
5974
|
+
* **Adjacency list format:**
|
|
5975
|
+
* ```
|
|
5976
|
+
* Graph (5 vertices, 6 edges):
|
|
5977
|
+
* A -> B (1), C (2)
|
|
5978
|
+
* B -> D (3)
|
|
5979
|
+
* C -> (no outgoing edges)
|
|
5980
|
+
* D -> A (1)
|
|
5981
|
+
* E (isolated)
|
|
5982
|
+
* ```
|
|
5983
|
+
*
|
|
5984
|
+
* @param options - Optional display settings.
|
|
5985
|
+
* @param options.showWeight - Whether to show edge weights (default: true).
|
|
5986
|
+
* @returns The visual string.
|
|
5987
|
+
*/
|
|
5988
|
+
toVisual(options) {
|
|
5989
|
+
var _a;
|
|
5990
|
+
const showWeight = (_a = options == null ? void 0 : options.showWeight) != null ? _a : true;
|
|
5991
|
+
const vertices = [...this._vertexMap.values()];
|
|
5992
|
+
const vertexCount = vertices.length;
|
|
5993
|
+
const edgeCount = this.edgeSet().length;
|
|
5994
|
+
const lines = [`Graph (${vertexCount} vertices, ${edgeCount} edges):`];
|
|
5995
|
+
for (const vertex of vertices) {
|
|
5996
|
+
const neighbors = this.getNeighbors(vertex);
|
|
5997
|
+
if (neighbors.length === 0) {
|
|
5998
|
+
lines.push(` ${vertex.key} (isolated)`);
|
|
5999
|
+
} else {
|
|
6000
|
+
const edgeStrs = neighbors.map((neighbor) => {
|
|
6001
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
6002
|
+
if (edge && showWeight && edge.weight !== void 0 && edge.weight !== 1) {
|
|
6003
|
+
return `${neighbor.key} (${edge.weight})`;
|
|
6004
|
+
}
|
|
6005
|
+
return `${neighbor.key}`;
|
|
6006
|
+
});
|
|
6007
|
+
lines.push(` ${vertex.key} ${this._edgeConnector} ${edgeStrs.join(", ")}`);
|
|
6008
|
+
}
|
|
6009
|
+
}
|
|
6010
|
+
return lines.join("\n");
|
|
6011
|
+
}
|
|
6012
|
+
/**
|
|
6013
|
+
* Generate DOT language representation for Graphviz.
|
|
6014
|
+
*
|
|
6015
|
+
* @param options - Optional display settings.
|
|
6016
|
+
* @param options.name - Graph name (default: 'G').
|
|
6017
|
+
* @param options.showWeight - Whether to label edges with weight (default: true).
|
|
6018
|
+
* @returns DOT format string.
|
|
6019
|
+
*/
|
|
6020
|
+
toDot(options) {
|
|
6021
|
+
var _a, _b;
|
|
6022
|
+
const name = (_a = options == null ? void 0 : options.name) != null ? _a : "G";
|
|
6023
|
+
const showWeight = (_b = options == null ? void 0 : options.showWeight) != null ? _b : true;
|
|
6024
|
+
const isDirected = this._edgeConnector === "->";
|
|
6025
|
+
const graphType = isDirected ? "digraph" : "graph";
|
|
6026
|
+
const edgeOp = isDirected ? "->" : "--";
|
|
6027
|
+
const lines = [`${graphType} ${name} {`];
|
|
6028
|
+
for (const vertex of this._vertexMap.values()) {
|
|
6029
|
+
lines.push(` "${vertex.key}";`);
|
|
6030
|
+
}
|
|
6031
|
+
const visited = /* @__PURE__ */ new Set();
|
|
6032
|
+
for (const vertex of this._vertexMap.values()) {
|
|
6033
|
+
for (const neighbor of this.getNeighbors(vertex)) {
|
|
6034
|
+
const edgeId = isDirected ? `${vertex.key}->${neighbor.key}` : [vertex.key, neighbor.key].sort().join("--");
|
|
6035
|
+
if (visited.has(edgeId)) continue;
|
|
6036
|
+
visited.add(edgeId);
|
|
6037
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
6038
|
+
const label = edge && showWeight && edge.weight !== void 0 && edge.weight !== 1 ? ` [label="${edge.weight}"]` : "";
|
|
6039
|
+
lines.push(` "${vertex.key}" ${edgeOp} "${neighbor.key}"${label};`);
|
|
6040
|
+
}
|
|
6041
|
+
}
|
|
6042
|
+
lines.push("}");
|
|
6043
|
+
return lines.join("\n");
|
|
6044
|
+
}
|
|
6045
|
+
/**
|
|
6046
|
+
* Print the graph to console.
|
|
6047
|
+
* @param options - Display settings passed to `toVisual`.
|
|
6048
|
+
*/
|
|
6049
|
+
print(options) {
|
|
6050
|
+
console.log(this.toVisual(options));
|
|
6051
|
+
}
|
|
5858
6052
|
};
|
|
5859
6053
|
__name(_AbstractGraph, "AbstractGraph");
|
|
5860
6054
|
var AbstractGraph = _AbstractGraph;
|
|
@@ -5889,6 +6083,9 @@ var _DirectedGraph = class _DirectedGraph extends AbstractGraph {
|
|
|
5889
6083
|
__publicField(this, "_outEdgeMap", /* @__PURE__ */ new Map());
|
|
5890
6084
|
__publicField(this, "_inEdgeMap", /* @__PURE__ */ new Map());
|
|
5891
6085
|
}
|
|
6086
|
+
get _edgeConnector() {
|
|
6087
|
+
return "->";
|
|
6088
|
+
}
|
|
5892
6089
|
get outEdgeMap() {
|
|
5893
6090
|
return this._outEdgeMap;
|
|
5894
6091
|
}
|
|
@@ -6669,6 +6866,84 @@ var _UndirectedGraph = class _UndirectedGraph extends AbstractGraph {
|
|
|
6669
6866
|
cutVertices
|
|
6670
6867
|
};
|
|
6671
6868
|
}
|
|
6869
|
+
/**
|
|
6870
|
+
* Find biconnected components using edge-stack Tarjan variant.
|
|
6871
|
+
* A biconnected component is a maximal biconnected subgraph.
|
|
6872
|
+
* @returns Array of edge arrays, each representing a biconnected component.
|
|
6873
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
6874
|
+
*/
|
|
6875
|
+
getBiconnectedComponents() {
|
|
6876
|
+
const dfn = /* @__PURE__ */ new Map();
|
|
6877
|
+
const low = /* @__PURE__ */ new Map();
|
|
6878
|
+
const edgeStack = [];
|
|
6879
|
+
const components = [];
|
|
6880
|
+
let time = 0;
|
|
6881
|
+
const dfs = /* @__PURE__ */ __name((vertex, parent) => {
|
|
6882
|
+
dfn.set(vertex, time);
|
|
6883
|
+
low.set(vertex, time);
|
|
6884
|
+
time++;
|
|
6885
|
+
const neighbors = this.getNeighbors(vertex);
|
|
6886
|
+
let childCount = 0;
|
|
6887
|
+
for (const neighbor of neighbors) {
|
|
6888
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
6889
|
+
if (!edge) continue;
|
|
6890
|
+
if (!dfn.has(neighbor)) {
|
|
6891
|
+
childCount++;
|
|
6892
|
+
edgeStack.push(edge);
|
|
6893
|
+
dfs(neighbor, vertex);
|
|
6894
|
+
low.set(vertex, Math.min(low.get(vertex), low.get(neighbor)));
|
|
6895
|
+
if (parent === void 0 && childCount > 1 || parent !== void 0 && low.get(neighbor) >= dfn.get(vertex)) {
|
|
6896
|
+
const component = [];
|
|
6897
|
+
let e;
|
|
6898
|
+
do {
|
|
6899
|
+
e = edgeStack.pop();
|
|
6900
|
+
if (e) component.push(e);
|
|
6901
|
+
} while (e && e !== edge);
|
|
6902
|
+
if (component.length > 0) components.push(component);
|
|
6903
|
+
}
|
|
6904
|
+
} else if (neighbor !== parent && dfn.get(neighbor) < dfn.get(vertex)) {
|
|
6905
|
+
edgeStack.push(edge);
|
|
6906
|
+
low.set(vertex, Math.min(low.get(vertex), dfn.get(neighbor)));
|
|
6907
|
+
}
|
|
6908
|
+
}
|
|
6909
|
+
}, "dfs");
|
|
6910
|
+
for (const vertex of this.vertexMap.values()) {
|
|
6911
|
+
if (!dfn.has(vertex)) {
|
|
6912
|
+
dfs(vertex, void 0);
|
|
6913
|
+
if (edgeStack.length > 0) {
|
|
6914
|
+
components.push([...edgeStack]);
|
|
6915
|
+
edgeStack.length = 0;
|
|
6916
|
+
}
|
|
6917
|
+
}
|
|
6918
|
+
}
|
|
6919
|
+
return components;
|
|
6920
|
+
}
|
|
6921
|
+
/**
|
|
6922
|
+
* Detect whether the graph contains a cycle.
|
|
6923
|
+
* Uses DFS with parent tracking.
|
|
6924
|
+
* @returns `true` if a cycle exists, `false` otherwise.
|
|
6925
|
+
* @remarks Time O(V + E), Space O(V)
|
|
6926
|
+
*/
|
|
6927
|
+
hasCycle() {
|
|
6928
|
+
const visited = /* @__PURE__ */ new Set();
|
|
6929
|
+
const dfs = /* @__PURE__ */ __name((vertex, parent) => {
|
|
6930
|
+
visited.add(vertex);
|
|
6931
|
+
for (const neighbor of this.getNeighbors(vertex)) {
|
|
6932
|
+
if (!visited.has(neighbor)) {
|
|
6933
|
+
if (dfs(neighbor, vertex)) return true;
|
|
6934
|
+
} else if (neighbor !== parent) {
|
|
6935
|
+
return true;
|
|
6936
|
+
}
|
|
6937
|
+
}
|
|
6938
|
+
return false;
|
|
6939
|
+
}, "dfs");
|
|
6940
|
+
for (const vertex of this.vertexMap.values()) {
|
|
6941
|
+
if (!visited.has(vertex)) {
|
|
6942
|
+
if (dfs(vertex, void 0)) return true;
|
|
6943
|
+
}
|
|
6944
|
+
}
|
|
6945
|
+
return false;
|
|
6946
|
+
}
|
|
6672
6947
|
/**
|
|
6673
6948
|
* Get bridges discovered by `tarjan()`.
|
|
6674
6949
|
* @returns Array of edges that are bridges.
|
|
@@ -6821,29 +7096,6 @@ var _MapGraph = class _MapGraph extends DirectedGraph {
|
|
|
6821
7096
|
__name(_MapGraph, "MapGraph");
|
|
6822
7097
|
var MapGraph = _MapGraph;
|
|
6823
7098
|
|
|
6824
|
-
// src/common/index.ts
|
|
6825
|
-
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
6826
|
-
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
6827
|
-
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
6828
|
-
return DFSOperation2;
|
|
6829
|
-
})(DFSOperation || {});
|
|
6830
|
-
var _Range = class _Range {
|
|
6831
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
6832
|
-
this.low = low;
|
|
6833
|
-
this.high = high;
|
|
6834
|
-
this.includeLow = includeLow;
|
|
6835
|
-
this.includeHigh = includeHigh;
|
|
6836
|
-
}
|
|
6837
|
-
// Determine whether a key is within the range
|
|
6838
|
-
isInRange(key, comparator) {
|
|
6839
|
-
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
6840
|
-
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
6841
|
-
return lowCheck && highCheck;
|
|
6842
|
-
}
|
|
6843
|
-
};
|
|
6844
|
-
__name(_Range, "Range");
|
|
6845
|
-
var Range = _Range;
|
|
6846
|
-
|
|
6847
7099
|
// src/data-structures/binary-tree/binary-tree.ts
|
|
6848
7100
|
var _BinaryTreeNode = class _BinaryTreeNode {
|
|
6849
7101
|
/**
|
|
@@ -7016,7 +7268,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
7016
7268
|
if (isMapMode !== void 0) this._isMapMode = isMapMode;
|
|
7017
7269
|
if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
|
|
7018
7270
|
if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
|
|
7019
|
-
else if (toEntryFn) throw TypeError("toEntryFn
|
|
7271
|
+
else if (toEntryFn) throw new TypeError(ERR.notAFunction("toEntryFn", "BinaryTree"));
|
|
7020
7272
|
}
|
|
7021
7273
|
if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
|
|
7022
7274
|
}
|
|
@@ -7244,7 +7496,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
7244
7496
|
if (!this._root) {
|
|
7245
7497
|
this._setRoot(newNode);
|
|
7246
7498
|
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
7247
|
-
this._size = 1;
|
|
7499
|
+
if (newNode !== null) this._size = 1;
|
|
7248
7500
|
return true;
|
|
7249
7501
|
}
|
|
7250
7502
|
const queue = new Queue([this._root]);
|
|
@@ -7276,7 +7528,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
7276
7528
|
potentialParent.right = newNode;
|
|
7277
7529
|
}
|
|
7278
7530
|
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
7279
|
-
this._size++;
|
|
7531
|
+
if (newNode !== null) this._size++;
|
|
7280
7532
|
return true;
|
|
7281
7533
|
}
|
|
7282
7534
|
return false;
|
|
@@ -7845,7 +8097,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
7845
8097
|
}
|
|
7846
8098
|
/**
|
|
7847
8099
|
* Finds all leaf nodes in the tree.
|
|
7848
|
-
* @remarks Time O(N), visits every node. Space O(H) for recursive
|
|
8100
|
+
* @remarks Time O(N), visits every node. Space O(H) for recursive or iterative stack.
|
|
7849
8101
|
*
|
|
7850
8102
|
* @template C - The type of the callback function.
|
|
7851
8103
|
* @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
|
|
@@ -7868,15 +8120,15 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
7868
8120
|
}, "dfs");
|
|
7869
8121
|
dfs(startNode);
|
|
7870
8122
|
} else {
|
|
7871
|
-
const
|
|
7872
|
-
while (
|
|
7873
|
-
const cur =
|
|
8123
|
+
const stack = [startNode];
|
|
8124
|
+
while (stack.length > 0) {
|
|
8125
|
+
const cur = stack.pop();
|
|
7874
8126
|
if (this.isRealNode(cur)) {
|
|
7875
8127
|
if (this.isLeaf(cur)) {
|
|
7876
8128
|
leaves.push(callback(cur));
|
|
7877
8129
|
}
|
|
7878
|
-
if (this.isRealNode(cur.
|
|
7879
|
-
if (this.isRealNode(cur.
|
|
8130
|
+
if (this.isRealNode(cur.right)) stack.push(cur.right);
|
|
8131
|
+
if (this.isRealNode(cur.left)) stack.push(cur.left);
|
|
7880
8132
|
}
|
|
7881
8133
|
}
|
|
7882
8134
|
}
|
|
@@ -8332,42 +8584,98 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
8332
8584
|
_displayAux(node, options) {
|
|
8333
8585
|
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
8334
8586
|
const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
|
|
8345
|
-
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
|
|
8349
|
-
|
|
8350
|
-
|
|
8351
|
-
|
|
8352
|
-
|
|
8353
|
-
|
|
8354
|
-
const
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8587
|
+
const newFrame = /* @__PURE__ */ __name((n) => ({
|
|
8588
|
+
node: n,
|
|
8589
|
+
stage: 0,
|
|
8590
|
+
leftLayout: emptyDisplayLayout,
|
|
8591
|
+
rightLayout: emptyDisplayLayout
|
|
8592
|
+
}), "newFrame");
|
|
8593
|
+
const stack = [newFrame(node)];
|
|
8594
|
+
let result = emptyDisplayLayout;
|
|
8595
|
+
const setChildResult = /* @__PURE__ */ __name((layout) => {
|
|
8596
|
+
if (stack.length === 0) {
|
|
8597
|
+
result = layout;
|
|
8598
|
+
return;
|
|
8599
|
+
}
|
|
8600
|
+
const parent = stack[stack.length - 1];
|
|
8601
|
+
if (parent.stage === 1) parent.leftLayout = layout;
|
|
8602
|
+
else parent.rightLayout = layout;
|
|
8603
|
+
}, "setChildResult");
|
|
8604
|
+
while (stack.length > 0) {
|
|
8605
|
+
const frame = stack[stack.length - 1];
|
|
8606
|
+
const cur = frame.node;
|
|
8607
|
+
if (frame.stage === 0) {
|
|
8608
|
+
if (this._isDisplayLeaf(cur, options)) {
|
|
8609
|
+
stack.pop();
|
|
8610
|
+
const layout = this._resolveDisplayLeaf(cur, options, emptyDisplayLayout);
|
|
8611
|
+
setChildResult(layout);
|
|
8612
|
+
continue;
|
|
8613
|
+
}
|
|
8614
|
+
frame.stage = 1;
|
|
8615
|
+
stack.push(newFrame(cur.left));
|
|
8616
|
+
} else if (frame.stage === 1) {
|
|
8617
|
+
frame.stage = 2;
|
|
8618
|
+
stack.push(newFrame(cur.right));
|
|
8619
|
+
} else {
|
|
8620
|
+
stack.pop();
|
|
8621
|
+
const line = this.isNIL(cur) ? "S" : String(cur.key);
|
|
8622
|
+
const layout = _BinaryTree._buildNodeDisplay(line, line.length, frame.leftLayout, frame.rightLayout);
|
|
8623
|
+
setChildResult(layout);
|
|
8363
8624
|
}
|
|
8364
|
-
return [
|
|
8365
|
-
mergedLines,
|
|
8366
|
-
leftWidth + width + rightWidth,
|
|
8367
|
-
Math.max(leftHeight, rightHeight) + 2,
|
|
8368
|
-
leftWidth + Math.floor(width / 2)
|
|
8369
|
-
];
|
|
8370
8625
|
}
|
|
8626
|
+
return result;
|
|
8627
|
+
}
|
|
8628
|
+
static _buildNodeDisplay(line, width, left, right) {
|
|
8629
|
+
const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
|
|
8630
|
+
const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
|
|
8631
|
+
const firstLine = " ".repeat(Math.max(0, leftMiddle + 1)) + "_".repeat(Math.max(0, leftWidth - leftMiddle - 1)) + line + "_".repeat(Math.max(0, rightMiddle)) + " ".repeat(Math.max(0, rightWidth - rightMiddle));
|
|
8632
|
+
const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
|
|
8633
|
+
const mergedLines = [firstLine, secondLine];
|
|
8634
|
+
for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
|
|
8635
|
+
const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
|
|
8636
|
+
const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
|
|
8637
|
+
mergedLines.push(leftLine + " ".repeat(width) + rightLine);
|
|
8638
|
+
}
|
|
8639
|
+
return [
|
|
8640
|
+
mergedLines,
|
|
8641
|
+
leftWidth + width + rightWidth,
|
|
8642
|
+
Math.max(leftHeight, rightHeight) + 2,
|
|
8643
|
+
leftWidth + Math.floor(width / 2)
|
|
8644
|
+
];
|
|
8645
|
+
}
|
|
8646
|
+
/**
|
|
8647
|
+
* Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
|
|
8648
|
+
*/
|
|
8649
|
+
_isDisplayLeaf(node, options) {
|
|
8650
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
8651
|
+
if (node === null && !isShowNull) return true;
|
|
8652
|
+
if (node === void 0 && !isShowUndefined) return true;
|
|
8653
|
+
if (this.isNIL(node) && !isShowRedBlackNIL) return true;
|
|
8654
|
+
if (node === null || node === void 0) return true;
|
|
8655
|
+
const hasDisplayableLeft = this._hasDisplayableChild(node.left, options);
|
|
8656
|
+
const hasDisplayableRight = this._hasDisplayableChild(node.right, options);
|
|
8657
|
+
return !hasDisplayableLeft && !hasDisplayableRight;
|
|
8658
|
+
}
|
|
8659
|
+
_hasDisplayableChild(child, options) {
|
|
8660
|
+
if (child === null) return !!options.isShowNull;
|
|
8661
|
+
if (child === void 0) return !!options.isShowUndefined;
|
|
8662
|
+
if (this.isNIL(child)) return !!options.isShowRedBlackNIL;
|
|
8663
|
+
return true;
|
|
8664
|
+
}
|
|
8665
|
+
/**
|
|
8666
|
+
* Resolve a display leaf node to its layout.
|
|
8667
|
+
*/
|
|
8668
|
+
_resolveDisplayLeaf(node, options, emptyDisplayLayout) {
|
|
8669
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
8670
|
+
if (node === null && !isShowNull) return emptyDisplayLayout;
|
|
8671
|
+
if (node === void 0 && !isShowUndefined) return emptyDisplayLayout;
|
|
8672
|
+
if (this.isNIL(node) && !isShowRedBlackNIL) return emptyDisplayLayout;
|
|
8673
|
+
if (node !== null && node !== void 0) {
|
|
8674
|
+
const line2 = this.isNIL(node) ? "S" : String(node.key);
|
|
8675
|
+
return _BinaryTree._buildNodeDisplay(line2, line2.length, emptyDisplayLayout, emptyDisplayLayout);
|
|
8676
|
+
}
|
|
8677
|
+
const line = node === void 0 ? "U" : "N";
|
|
8678
|
+
return _BinaryTree._buildNodeDisplay(line, line.length, [[""], 1, 0, 0], [[""], 1, 0, 0]);
|
|
8371
8679
|
}
|
|
8372
8680
|
/**
|
|
8373
8681
|
* (Protected) Swaps the key/value properties of two nodes.
|
|
@@ -9373,9 +9681,15 @@ var _BST = class _BST extends BinaryTree {
|
|
|
9373
9681
|
if (a < b) return -1;
|
|
9374
9682
|
return 0;
|
|
9375
9683
|
}
|
|
9684
|
+
if (a instanceof Date && b instanceof Date) {
|
|
9685
|
+
const ta = a.getTime();
|
|
9686
|
+
const tb = b.getTime();
|
|
9687
|
+
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("BST"));
|
|
9688
|
+
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
9689
|
+
}
|
|
9376
9690
|
if (typeof a === "object" || typeof b === "object") {
|
|
9377
|
-
throw TypeError(
|
|
9378
|
-
|
|
9691
|
+
throw new TypeError(
|
|
9692
|
+
ERR.comparatorRequired("BST")
|
|
9379
9693
|
);
|
|
9380
9694
|
}
|
|
9381
9695
|
return 0;
|
|
@@ -9889,7 +10203,7 @@ var _BinaryIndexedTree = class _BinaryIndexedTree {
|
|
|
9889
10203
|
*/
|
|
9890
10204
|
read(count) {
|
|
9891
10205
|
if (!Number.isInteger(count)) {
|
|
9892
|
-
throw new Error("
|
|
10206
|
+
throw new Error(ERR.invalidArgument("count must be an integer", "BinaryIndexedTree"));
|
|
9893
10207
|
}
|
|
9894
10208
|
return this._read(Math.max(Math.min(count, this.max), 0));
|
|
9895
10209
|
}
|
|
@@ -9901,7 +10215,7 @@ var _BinaryIndexedTree = class _BinaryIndexedTree {
|
|
|
9901
10215
|
*/
|
|
9902
10216
|
lowerBound(sum) {
|
|
9903
10217
|
if (this.negativeCount > 0) {
|
|
9904
|
-
throw new Error("Sequence is not non-descending");
|
|
10218
|
+
throw new Error(ERR.invalidOperation("Sequence is not non-descending.", "BinaryIndexedTree"));
|
|
9905
10219
|
}
|
|
9906
10220
|
return this._binarySearch(sum, (x, y) => x < y);
|
|
9907
10221
|
}
|
|
@@ -9914,7 +10228,7 @@ var _BinaryIndexedTree = class _BinaryIndexedTree {
|
|
|
9914
10228
|
*/
|
|
9915
10229
|
upperBound(sum) {
|
|
9916
10230
|
if (this.negativeCount > 0) {
|
|
9917
|
-
throw new Error("
|
|
10231
|
+
throw new Error(ERR.invalidOperation("Sequence must not be descending.", "BinaryIndexedTree"));
|
|
9918
10232
|
}
|
|
9919
10233
|
return this._binarySearch(sum, (x, y) => x <= y);
|
|
9920
10234
|
}
|
|
@@ -9965,10 +10279,10 @@ var _BinaryIndexedTree = class _BinaryIndexedTree {
|
|
|
9965
10279
|
*/
|
|
9966
10280
|
_checkIndex(index) {
|
|
9967
10281
|
if (!Number.isInteger(index)) {
|
|
9968
|
-
throw new
|
|
10282
|
+
throw new TypeError(ERR.invalidIndex("BinaryIndexedTree"));
|
|
9969
10283
|
}
|
|
9970
10284
|
if (index < 0 || index >= this.max) {
|
|
9971
|
-
throw new
|
|
10285
|
+
throw new RangeError(ERR.indexOutOfRange(index, 0, this.max - 1, "BinaryIndexedTree"));
|
|
9972
10286
|
}
|
|
9973
10287
|
}
|
|
9974
10288
|
/**
|
|
@@ -11557,6 +11871,24 @@ var _RedBlackTree = class _RedBlackTree extends BST {
|
|
|
11557
11871
|
* @param [thisArg] - See parameter type for details.
|
|
11558
11872
|
* @returns A new RedBlackTree with mapped entries.
|
|
11559
11873
|
*/
|
|
11874
|
+
/**
|
|
11875
|
+
* Red-Black trees are self-balancing — `perfectlyBalance` rebuilds via
|
|
11876
|
+
* sorted bulk insert, which naturally produces a balanced RBT.
|
|
11877
|
+
* @remarks Time O(N), Space O(N)
|
|
11878
|
+
*/
|
|
11879
|
+
perfectlyBalance(iterationType) {
|
|
11880
|
+
const entries = [];
|
|
11881
|
+
for (const [key, value] of this) entries.push([key, value]);
|
|
11882
|
+
if (entries.length <= 1) return true;
|
|
11883
|
+
this.clear();
|
|
11884
|
+
this.setMany(
|
|
11885
|
+
entries.map(([k]) => k),
|
|
11886
|
+
entries.map(([, v]) => v),
|
|
11887
|
+
true
|
|
11888
|
+
// isBalanceAdd
|
|
11889
|
+
);
|
|
11890
|
+
return true;
|
|
11891
|
+
}
|
|
11560
11892
|
map(callback, options, thisArg) {
|
|
11561
11893
|
const out = this._createLike([], options);
|
|
11562
11894
|
let index = 0;
|
|
@@ -11881,7 +12213,7 @@ var _TreeSet = class _TreeSet {
|
|
|
11881
12213
|
static createDefaultComparator() {
|
|
11882
12214
|
return (a, b) => {
|
|
11883
12215
|
if (typeof a === "number" && typeof b === "number") {
|
|
11884
|
-
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError("TreeSet
|
|
12216
|
+
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN("TreeSet"));
|
|
11885
12217
|
const aa = Object.is(a, -0) ? 0 : a;
|
|
11886
12218
|
const bb = Object.is(b, -0) ? 0 : b;
|
|
11887
12219
|
return aa > bb ? 1 : aa < bb ? -1 : 0;
|
|
@@ -11892,10 +12224,10 @@ var _TreeSet = class _TreeSet {
|
|
|
11892
12224
|
if (a instanceof Date && b instanceof Date) {
|
|
11893
12225
|
const ta = a.getTime();
|
|
11894
12226
|
const tb = b.getTime();
|
|
11895
|
-
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError("TreeSet
|
|
12227
|
+
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("TreeSet"));
|
|
11896
12228
|
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
11897
12229
|
}
|
|
11898
|
-
throw new TypeError("TreeSet
|
|
12230
|
+
throw new TypeError(ERR.comparatorRequired("TreeSet"));
|
|
11899
12231
|
};
|
|
11900
12232
|
}
|
|
11901
12233
|
/**
|
|
@@ -11913,15 +12245,15 @@ var _TreeSet = class _TreeSet {
|
|
|
11913
12245
|
_validateKey(key) {
|
|
11914
12246
|
if (!__privateGet(this, _isDefaultComparator)) return;
|
|
11915
12247
|
if (typeof key === "number") {
|
|
11916
|
-
if (Number.isNaN(key)) throw new TypeError("TreeSet
|
|
12248
|
+
if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeSet"));
|
|
11917
12249
|
return;
|
|
11918
12250
|
}
|
|
11919
12251
|
if (typeof key === "string") return;
|
|
11920
12252
|
if (key instanceof Date) {
|
|
11921
|
-
if (Number.isNaN(key.getTime())) throw new TypeError("TreeSet
|
|
12253
|
+
if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeSet"));
|
|
11922
12254
|
return;
|
|
11923
12255
|
}
|
|
11924
|
-
throw new TypeError("TreeSet
|
|
12256
|
+
throw new TypeError(ERR.comparatorRequired("TreeSet"));
|
|
11925
12257
|
}
|
|
11926
12258
|
/**
|
|
11927
12259
|
* Add a key to the set (no-op if already present).
|
|
@@ -12244,15 +12576,15 @@ var _TreeMultiMap = class _TreeMultiMap {
|
|
|
12244
12576
|
_validateKey(key) {
|
|
12245
12577
|
if (!__privateGet(this, _isDefaultComparator2)) return;
|
|
12246
12578
|
if (typeof key === "number") {
|
|
12247
|
-
if (Number.isNaN(key)) throw new TypeError("TreeMultiMap
|
|
12579
|
+
if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeMultiMap"));
|
|
12248
12580
|
return;
|
|
12249
12581
|
}
|
|
12250
12582
|
if (typeof key === "string") return;
|
|
12251
12583
|
if (key instanceof Date) {
|
|
12252
|
-
if (Number.isNaN(key.getTime())) throw new TypeError("TreeMultiMap
|
|
12584
|
+
if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeMultiMap"));
|
|
12253
12585
|
return;
|
|
12254
12586
|
}
|
|
12255
|
-
throw new TypeError("TreeMultiMap
|
|
12587
|
+
throw new TypeError(ERR.comparatorRequired("TreeMultiMap"));
|
|
12256
12588
|
}
|
|
12257
12589
|
/**
|
|
12258
12590
|
* Number of distinct keys.
|
|
@@ -12677,7 +13009,7 @@ var _TreeMap = class _TreeMap {
|
|
|
12677
13009
|
[k, v] = toEntryFn(item);
|
|
12678
13010
|
} else {
|
|
12679
13011
|
if (!Array.isArray(item) || item.length < 2) {
|
|
12680
|
-
throw new TypeError("TreeMap
|
|
13012
|
+
throw new TypeError(ERR.invalidEntry("TreeMap"));
|
|
12681
13013
|
}
|
|
12682
13014
|
k = item[0];
|
|
12683
13015
|
v = item[1];
|
|
@@ -12698,7 +13030,7 @@ var _TreeMap = class _TreeMap {
|
|
|
12698
13030
|
static createDefaultComparator() {
|
|
12699
13031
|
return (a, b) => {
|
|
12700
13032
|
if (typeof a === "number" && typeof b === "number") {
|
|
12701
|
-
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError("TreeMap
|
|
13033
|
+
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN("TreeMap"));
|
|
12702
13034
|
const aa = Object.is(a, -0) ? 0 : a;
|
|
12703
13035
|
const bb = Object.is(b, -0) ? 0 : b;
|
|
12704
13036
|
return aa > bb ? 1 : aa < bb ? -1 : 0;
|
|
@@ -12709,24 +13041,24 @@ var _TreeMap = class _TreeMap {
|
|
|
12709
13041
|
if (a instanceof Date && b instanceof Date) {
|
|
12710
13042
|
const ta = a.getTime();
|
|
12711
13043
|
const tb = b.getTime();
|
|
12712
|
-
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError("TreeMap
|
|
13044
|
+
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("TreeMap"));
|
|
12713
13045
|
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
12714
13046
|
}
|
|
12715
|
-
throw new TypeError("TreeMap
|
|
13047
|
+
throw new TypeError(ERR.comparatorRequired("TreeMap"));
|
|
12716
13048
|
};
|
|
12717
13049
|
}
|
|
12718
13050
|
_validateKey(key) {
|
|
12719
13051
|
if (!__privateGet(this, _isDefaultComparator3)) return;
|
|
12720
13052
|
if (typeof key === "number") {
|
|
12721
|
-
if (Number.isNaN(key)) throw new TypeError("TreeMap
|
|
13053
|
+
if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeMap"));
|
|
12722
13054
|
return;
|
|
12723
13055
|
}
|
|
12724
13056
|
if (typeof key === "string") return;
|
|
12725
13057
|
if (key instanceof Date) {
|
|
12726
|
-
if (Number.isNaN(key.getTime())) throw new TypeError("TreeMap
|
|
13058
|
+
if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeMap"));
|
|
12727
13059
|
return;
|
|
12728
13060
|
}
|
|
12729
|
-
throw new TypeError("TreeMap
|
|
13061
|
+
throw new TypeError(ERR.comparatorRequired("TreeMap"));
|
|
12730
13062
|
}
|
|
12731
13063
|
/**
|
|
12732
13064
|
* Number of entries in the map.
|
|
@@ -13055,22 +13387,22 @@ var _TreeMultiSet = class _TreeMultiSet {
|
|
|
13055
13387
|
_validateKey(key) {
|
|
13056
13388
|
if (!__privateGet(this, _isDefaultComparator4)) return;
|
|
13057
13389
|
if (typeof key === "number") {
|
|
13058
|
-
if (Number.isNaN(key)) throw new TypeError("TreeMultiSet
|
|
13390
|
+
if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeMultiSet"));
|
|
13059
13391
|
return;
|
|
13060
13392
|
}
|
|
13061
13393
|
if (typeof key === "string") return;
|
|
13062
13394
|
if (key instanceof Date) {
|
|
13063
|
-
if (Number.isNaN(key.getTime())) throw new TypeError("TreeMultiSet
|
|
13395
|
+
if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeMultiSet"));
|
|
13064
13396
|
return;
|
|
13065
13397
|
}
|
|
13066
|
-
throw new TypeError("TreeMultiSet
|
|
13398
|
+
throw new TypeError(ERR.comparatorRequired("TreeMultiSet"));
|
|
13067
13399
|
}
|
|
13068
13400
|
/**
|
|
13069
13401
|
* Validates that count is a non-negative safe integer.
|
|
13070
13402
|
* @remarks Time O(1), Space O(1)
|
|
13071
13403
|
*/
|
|
13072
13404
|
_validateCount(n) {
|
|
13073
|
-
if (!Number.isSafeInteger(n) || n < 0) throw new RangeError("
|
|
13405
|
+
if (!Number.isSafeInteger(n) || n < 0) throw new RangeError(ERR.invalidArgument("count must be a safe integer >= 0.", "TreeMultiSet"));
|
|
13074
13406
|
}
|
|
13075
13407
|
/**
|
|
13076
13408
|
* Total occurrences (sumCounts).
|
|
@@ -13498,9 +13830,7 @@ var _MaxPriorityQueue = class _MaxPriorityQueue extends PriorityQueue {
|
|
|
13498
13830
|
super(elements, {
|
|
13499
13831
|
comparator: /* @__PURE__ */ __name((a, b) => {
|
|
13500
13832
|
if (typeof a === "object" || typeof b === "object") {
|
|
13501
|
-
throw TypeError(
|
|
13502
|
-
`When comparing object types, a custom comparator must be defined in the constructor's options parameter.`
|
|
13503
|
-
);
|
|
13833
|
+
throw new TypeError(ERR.comparatorRequired("MaxPriorityQueue"));
|
|
13504
13834
|
}
|
|
13505
13835
|
if (a < b) return 1;
|
|
13506
13836
|
if (a > b) return -1;
|
|
@@ -13641,7 +13971,7 @@ var _Matrix = class _Matrix {
|
|
|
13641
13971
|
*/
|
|
13642
13972
|
add(matrix) {
|
|
13643
13973
|
if (!this.isMatchForCalculate(matrix)) {
|
|
13644
|
-
throw new Error("
|
|
13974
|
+
throw new Error(ERR.matrixDimensionMismatch("addition"));
|
|
13645
13975
|
}
|
|
13646
13976
|
const resultData = [];
|
|
13647
13977
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -13673,7 +14003,7 @@ var _Matrix = class _Matrix {
|
|
|
13673
14003
|
*/
|
|
13674
14004
|
subtract(matrix) {
|
|
13675
14005
|
if (!this.isMatchForCalculate(matrix)) {
|
|
13676
|
-
throw new Error("
|
|
14006
|
+
throw new Error(ERR.matrixDimensionMismatch("subtraction"));
|
|
13677
14007
|
}
|
|
13678
14008
|
const resultData = [];
|
|
13679
14009
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -13704,7 +14034,7 @@ var _Matrix = class _Matrix {
|
|
|
13704
14034
|
*/
|
|
13705
14035
|
multiply(matrix) {
|
|
13706
14036
|
if (this.cols !== matrix.rows) {
|
|
13707
|
-
throw new Error("
|
|
14037
|
+
throw new Error(ERR.matrixDimensionMismatch("multiplication (A.cols must equal B.rows)"));
|
|
13708
14038
|
}
|
|
13709
14039
|
const resultData = [];
|
|
13710
14040
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -13738,7 +14068,7 @@ var _Matrix = class _Matrix {
|
|
|
13738
14068
|
*/
|
|
13739
14069
|
transpose() {
|
|
13740
14070
|
if (this.data.some((row) => row.length !== this.rows)) {
|
|
13741
|
-
throw new Error(
|
|
14071
|
+
throw new Error(ERR.matrixNotRectangular());
|
|
13742
14072
|
}
|
|
13743
14073
|
const resultData = [];
|
|
13744
14074
|
for (let j = 0; j < this.cols; j++) {
|
|
@@ -13763,7 +14093,7 @@ var _Matrix = class _Matrix {
|
|
|
13763
14093
|
inverse() {
|
|
13764
14094
|
var _a;
|
|
13765
14095
|
if (this.rows !== this.cols) {
|
|
13766
|
-
throw new Error(
|
|
14096
|
+
throw new Error(ERR.matrixNotSquare());
|
|
13767
14097
|
}
|
|
13768
14098
|
const augmentedMatrixData = [];
|
|
13769
14099
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -13785,12 +14115,12 @@ var _Matrix = class _Matrix {
|
|
|
13785
14115
|
pivotRow++;
|
|
13786
14116
|
}
|
|
13787
14117
|
if (pivotRow === this.rows) {
|
|
13788
|
-
throw new Error(
|
|
14118
|
+
throw new Error(ERR.matrixSingular());
|
|
13789
14119
|
}
|
|
13790
14120
|
augmentedMatrix._swapRows(i, pivotRow);
|
|
13791
14121
|
const pivotElement = (_a = augmentedMatrix.get(i, i)) != null ? _a : 1;
|
|
13792
14122
|
if (pivotElement === 0) {
|
|
13793
|
-
throw new Error(
|
|
14123
|
+
throw new Error(ERR.matrixSingular());
|
|
13794
14124
|
}
|
|
13795
14125
|
augmentedMatrix._scaleRow(i, 1 / pivotElement);
|
|
13796
14126
|
for (let j = 0; j < this.rows; j++) {
|
|
@@ -13820,9 +14150,7 @@ var _Matrix = class _Matrix {
|
|
|
13820
14150
|
*/
|
|
13821
14151
|
dot(matrix) {
|
|
13822
14152
|
if (this.cols !== matrix.rows) {
|
|
13823
|
-
throw new Error(
|
|
13824
|
-
"Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product."
|
|
13825
|
-
);
|
|
14153
|
+
throw new Error(ERR.matrixDimensionMismatch("dot product (A.cols must equal B.rows)"));
|
|
13826
14154
|
}
|
|
13827
14155
|
const resultData = [];
|
|
13828
14156
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -14444,7 +14772,7 @@ var _Trie = class _Trie extends IterableElementBase {
|
|
|
14444
14772
|
for (const x of this) {
|
|
14445
14773
|
const v = thisArg === void 0 ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
|
|
14446
14774
|
if (typeof v !== "string") {
|
|
14447
|
-
throw new TypeError(
|
|
14775
|
+
throw new TypeError(ERR.callbackReturnType("string", typeof v, "Trie.map"));
|
|
14448
14776
|
}
|
|
14449
14777
|
newTrie.add(v);
|
|
14450
14778
|
}
|
|
@@ -14677,6 +15005,6 @@ var TreeNode = _TreeNode;
|
|
|
14677
15005
|
* @license MIT License
|
|
14678
15006
|
*/
|
|
14679
15007
|
|
|
14680
|
-
export { AVLTree, AVLTreeNode, AbstractEdge, AbstractGraph, AbstractVertex, BST, BSTNode, BinaryIndexedTree, BinaryTree, BinaryTreeNode, Character, DFSOperation, Deque, DirectedEdge, DirectedGraph, DirectedVertex, DoublyLinkedList, DoublyLinkedListNode, FibonacciHeap, FibonacciHeapNode, HashMap, Heap, IterableElementBase, IterableEntryBase, LinkedHashMap, LinkedListQueue, MapEdge, MapGraph, MapVertex, Matrix, MaxHeap, MaxPriorityQueue, MinHeap, MinPriorityQueue, Navigator, PriorityQueue, Queue, Range, RedBlackTree, RedBlackTreeNode, SegmentTree, SegmentTreeNode, SinglyLinkedList, SinglyLinkedListNode, SkipList, SkipListNode, Stack, TreeMap, TreeMultiMap, TreeMultiMapNode, TreeMultiSet, TreeNode, TreeSet, Trie, TrieNode, UndirectedEdge, UndirectedGraph, UndirectedVertex, arrayRemove, asyncTrampoline, calcMinUnitsRequired, getMSB, isComparable, isTrampolineThunk, isWeakKey, makeAsyncTrampoline, makeTrampoline, makeTrampolineThunk, rangeCheck, roundFixed, throwRangeError, toBinaryString, trampoline, uuidV4 };
|
|
15008
|
+
export { AVLTree, AVLTreeNode, AbstractEdge, AbstractGraph, AbstractVertex, BST, BSTNode, BinaryIndexedTree, BinaryTree, BinaryTreeNode, Character, DFSOperation, Deque, DirectedEdge, DirectedGraph, DirectedVertex, DoublyLinkedList, DoublyLinkedListNode, ERR, FibonacciHeap, FibonacciHeapNode, HashMap, Heap, IterableElementBase, IterableEntryBase, LinkedHashMap, LinkedListQueue, MapEdge, MapGraph, MapVertex, Matrix, MaxHeap, MaxPriorityQueue, MinHeap, MinPriorityQueue, Navigator, PriorityQueue, Queue, Range, RedBlackTree, RedBlackTreeNode, SegmentTree, SegmentTreeNode, SinglyLinkedList, SinglyLinkedListNode, SkipList, SkipListNode, Stack, TreeMap, TreeMultiMap, TreeMultiMapNode, TreeMultiSet, TreeNode, TreeSet, Trie, TrieNode, UndirectedEdge, UndirectedGraph, UndirectedVertex, arrayRemove, asyncTrampoline, calcMinUnitsRequired, getMSB, isComparable, isTrampolineThunk, isWeakKey, makeAsyncTrampoline, makeTrampoline, makeTrampolineThunk, rangeCheck, roundFixed, throwRangeError, toBinaryString, trampoline, uuidV4 };
|
|
14681
15009
|
//# sourceMappingURL=index.mjs.map
|
|
14682
15010
|
//# sourceMappingURL=index.mjs.map
|