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
|
@@ -48,6 +48,7 @@ var dataStructureTyped = (() => {
|
|
|
48
48
|
DirectedVertex: () => DirectedVertex,
|
|
49
49
|
DoublyLinkedList: () => DoublyLinkedList,
|
|
50
50
|
DoublyLinkedListNode: () => DoublyLinkedListNode,
|
|
51
|
+
ERR: () => ERR,
|
|
51
52
|
FibonacciHeap: () => FibonacciHeap,
|
|
52
53
|
FibonacciHeapNode: () => FibonacciHeapNode,
|
|
53
54
|
HashMap: () => HashMap,
|
|
@@ -285,6 +286,52 @@ var dataStructureTyped = (() => {
|
|
|
285
286
|
}
|
|
286
287
|
};
|
|
287
288
|
|
|
289
|
+
// src/common/error.ts
|
|
290
|
+
var ERR = {
|
|
291
|
+
// Range / index
|
|
292
|
+
indexOutOfRange: (index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`,
|
|
293
|
+
invalidIndex: (ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`,
|
|
294
|
+
// Type / argument
|
|
295
|
+
invalidArgument: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
296
|
+
comparatorRequired: (ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`,
|
|
297
|
+
invalidKey: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
298
|
+
notAFunction: (name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`,
|
|
299
|
+
invalidEntry: (ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`,
|
|
300
|
+
invalidNaN: (ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`,
|
|
301
|
+
invalidDate: (ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`,
|
|
302
|
+
reduceEmpty: (ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`,
|
|
303
|
+
callbackReturnType: (expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`,
|
|
304
|
+
// State / operation
|
|
305
|
+
invalidOperation: (reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`,
|
|
306
|
+
// Matrix
|
|
307
|
+
matrixDimensionMismatch: (op) => `Matrix: Dimensions must be compatible for ${op}.`,
|
|
308
|
+
matrixSingular: () => "Matrix: Singular matrix, inverse does not exist.",
|
|
309
|
+
matrixNotSquare: () => "Matrix: Must be square for inversion.",
|
|
310
|
+
matrixNotRectangular: () => "Matrix: Must be rectangular for transposition.",
|
|
311
|
+
matrixRowMismatch: (expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// src/common/index.ts
|
|
315
|
+
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
316
|
+
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
317
|
+
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
318
|
+
return DFSOperation2;
|
|
319
|
+
})(DFSOperation || {});
|
|
320
|
+
var Range = class {
|
|
321
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
322
|
+
this.low = low;
|
|
323
|
+
this.high = high;
|
|
324
|
+
this.includeLow = includeLow;
|
|
325
|
+
this.includeHigh = includeHigh;
|
|
326
|
+
}
|
|
327
|
+
// Determine whether a key is within the range
|
|
328
|
+
isInRange(key, comparator) {
|
|
329
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
330
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
331
|
+
return lowCheck && highCheck;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
|
|
288
335
|
// src/data-structures/base/iterable-element-base.ts
|
|
289
336
|
var IterableElementBase = class {
|
|
290
337
|
/**
|
|
@@ -307,7 +354,7 @@ var dataStructureTyped = (() => {
|
|
|
307
354
|
if (options) {
|
|
308
355
|
const { toElementFn } = options;
|
|
309
356
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
310
|
-
else if (toElementFn) throw new TypeError("toElementFn
|
|
357
|
+
else if (toElementFn) throw new TypeError(ERR.notAFunction("toElementFn"));
|
|
311
358
|
}
|
|
312
359
|
}
|
|
313
360
|
/**
|
|
@@ -463,7 +510,7 @@ var dataStructureTyped = (() => {
|
|
|
463
510
|
acc = initialValue;
|
|
464
511
|
} else {
|
|
465
512
|
const first = iter.next();
|
|
466
|
-
if (first.done) throw new TypeError(
|
|
513
|
+
if (first.done) throw new TypeError(ERR.reduceEmpty());
|
|
467
514
|
acc = first.value;
|
|
468
515
|
index = 1;
|
|
469
516
|
}
|
|
@@ -531,8 +578,10 @@ var dataStructureTyped = (() => {
|
|
|
531
578
|
}
|
|
532
579
|
return 1 << 31 - Math.clz32(value);
|
|
533
580
|
};
|
|
534
|
-
var rangeCheck = (index, min, max, message
|
|
535
|
-
if (index < min || index > max)
|
|
581
|
+
var rangeCheck = (index, min, max, message) => {
|
|
582
|
+
if (index < min || index > max) {
|
|
583
|
+
throw new RangeError(message != null ? message : `Index ${index} is out of range [${min}, ${max}].`);
|
|
584
|
+
}
|
|
536
585
|
};
|
|
537
586
|
var throwRangeError = (message = "The value is off-limits.") => {
|
|
538
587
|
throw new RangeError(message);
|
|
@@ -894,8 +943,8 @@ var dataStructureTyped = (() => {
|
|
|
894
943
|
if (this.isEntry(rawElement)) {
|
|
895
944
|
return rawElement;
|
|
896
945
|
}
|
|
897
|
-
throw new
|
|
898
|
-
"If
|
|
946
|
+
throw new TypeError(
|
|
947
|
+
ERR.invalidArgument("If elements do not adhere to [key, value], provide options.toEntryFn to transform raw records.", "HashMap")
|
|
899
948
|
);
|
|
900
949
|
});
|
|
901
950
|
__publicField(this, "_size", 0);
|
|
@@ -1180,6 +1229,13 @@ var dataStructureTyped = (() => {
|
|
|
1180
1229
|
}
|
|
1181
1230
|
}
|
|
1182
1231
|
_deleteNode(node) {
|
|
1232
|
+
const key = node.key;
|
|
1233
|
+
if (isWeakKey(key)) {
|
|
1234
|
+
this._objMap.delete(key);
|
|
1235
|
+
} else {
|
|
1236
|
+
const hash = this._hashFn(key);
|
|
1237
|
+
delete this._noObjMap[hash];
|
|
1238
|
+
}
|
|
1183
1239
|
const { prev, next } = node;
|
|
1184
1240
|
prev.next = next;
|
|
1185
1241
|
next.prev = prev;
|
|
@@ -3660,17 +3716,16 @@ var dataStructureTyped = (() => {
|
|
|
3660
3716
|
|
|
3661
3717
|
// src/data-structures/queue/deque.ts
|
|
3662
3718
|
var Deque = class extends LinearBase {
|
|
3663
|
-
/**
|
|
3664
|
-
* Create a Deque and optionally bulk-insert elements.
|
|
3665
|
-
* @remarks Time O(N), Space O(N)
|
|
3666
|
-
* @param [elements] - Iterable (or iterable-like) of elements/records to insert.
|
|
3667
|
-
* @param [options] - Options such as bucketSize, toElementFn, and maxLen.
|
|
3668
|
-
* @returns New Deque instance.
|
|
3669
|
-
*/
|
|
3670
3719
|
constructor(elements = [], options) {
|
|
3671
3720
|
super(options);
|
|
3672
3721
|
__publicField(this, "_equals", (a, b) => Object.is(a, b));
|
|
3673
3722
|
__publicField(this, "_bucketSize", 1 << 12);
|
|
3723
|
+
__publicField(this, "_autoCompactRatio", 0.5);
|
|
3724
|
+
/**
|
|
3725
|
+
* Counter for shift/pop operations since last compaction check.
|
|
3726
|
+
* Only checks ratio every `_bucketSize` operations to minimize overhead.
|
|
3727
|
+
*/
|
|
3728
|
+
__publicField(this, "_compactCounter", 0);
|
|
3674
3729
|
__publicField(this, "_bucketFirst", 0);
|
|
3675
3730
|
__publicField(this, "_firstInBucket", 0);
|
|
3676
3731
|
__publicField(this, "_bucketLast", 0);
|
|
@@ -3679,8 +3734,9 @@ var dataStructureTyped = (() => {
|
|
|
3679
3734
|
__publicField(this, "_buckets", []);
|
|
3680
3735
|
__publicField(this, "_length", 0);
|
|
3681
3736
|
if (options) {
|
|
3682
|
-
const { bucketSize } = options;
|
|
3737
|
+
const { bucketSize, autoCompactRatio } = options;
|
|
3683
3738
|
if (typeof bucketSize === "number") this._bucketSize = bucketSize;
|
|
3739
|
+
if (typeof autoCompactRatio === "number") this._autoCompactRatio = autoCompactRatio;
|
|
3684
3740
|
}
|
|
3685
3741
|
let _size;
|
|
3686
3742
|
if ("length" in elements) {
|
|
@@ -3705,6 +3761,24 @@ var dataStructureTyped = (() => {
|
|
|
3705
3761
|
get bucketSize() {
|
|
3706
3762
|
return this._bucketSize;
|
|
3707
3763
|
}
|
|
3764
|
+
/**
|
|
3765
|
+
* Get the auto-compaction ratio.
|
|
3766
|
+
* When `elements / (bucketCount * bucketSize)` drops below this ratio after
|
|
3767
|
+
* enough shift/pop operations, the deque auto-compacts.
|
|
3768
|
+
* @remarks Time O(1), Space O(1)
|
|
3769
|
+
* @returns Current ratio threshold. 0 means auto-compact is disabled.
|
|
3770
|
+
*/
|
|
3771
|
+
get autoCompactRatio() {
|
|
3772
|
+
return this._autoCompactRatio;
|
|
3773
|
+
}
|
|
3774
|
+
/**
|
|
3775
|
+
* Set the auto-compaction ratio.
|
|
3776
|
+
* @remarks Time O(1), Space O(1)
|
|
3777
|
+
* @param value - Ratio in [0,1]. 0 disables auto-compact.
|
|
3778
|
+
*/
|
|
3779
|
+
set autoCompactRatio(value) {
|
|
3780
|
+
this._autoCompactRatio = value;
|
|
3781
|
+
}
|
|
3708
3782
|
/**
|
|
3709
3783
|
* Get the index of the first bucket in use.
|
|
3710
3784
|
* @remarks Time O(1), Space O(1)
|
|
@@ -3836,6 +3910,7 @@ var dataStructureTyped = (() => {
|
|
|
3836
3910
|
}
|
|
3837
3911
|
}
|
|
3838
3912
|
this._length -= 1;
|
|
3913
|
+
this._autoCompact();
|
|
3839
3914
|
return element;
|
|
3840
3915
|
}
|
|
3841
3916
|
/**
|
|
@@ -3858,6 +3933,7 @@ var dataStructureTyped = (() => {
|
|
|
3858
3933
|
}
|
|
3859
3934
|
}
|
|
3860
3935
|
this._length -= 1;
|
|
3936
|
+
this._autoCompact();
|
|
3861
3937
|
return element;
|
|
3862
3938
|
}
|
|
3863
3939
|
/**
|
|
@@ -4190,11 +4266,40 @@ var dataStructureTyped = (() => {
|
|
|
4190
4266
|
* @remarks Time O(N), Space O(1)
|
|
4191
4267
|
* @returns void
|
|
4192
4268
|
*/
|
|
4269
|
+
/**
|
|
4270
|
+
* (Protected) Trigger auto-compaction if space utilization drops below threshold.
|
|
4271
|
+
* Only checks every `_bucketSize` operations to minimize hot-path overhead.
|
|
4272
|
+
* Uses element-based ratio: `elements / (bucketCount * bucketSize)`.
|
|
4273
|
+
*/
|
|
4274
|
+
_autoCompact() {
|
|
4275
|
+
if (this._autoCompactRatio <= 0 || this._bucketCount <= 1) return;
|
|
4276
|
+
this._compactCounter++;
|
|
4277
|
+
if (this._compactCounter < this._bucketSize) return;
|
|
4278
|
+
this._compactCounter = 0;
|
|
4279
|
+
const utilization = this._length / (this._bucketCount * this._bucketSize);
|
|
4280
|
+
if (utilization < this._autoCompactRatio) {
|
|
4281
|
+
this.shrinkToFit();
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
/**
|
|
4285
|
+
* Compact the deque by removing unused buckets.
|
|
4286
|
+
* @remarks Time O(N), Space O(1)
|
|
4287
|
+
* @returns True if compaction was performed (bucket count reduced).
|
|
4288
|
+
*/
|
|
4289
|
+
/**
|
|
4290
|
+
* Compact the deque by removing unused buckets.
|
|
4291
|
+
* @remarks Time O(N), Space O(1)
|
|
4292
|
+
* @returns True if compaction was performed (bucket count reduced).
|
|
4293
|
+
*/
|
|
4294
|
+
compact() {
|
|
4295
|
+
const before = this._bucketCount;
|
|
4296
|
+
this.shrinkToFit();
|
|
4297
|
+
return this._bucketCount < before;
|
|
4298
|
+
}
|
|
4193
4299
|
shrinkToFit() {
|
|
4194
4300
|
if (this._length === 0) return;
|
|
4195
4301
|
const newBuckets = [];
|
|
4196
|
-
if (this._bucketFirst
|
|
4197
|
-
else if (this._bucketFirst < this._bucketLast) {
|
|
4302
|
+
if (this._bucketFirst <= this._bucketLast) {
|
|
4198
4303
|
for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {
|
|
4199
4304
|
newBuckets.push(this._buckets[i]);
|
|
4200
4305
|
}
|
|
@@ -4209,6 +4314,8 @@ var dataStructureTyped = (() => {
|
|
|
4209
4314
|
this._bucketFirst = 0;
|
|
4210
4315
|
this._bucketLast = newBuckets.length - 1;
|
|
4211
4316
|
this._buckets = newBuckets;
|
|
4317
|
+
this._bucketCount = newBuckets.length;
|
|
4318
|
+
this._compactCounter = 0;
|
|
4212
4319
|
}
|
|
4213
4320
|
/**
|
|
4214
4321
|
* Deep clone this deque, preserving options.
|
|
@@ -4404,7 +4511,7 @@ var dataStructureTyped = (() => {
|
|
|
4404
4511
|
__publicField(this, "_elements", []);
|
|
4405
4512
|
__publicField(this, "_DEFAULT_COMPARATOR", (a, b) => {
|
|
4406
4513
|
if (typeof a === "object" || typeof b === "object") {
|
|
4407
|
-
throw TypeError(
|
|
4514
|
+
throw new TypeError(ERR.comparatorRequired("Heap"));
|
|
4408
4515
|
}
|
|
4409
4516
|
if (a > b) return 1;
|
|
4410
4517
|
if (a < b) return -1;
|
|
@@ -4714,7 +4821,7 @@ var dataStructureTyped = (() => {
|
|
|
4714
4821
|
*/
|
|
4715
4822
|
map(callback, options, thisArg) {
|
|
4716
4823
|
const { comparator, toElementFn, ...rest } = options != null ? options : {};
|
|
4717
|
-
if (!comparator) throw new TypeError("Heap.map
|
|
4824
|
+
if (!comparator) throw new TypeError(ERR.comparatorRequired("Heap.map"));
|
|
4718
4825
|
const out = this._createLike([], { ...rest, comparator, toElementFn });
|
|
4719
4826
|
let i = 0;
|
|
4720
4827
|
for (const x of this) {
|
|
@@ -4842,7 +4949,7 @@ var dataStructureTyped = (() => {
|
|
|
4842
4949
|
__publicField(this, "_comparator");
|
|
4843
4950
|
this.clear();
|
|
4844
4951
|
this._comparator = comparator || this._defaultComparator;
|
|
4845
|
-
if (typeof this.comparator !== "function") throw new
|
|
4952
|
+
if (typeof this.comparator !== "function") throw new TypeError(ERR.notAFunction("comparator", "FibonacciHeap"));
|
|
4846
4953
|
}
|
|
4847
4954
|
/**
|
|
4848
4955
|
* Get the circular root list head.
|
|
@@ -5051,9 +5158,7 @@ var dataStructureTyped = (() => {
|
|
|
5051
5158
|
super(elements, {
|
|
5052
5159
|
comparator: (a, b) => {
|
|
5053
5160
|
if (typeof a === "object" || typeof b === "object") {
|
|
5054
|
-
throw TypeError(
|
|
5055
|
-
`When comparing object types, a custom comparator must be defined in the constructor's options parameter.`
|
|
5056
|
-
);
|
|
5161
|
+
throw new TypeError(ERR.comparatorRequired("MaxHeap"));
|
|
5057
5162
|
}
|
|
5058
5163
|
if (a < b) return 1;
|
|
5059
5164
|
if (a > b) return -1;
|
|
@@ -5210,7 +5315,7 @@ var dataStructureTyped = (() => {
|
|
|
5210
5315
|
const newEdge = this.createEdge(srcOrEdge, dest, weight, value);
|
|
5211
5316
|
return this._addEdge(newEdge);
|
|
5212
5317
|
} else {
|
|
5213
|
-
throw new
|
|
5318
|
+
throw new TypeError(ERR.invalidArgument("dest must be a Vertex or vertex key when srcOrEdge is an Edge.", "Graph"));
|
|
5214
5319
|
}
|
|
5215
5320
|
}
|
|
5216
5321
|
}
|
|
@@ -5894,6 +5999,94 @@ var dataStructureTyped = (() => {
|
|
|
5894
5999
|
_getVertexKey(vertexOrKey) {
|
|
5895
6000
|
return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
|
|
5896
6001
|
}
|
|
6002
|
+
/**
|
|
6003
|
+
* The edge connector string used in visual output.
|
|
6004
|
+
* Override in subclasses (e.g., '--' for undirected, '->' for directed).
|
|
6005
|
+
*/
|
|
6006
|
+
get _edgeConnector() {
|
|
6007
|
+
return "--";
|
|
6008
|
+
}
|
|
6009
|
+
/**
|
|
6010
|
+
* Generate a text-based visual representation of the graph.
|
|
6011
|
+
*
|
|
6012
|
+
* **Adjacency list format:**
|
|
6013
|
+
* ```
|
|
6014
|
+
* Graph (5 vertices, 6 edges):
|
|
6015
|
+
* A -> B (1), C (2)
|
|
6016
|
+
* B -> D (3)
|
|
6017
|
+
* C -> (no outgoing edges)
|
|
6018
|
+
* D -> A (1)
|
|
6019
|
+
* E (isolated)
|
|
6020
|
+
* ```
|
|
6021
|
+
*
|
|
6022
|
+
* @param options - Optional display settings.
|
|
6023
|
+
* @param options.showWeight - Whether to show edge weights (default: true).
|
|
6024
|
+
* @returns The visual string.
|
|
6025
|
+
*/
|
|
6026
|
+
toVisual(options) {
|
|
6027
|
+
var _a;
|
|
6028
|
+
const showWeight = (_a = options == null ? void 0 : options.showWeight) != null ? _a : true;
|
|
6029
|
+
const vertices = [...this._vertexMap.values()];
|
|
6030
|
+
const vertexCount = vertices.length;
|
|
6031
|
+
const edgeCount = this.edgeSet().length;
|
|
6032
|
+
const lines = [`Graph (${vertexCount} vertices, ${edgeCount} edges):`];
|
|
6033
|
+
for (const vertex of vertices) {
|
|
6034
|
+
const neighbors = this.getNeighbors(vertex);
|
|
6035
|
+
if (neighbors.length === 0) {
|
|
6036
|
+
lines.push(` ${vertex.key} (isolated)`);
|
|
6037
|
+
} else {
|
|
6038
|
+
const edgeStrs = neighbors.map((neighbor) => {
|
|
6039
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
6040
|
+
if (edge && showWeight && edge.weight !== void 0 && edge.weight !== 1) {
|
|
6041
|
+
return `${neighbor.key} (${edge.weight})`;
|
|
6042
|
+
}
|
|
6043
|
+
return `${neighbor.key}`;
|
|
6044
|
+
});
|
|
6045
|
+
lines.push(` ${vertex.key} ${this._edgeConnector} ${edgeStrs.join(", ")}`);
|
|
6046
|
+
}
|
|
6047
|
+
}
|
|
6048
|
+
return lines.join("\n");
|
|
6049
|
+
}
|
|
6050
|
+
/**
|
|
6051
|
+
* Generate DOT language representation for Graphviz.
|
|
6052
|
+
*
|
|
6053
|
+
* @param options - Optional display settings.
|
|
6054
|
+
* @param options.name - Graph name (default: 'G').
|
|
6055
|
+
* @param options.showWeight - Whether to label edges with weight (default: true).
|
|
6056
|
+
* @returns DOT format string.
|
|
6057
|
+
*/
|
|
6058
|
+
toDot(options) {
|
|
6059
|
+
var _a, _b;
|
|
6060
|
+
const name = (_a = options == null ? void 0 : options.name) != null ? _a : "G";
|
|
6061
|
+
const showWeight = (_b = options == null ? void 0 : options.showWeight) != null ? _b : true;
|
|
6062
|
+
const isDirected = this._edgeConnector === "->";
|
|
6063
|
+
const graphType = isDirected ? "digraph" : "graph";
|
|
6064
|
+
const edgeOp = isDirected ? "->" : "--";
|
|
6065
|
+
const lines = [`${graphType} ${name} {`];
|
|
6066
|
+
for (const vertex of this._vertexMap.values()) {
|
|
6067
|
+
lines.push(` "${vertex.key}";`);
|
|
6068
|
+
}
|
|
6069
|
+
const visited = /* @__PURE__ */ new Set();
|
|
6070
|
+
for (const vertex of this._vertexMap.values()) {
|
|
6071
|
+
for (const neighbor of this.getNeighbors(vertex)) {
|
|
6072
|
+
const edgeId = isDirected ? `${vertex.key}->${neighbor.key}` : [vertex.key, neighbor.key].sort().join("--");
|
|
6073
|
+
if (visited.has(edgeId)) continue;
|
|
6074
|
+
visited.add(edgeId);
|
|
6075
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
6076
|
+
const label = edge && showWeight && edge.weight !== void 0 && edge.weight !== 1 ? ` [label="${edge.weight}"]` : "";
|
|
6077
|
+
lines.push(` "${vertex.key}" ${edgeOp} "${neighbor.key}"${label};`);
|
|
6078
|
+
}
|
|
6079
|
+
}
|
|
6080
|
+
lines.push("}");
|
|
6081
|
+
return lines.join("\n");
|
|
6082
|
+
}
|
|
6083
|
+
/**
|
|
6084
|
+
* Print the graph to console.
|
|
6085
|
+
* @param options - Display settings passed to `toVisual`.
|
|
6086
|
+
*/
|
|
6087
|
+
print(options) {
|
|
6088
|
+
console.log(this.toVisual(options));
|
|
6089
|
+
}
|
|
5897
6090
|
};
|
|
5898
6091
|
|
|
5899
6092
|
// src/data-structures/graph/directed-graph.ts
|
|
@@ -5922,6 +6115,9 @@ var dataStructureTyped = (() => {
|
|
|
5922
6115
|
__publicField(this, "_outEdgeMap", /* @__PURE__ */ new Map());
|
|
5923
6116
|
__publicField(this, "_inEdgeMap", /* @__PURE__ */ new Map());
|
|
5924
6117
|
}
|
|
6118
|
+
get _edgeConnector() {
|
|
6119
|
+
return "->";
|
|
6120
|
+
}
|
|
5925
6121
|
get outEdgeMap() {
|
|
5926
6122
|
return this._outEdgeMap;
|
|
5927
6123
|
}
|
|
@@ -6696,6 +6892,84 @@ var dataStructureTyped = (() => {
|
|
|
6696
6892
|
cutVertices
|
|
6697
6893
|
};
|
|
6698
6894
|
}
|
|
6895
|
+
/**
|
|
6896
|
+
* Find biconnected components using edge-stack Tarjan variant.
|
|
6897
|
+
* A biconnected component is a maximal biconnected subgraph.
|
|
6898
|
+
* @returns Array of edge arrays, each representing a biconnected component.
|
|
6899
|
+
* @remarks Time O(V + E), Space O(V + E)
|
|
6900
|
+
*/
|
|
6901
|
+
getBiconnectedComponents() {
|
|
6902
|
+
const dfn = /* @__PURE__ */ new Map();
|
|
6903
|
+
const low = /* @__PURE__ */ new Map();
|
|
6904
|
+
const edgeStack = [];
|
|
6905
|
+
const components = [];
|
|
6906
|
+
let time = 0;
|
|
6907
|
+
const dfs = (vertex, parent) => {
|
|
6908
|
+
dfn.set(vertex, time);
|
|
6909
|
+
low.set(vertex, time);
|
|
6910
|
+
time++;
|
|
6911
|
+
const neighbors = this.getNeighbors(vertex);
|
|
6912
|
+
let childCount = 0;
|
|
6913
|
+
for (const neighbor of neighbors) {
|
|
6914
|
+
const edge = this.getEdge(vertex, neighbor);
|
|
6915
|
+
if (!edge) continue;
|
|
6916
|
+
if (!dfn.has(neighbor)) {
|
|
6917
|
+
childCount++;
|
|
6918
|
+
edgeStack.push(edge);
|
|
6919
|
+
dfs(neighbor, vertex);
|
|
6920
|
+
low.set(vertex, Math.min(low.get(vertex), low.get(neighbor)));
|
|
6921
|
+
if (parent === void 0 && childCount > 1 || parent !== void 0 && low.get(neighbor) >= dfn.get(vertex)) {
|
|
6922
|
+
const component = [];
|
|
6923
|
+
let e;
|
|
6924
|
+
do {
|
|
6925
|
+
e = edgeStack.pop();
|
|
6926
|
+
if (e) component.push(e);
|
|
6927
|
+
} while (e && e !== edge);
|
|
6928
|
+
if (component.length > 0) components.push(component);
|
|
6929
|
+
}
|
|
6930
|
+
} else if (neighbor !== parent && dfn.get(neighbor) < dfn.get(vertex)) {
|
|
6931
|
+
edgeStack.push(edge);
|
|
6932
|
+
low.set(vertex, Math.min(low.get(vertex), dfn.get(neighbor)));
|
|
6933
|
+
}
|
|
6934
|
+
}
|
|
6935
|
+
};
|
|
6936
|
+
for (const vertex of this.vertexMap.values()) {
|
|
6937
|
+
if (!dfn.has(vertex)) {
|
|
6938
|
+
dfs(vertex, void 0);
|
|
6939
|
+
if (edgeStack.length > 0) {
|
|
6940
|
+
components.push([...edgeStack]);
|
|
6941
|
+
edgeStack.length = 0;
|
|
6942
|
+
}
|
|
6943
|
+
}
|
|
6944
|
+
}
|
|
6945
|
+
return components;
|
|
6946
|
+
}
|
|
6947
|
+
/**
|
|
6948
|
+
* Detect whether the graph contains a cycle.
|
|
6949
|
+
* Uses DFS with parent tracking.
|
|
6950
|
+
* @returns `true` if a cycle exists, `false` otherwise.
|
|
6951
|
+
* @remarks Time O(V + E), Space O(V)
|
|
6952
|
+
*/
|
|
6953
|
+
hasCycle() {
|
|
6954
|
+
const visited = /* @__PURE__ */ new Set();
|
|
6955
|
+
const dfs = (vertex, parent) => {
|
|
6956
|
+
visited.add(vertex);
|
|
6957
|
+
for (const neighbor of this.getNeighbors(vertex)) {
|
|
6958
|
+
if (!visited.has(neighbor)) {
|
|
6959
|
+
if (dfs(neighbor, vertex)) return true;
|
|
6960
|
+
} else if (neighbor !== parent) {
|
|
6961
|
+
return true;
|
|
6962
|
+
}
|
|
6963
|
+
}
|
|
6964
|
+
return false;
|
|
6965
|
+
};
|
|
6966
|
+
for (const vertex of this.vertexMap.values()) {
|
|
6967
|
+
if (!visited.has(vertex)) {
|
|
6968
|
+
if (dfs(vertex, void 0)) return true;
|
|
6969
|
+
}
|
|
6970
|
+
}
|
|
6971
|
+
return false;
|
|
6972
|
+
}
|
|
6699
6973
|
/**
|
|
6700
6974
|
* Get bridges discovered by `tarjan()`.
|
|
6701
6975
|
* @returns Array of edges that are bridges.
|
|
@@ -6840,27 +7114,6 @@ var dataStructureTyped = (() => {
|
|
|
6840
7114
|
}
|
|
6841
7115
|
};
|
|
6842
7116
|
|
|
6843
|
-
// src/common/index.ts
|
|
6844
|
-
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
6845
|
-
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
6846
|
-
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
6847
|
-
return DFSOperation2;
|
|
6848
|
-
})(DFSOperation || {});
|
|
6849
|
-
var Range = class {
|
|
6850
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
6851
|
-
this.low = low;
|
|
6852
|
-
this.high = high;
|
|
6853
|
-
this.includeLow = includeLow;
|
|
6854
|
-
this.includeHigh = includeHigh;
|
|
6855
|
-
}
|
|
6856
|
-
// Determine whether a key is within the range
|
|
6857
|
-
isInRange(key, comparator) {
|
|
6858
|
-
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
6859
|
-
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
6860
|
-
return lowCheck && highCheck;
|
|
6861
|
-
}
|
|
6862
|
-
};
|
|
6863
|
-
|
|
6864
7117
|
// src/data-structures/binary-tree/binary-tree.ts
|
|
6865
7118
|
var BinaryTreeNode = class {
|
|
6866
7119
|
/**
|
|
@@ -6996,7 +7249,7 @@ var dataStructureTyped = (() => {
|
|
|
6996
7249
|
return "MAL_NODE";
|
|
6997
7250
|
}
|
|
6998
7251
|
};
|
|
6999
|
-
var BinaryTree = class extends IterableEntryBase {
|
|
7252
|
+
var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
7000
7253
|
/**
|
|
7001
7254
|
* Creates an instance of BinaryTree.
|
|
7002
7255
|
* @remarks Time O(N * M), where N is the number of items in `keysNodesEntriesOrRaws` and M is the tree size at insertion time (due to O(M) `set` operation). Space O(N) for storing the nodes.
|
|
@@ -7031,7 +7284,7 @@ var dataStructureTyped = (() => {
|
|
|
7031
7284
|
if (isMapMode !== void 0) this._isMapMode = isMapMode;
|
|
7032
7285
|
if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
|
|
7033
7286
|
if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
|
|
7034
|
-
else if (toEntryFn) throw TypeError("toEntryFn
|
|
7287
|
+
else if (toEntryFn) throw new TypeError(ERR.notAFunction("toEntryFn", "BinaryTree"));
|
|
7035
7288
|
}
|
|
7036
7289
|
if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
|
|
7037
7290
|
}
|
|
@@ -7259,7 +7512,7 @@ var dataStructureTyped = (() => {
|
|
|
7259
7512
|
if (!this._root) {
|
|
7260
7513
|
this._setRoot(newNode);
|
|
7261
7514
|
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
7262
|
-
this._size = 1;
|
|
7515
|
+
if (newNode !== null) this._size = 1;
|
|
7263
7516
|
return true;
|
|
7264
7517
|
}
|
|
7265
7518
|
const queue = new Queue([this._root]);
|
|
@@ -7291,7 +7544,7 @@ var dataStructureTyped = (() => {
|
|
|
7291
7544
|
potentialParent.right = newNode;
|
|
7292
7545
|
}
|
|
7293
7546
|
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
7294
|
-
this._size++;
|
|
7547
|
+
if (newNode !== null) this._size++;
|
|
7295
7548
|
return true;
|
|
7296
7549
|
}
|
|
7297
7550
|
return false;
|
|
@@ -7860,7 +8113,7 @@ var dataStructureTyped = (() => {
|
|
|
7860
8113
|
}
|
|
7861
8114
|
/**
|
|
7862
8115
|
* Finds all leaf nodes in the tree.
|
|
7863
|
-
* @remarks Time O(N), visits every node. Space O(H) for recursive
|
|
8116
|
+
* @remarks Time O(N), visits every node. Space O(H) for recursive or iterative stack.
|
|
7864
8117
|
*
|
|
7865
8118
|
* @template C - The type of the callback function.
|
|
7866
8119
|
* @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
|
|
@@ -7883,15 +8136,15 @@ var dataStructureTyped = (() => {
|
|
|
7883
8136
|
};
|
|
7884
8137
|
dfs(startNode);
|
|
7885
8138
|
} else {
|
|
7886
|
-
const
|
|
7887
|
-
while (
|
|
7888
|
-
const cur =
|
|
8139
|
+
const stack = [startNode];
|
|
8140
|
+
while (stack.length > 0) {
|
|
8141
|
+
const cur = stack.pop();
|
|
7889
8142
|
if (this.isRealNode(cur)) {
|
|
7890
8143
|
if (this.isLeaf(cur)) {
|
|
7891
8144
|
leaves.push(callback(cur));
|
|
7892
8145
|
}
|
|
7893
|
-
if (this.isRealNode(cur.
|
|
7894
|
-
if (this.isRealNode(cur.
|
|
8146
|
+
if (this.isRealNode(cur.right)) stack.push(cur.right);
|
|
8147
|
+
if (this.isRealNode(cur.left)) stack.push(cur.left);
|
|
7895
8148
|
}
|
|
7896
8149
|
}
|
|
7897
8150
|
}
|
|
@@ -8347,42 +8600,98 @@ var dataStructureTyped = (() => {
|
|
|
8347
8600
|
_displayAux(node, options) {
|
|
8348
8601
|
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
8349
8602
|
const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
|
|
8350
|
-
|
|
8351
|
-
|
|
8352
|
-
|
|
8353
|
-
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
const
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8603
|
+
const newFrame = (n) => ({
|
|
8604
|
+
node: n,
|
|
8605
|
+
stage: 0,
|
|
8606
|
+
leftLayout: emptyDisplayLayout,
|
|
8607
|
+
rightLayout: emptyDisplayLayout
|
|
8608
|
+
});
|
|
8609
|
+
const stack = [newFrame(node)];
|
|
8610
|
+
let result = emptyDisplayLayout;
|
|
8611
|
+
const setChildResult = (layout) => {
|
|
8612
|
+
if (stack.length === 0) {
|
|
8613
|
+
result = layout;
|
|
8614
|
+
return;
|
|
8615
|
+
}
|
|
8616
|
+
const parent = stack[stack.length - 1];
|
|
8617
|
+
if (parent.stage === 1) parent.leftLayout = layout;
|
|
8618
|
+
else parent.rightLayout = layout;
|
|
8619
|
+
};
|
|
8620
|
+
while (stack.length > 0) {
|
|
8621
|
+
const frame = stack[stack.length - 1];
|
|
8622
|
+
const cur = frame.node;
|
|
8623
|
+
if (frame.stage === 0) {
|
|
8624
|
+
if (this._isDisplayLeaf(cur, options)) {
|
|
8625
|
+
stack.pop();
|
|
8626
|
+
const layout = this._resolveDisplayLeaf(cur, options, emptyDisplayLayout);
|
|
8627
|
+
setChildResult(layout);
|
|
8628
|
+
continue;
|
|
8629
|
+
}
|
|
8630
|
+
frame.stage = 1;
|
|
8631
|
+
stack.push(newFrame(cur.left));
|
|
8632
|
+
} else if (frame.stage === 1) {
|
|
8633
|
+
frame.stage = 2;
|
|
8634
|
+
stack.push(newFrame(cur.right));
|
|
8635
|
+
} else {
|
|
8636
|
+
stack.pop();
|
|
8637
|
+
const line = this.isNIL(cur) ? "S" : String(cur.key);
|
|
8638
|
+
const layout = _BinaryTree._buildNodeDisplay(line, line.length, frame.leftLayout, frame.rightLayout);
|
|
8639
|
+
setChildResult(layout);
|
|
8378
8640
|
}
|
|
8379
|
-
return [
|
|
8380
|
-
mergedLines,
|
|
8381
|
-
leftWidth + width + rightWidth,
|
|
8382
|
-
Math.max(leftHeight, rightHeight) + 2,
|
|
8383
|
-
leftWidth + Math.floor(width / 2)
|
|
8384
|
-
];
|
|
8385
8641
|
}
|
|
8642
|
+
return result;
|
|
8643
|
+
}
|
|
8644
|
+
static _buildNodeDisplay(line, width, left, right) {
|
|
8645
|
+
const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
|
|
8646
|
+
const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
|
|
8647
|
+
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));
|
|
8648
|
+
const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
|
|
8649
|
+
const mergedLines = [firstLine, secondLine];
|
|
8650
|
+
for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
|
|
8651
|
+
const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
|
|
8652
|
+
const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
|
|
8653
|
+
mergedLines.push(leftLine + " ".repeat(width) + rightLine);
|
|
8654
|
+
}
|
|
8655
|
+
return [
|
|
8656
|
+
mergedLines,
|
|
8657
|
+
leftWidth + width + rightWidth,
|
|
8658
|
+
Math.max(leftHeight, rightHeight) + 2,
|
|
8659
|
+
leftWidth + Math.floor(width / 2)
|
|
8660
|
+
];
|
|
8661
|
+
}
|
|
8662
|
+
/**
|
|
8663
|
+
* Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
|
|
8664
|
+
*/
|
|
8665
|
+
_isDisplayLeaf(node, options) {
|
|
8666
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
8667
|
+
if (node === null && !isShowNull) return true;
|
|
8668
|
+
if (node === void 0 && !isShowUndefined) return true;
|
|
8669
|
+
if (this.isNIL(node) && !isShowRedBlackNIL) return true;
|
|
8670
|
+
if (node === null || node === void 0) return true;
|
|
8671
|
+
const hasDisplayableLeft = this._hasDisplayableChild(node.left, options);
|
|
8672
|
+
const hasDisplayableRight = this._hasDisplayableChild(node.right, options);
|
|
8673
|
+
return !hasDisplayableLeft && !hasDisplayableRight;
|
|
8674
|
+
}
|
|
8675
|
+
_hasDisplayableChild(child, options) {
|
|
8676
|
+
if (child === null) return !!options.isShowNull;
|
|
8677
|
+
if (child === void 0) return !!options.isShowUndefined;
|
|
8678
|
+
if (this.isNIL(child)) return !!options.isShowRedBlackNIL;
|
|
8679
|
+
return true;
|
|
8680
|
+
}
|
|
8681
|
+
/**
|
|
8682
|
+
* Resolve a display leaf node to its layout.
|
|
8683
|
+
*/
|
|
8684
|
+
_resolveDisplayLeaf(node, options, emptyDisplayLayout) {
|
|
8685
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
8686
|
+
if (node === null && !isShowNull) return emptyDisplayLayout;
|
|
8687
|
+
if (node === void 0 && !isShowUndefined) return emptyDisplayLayout;
|
|
8688
|
+
if (this.isNIL(node) && !isShowRedBlackNIL) return emptyDisplayLayout;
|
|
8689
|
+
if (node !== null && node !== void 0) {
|
|
8690
|
+
const line2 = this.isNIL(node) ? "S" : String(node.key);
|
|
8691
|
+
return _BinaryTree._buildNodeDisplay(line2, line2.length, emptyDisplayLayout, emptyDisplayLayout);
|
|
8692
|
+
}
|
|
8693
|
+
const line = node === void 0 ? "U" : "N";
|
|
8694
|
+
return _BinaryTree._buildNodeDisplay(line, line.length, [[""], 1, 0, 0], [[""], 1, 0, 0]);
|
|
8386
8695
|
}
|
|
8387
8696
|
/**
|
|
8388
8697
|
* (Protected) Swaps the key/value properties of two nodes.
|
|
@@ -9384,9 +9693,15 @@ var dataStructureTyped = (() => {
|
|
|
9384
9693
|
if (a < b) return -1;
|
|
9385
9694
|
return 0;
|
|
9386
9695
|
}
|
|
9696
|
+
if (a instanceof Date && b instanceof Date) {
|
|
9697
|
+
const ta = a.getTime();
|
|
9698
|
+
const tb = b.getTime();
|
|
9699
|
+
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("BST"));
|
|
9700
|
+
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
9701
|
+
}
|
|
9387
9702
|
if (typeof a === "object" || typeof b === "object") {
|
|
9388
|
-
throw TypeError(
|
|
9389
|
-
|
|
9703
|
+
throw new TypeError(
|
|
9704
|
+
ERR.comparatorRequired("BST")
|
|
9390
9705
|
);
|
|
9391
9706
|
}
|
|
9392
9707
|
return 0;
|
|
@@ -9898,7 +10213,7 @@ var dataStructureTyped = (() => {
|
|
|
9898
10213
|
*/
|
|
9899
10214
|
read(count) {
|
|
9900
10215
|
if (!Number.isInteger(count)) {
|
|
9901
|
-
throw new Error("
|
|
10216
|
+
throw new Error(ERR.invalidArgument("count must be an integer", "BinaryIndexedTree"));
|
|
9902
10217
|
}
|
|
9903
10218
|
return this._read(Math.max(Math.min(count, this.max), 0));
|
|
9904
10219
|
}
|
|
@@ -9910,7 +10225,7 @@ var dataStructureTyped = (() => {
|
|
|
9910
10225
|
*/
|
|
9911
10226
|
lowerBound(sum) {
|
|
9912
10227
|
if (this.negativeCount > 0) {
|
|
9913
|
-
throw new Error("Sequence is not non-descending");
|
|
10228
|
+
throw new Error(ERR.invalidOperation("Sequence is not non-descending.", "BinaryIndexedTree"));
|
|
9914
10229
|
}
|
|
9915
10230
|
return this._binarySearch(sum, (x, y) => x < y);
|
|
9916
10231
|
}
|
|
@@ -9923,7 +10238,7 @@ var dataStructureTyped = (() => {
|
|
|
9923
10238
|
*/
|
|
9924
10239
|
upperBound(sum) {
|
|
9925
10240
|
if (this.negativeCount > 0) {
|
|
9926
|
-
throw new Error("
|
|
10241
|
+
throw new Error(ERR.invalidOperation("Sequence must not be descending.", "BinaryIndexedTree"));
|
|
9927
10242
|
}
|
|
9928
10243
|
return this._binarySearch(sum, (x, y) => x <= y);
|
|
9929
10244
|
}
|
|
@@ -9974,10 +10289,10 @@ var dataStructureTyped = (() => {
|
|
|
9974
10289
|
*/
|
|
9975
10290
|
_checkIndex(index) {
|
|
9976
10291
|
if (!Number.isInteger(index)) {
|
|
9977
|
-
throw new
|
|
10292
|
+
throw new TypeError(ERR.invalidIndex("BinaryIndexedTree"));
|
|
9978
10293
|
}
|
|
9979
10294
|
if (index < 0 || index >= this.max) {
|
|
9980
|
-
throw new
|
|
10295
|
+
throw new RangeError(ERR.indexOutOfRange(index, 0, this.max - 1, "BinaryIndexedTree"));
|
|
9981
10296
|
}
|
|
9982
10297
|
}
|
|
9983
10298
|
/**
|
|
@@ -11554,6 +11869,24 @@ var dataStructureTyped = (() => {
|
|
|
11554
11869
|
* @param [thisArg] - See parameter type for details.
|
|
11555
11870
|
* @returns A new RedBlackTree with mapped entries.
|
|
11556
11871
|
*/
|
|
11872
|
+
/**
|
|
11873
|
+
* Red-Black trees are self-balancing — `perfectlyBalance` rebuilds via
|
|
11874
|
+
* sorted bulk insert, which naturally produces a balanced RBT.
|
|
11875
|
+
* @remarks Time O(N), Space O(N)
|
|
11876
|
+
*/
|
|
11877
|
+
perfectlyBalance(iterationType) {
|
|
11878
|
+
const entries = [];
|
|
11879
|
+
for (const [key, value] of this) entries.push([key, value]);
|
|
11880
|
+
if (entries.length <= 1) return true;
|
|
11881
|
+
this.clear();
|
|
11882
|
+
this.setMany(
|
|
11883
|
+
entries.map(([k]) => k),
|
|
11884
|
+
entries.map(([, v]) => v),
|
|
11885
|
+
true
|
|
11886
|
+
// isBalanceAdd
|
|
11887
|
+
);
|
|
11888
|
+
return true;
|
|
11889
|
+
}
|
|
11557
11890
|
map(callback, options, thisArg) {
|
|
11558
11891
|
const out = this._createLike([], options);
|
|
11559
11892
|
let index = 0;
|
|
@@ -11876,7 +12209,7 @@ var dataStructureTyped = (() => {
|
|
|
11876
12209
|
static createDefaultComparator() {
|
|
11877
12210
|
return (a, b) => {
|
|
11878
12211
|
if (typeof a === "number" && typeof b === "number") {
|
|
11879
|
-
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError("TreeSet
|
|
12212
|
+
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN("TreeSet"));
|
|
11880
12213
|
const aa = Object.is(a, -0) ? 0 : a;
|
|
11881
12214
|
const bb = Object.is(b, -0) ? 0 : b;
|
|
11882
12215
|
return aa > bb ? 1 : aa < bb ? -1 : 0;
|
|
@@ -11887,10 +12220,10 @@ var dataStructureTyped = (() => {
|
|
|
11887
12220
|
if (a instanceof Date && b instanceof Date) {
|
|
11888
12221
|
const ta = a.getTime();
|
|
11889
12222
|
const tb = b.getTime();
|
|
11890
|
-
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError("TreeSet
|
|
12223
|
+
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("TreeSet"));
|
|
11891
12224
|
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
11892
12225
|
}
|
|
11893
|
-
throw new TypeError("TreeSet
|
|
12226
|
+
throw new TypeError(ERR.comparatorRequired("TreeSet"));
|
|
11894
12227
|
};
|
|
11895
12228
|
}
|
|
11896
12229
|
/**
|
|
@@ -11908,15 +12241,15 @@ var dataStructureTyped = (() => {
|
|
|
11908
12241
|
_validateKey(key) {
|
|
11909
12242
|
if (!__privateGet(this, _isDefaultComparator)) return;
|
|
11910
12243
|
if (typeof key === "number") {
|
|
11911
|
-
if (Number.isNaN(key)) throw new TypeError("TreeSet
|
|
12244
|
+
if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeSet"));
|
|
11912
12245
|
return;
|
|
11913
12246
|
}
|
|
11914
12247
|
if (typeof key === "string") return;
|
|
11915
12248
|
if (key instanceof Date) {
|
|
11916
|
-
if (Number.isNaN(key.getTime())) throw new TypeError("TreeSet
|
|
12249
|
+
if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeSet"));
|
|
11917
12250
|
return;
|
|
11918
12251
|
}
|
|
11919
|
-
throw new TypeError("TreeSet
|
|
12252
|
+
throw new TypeError(ERR.comparatorRequired("TreeSet"));
|
|
11920
12253
|
}
|
|
11921
12254
|
/**
|
|
11922
12255
|
* Add a key to the set (no-op if already present).
|
|
@@ -12236,15 +12569,15 @@ var dataStructureTyped = (() => {
|
|
|
12236
12569
|
_validateKey(key) {
|
|
12237
12570
|
if (!__privateGet(this, _isDefaultComparator2)) return;
|
|
12238
12571
|
if (typeof key === "number") {
|
|
12239
|
-
if (Number.isNaN(key)) throw new TypeError("TreeMultiMap
|
|
12572
|
+
if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeMultiMap"));
|
|
12240
12573
|
return;
|
|
12241
12574
|
}
|
|
12242
12575
|
if (typeof key === "string") return;
|
|
12243
12576
|
if (key instanceof Date) {
|
|
12244
|
-
if (Number.isNaN(key.getTime())) throw new TypeError("TreeMultiMap
|
|
12577
|
+
if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeMultiMap"));
|
|
12245
12578
|
return;
|
|
12246
12579
|
}
|
|
12247
|
-
throw new TypeError("TreeMultiMap
|
|
12580
|
+
throw new TypeError(ERR.comparatorRequired("TreeMultiMap"));
|
|
12248
12581
|
}
|
|
12249
12582
|
/**
|
|
12250
12583
|
* Number of distinct keys.
|
|
@@ -12668,7 +13001,7 @@ var dataStructureTyped = (() => {
|
|
|
12668
13001
|
[k, v] = toEntryFn(item);
|
|
12669
13002
|
} else {
|
|
12670
13003
|
if (!Array.isArray(item) || item.length < 2) {
|
|
12671
|
-
throw new TypeError("TreeMap
|
|
13004
|
+
throw new TypeError(ERR.invalidEntry("TreeMap"));
|
|
12672
13005
|
}
|
|
12673
13006
|
k = item[0];
|
|
12674
13007
|
v = item[1];
|
|
@@ -12689,7 +13022,7 @@ var dataStructureTyped = (() => {
|
|
|
12689
13022
|
static createDefaultComparator() {
|
|
12690
13023
|
return (a, b) => {
|
|
12691
13024
|
if (typeof a === "number" && typeof b === "number") {
|
|
12692
|
-
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError("TreeMap
|
|
13025
|
+
if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN("TreeMap"));
|
|
12693
13026
|
const aa = Object.is(a, -0) ? 0 : a;
|
|
12694
13027
|
const bb = Object.is(b, -0) ? 0 : b;
|
|
12695
13028
|
return aa > bb ? 1 : aa < bb ? -1 : 0;
|
|
@@ -12700,24 +13033,24 @@ var dataStructureTyped = (() => {
|
|
|
12700
13033
|
if (a instanceof Date && b instanceof Date) {
|
|
12701
13034
|
const ta = a.getTime();
|
|
12702
13035
|
const tb = b.getTime();
|
|
12703
|
-
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError("TreeMap
|
|
13036
|
+
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("TreeMap"));
|
|
12704
13037
|
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
12705
13038
|
}
|
|
12706
|
-
throw new TypeError("TreeMap
|
|
13039
|
+
throw new TypeError(ERR.comparatorRequired("TreeMap"));
|
|
12707
13040
|
};
|
|
12708
13041
|
}
|
|
12709
13042
|
_validateKey(key) {
|
|
12710
13043
|
if (!__privateGet(this, _isDefaultComparator3)) return;
|
|
12711
13044
|
if (typeof key === "number") {
|
|
12712
|
-
if (Number.isNaN(key)) throw new TypeError("TreeMap
|
|
13045
|
+
if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeMap"));
|
|
12713
13046
|
return;
|
|
12714
13047
|
}
|
|
12715
13048
|
if (typeof key === "string") return;
|
|
12716
13049
|
if (key instanceof Date) {
|
|
12717
|
-
if (Number.isNaN(key.getTime())) throw new TypeError("TreeMap
|
|
13050
|
+
if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeMap"));
|
|
12718
13051
|
return;
|
|
12719
13052
|
}
|
|
12720
|
-
throw new TypeError("TreeMap
|
|
13053
|
+
throw new TypeError(ERR.comparatorRequired("TreeMap"));
|
|
12721
13054
|
}
|
|
12722
13055
|
/**
|
|
12723
13056
|
* Number of entries in the map.
|
|
@@ -13045,22 +13378,22 @@ var dataStructureTyped = (() => {
|
|
|
13045
13378
|
_validateKey(key) {
|
|
13046
13379
|
if (!__privateGet(this, _isDefaultComparator4)) return;
|
|
13047
13380
|
if (typeof key === "number") {
|
|
13048
|
-
if (Number.isNaN(key)) throw new TypeError("TreeMultiSet
|
|
13381
|
+
if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN("TreeMultiSet"));
|
|
13049
13382
|
return;
|
|
13050
13383
|
}
|
|
13051
13384
|
if (typeof key === "string") return;
|
|
13052
13385
|
if (key instanceof Date) {
|
|
13053
|
-
if (Number.isNaN(key.getTime())) throw new TypeError("TreeMultiSet
|
|
13386
|
+
if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate("TreeMultiSet"));
|
|
13054
13387
|
return;
|
|
13055
13388
|
}
|
|
13056
|
-
throw new TypeError("TreeMultiSet
|
|
13389
|
+
throw new TypeError(ERR.comparatorRequired("TreeMultiSet"));
|
|
13057
13390
|
}
|
|
13058
13391
|
/**
|
|
13059
13392
|
* Validates that count is a non-negative safe integer.
|
|
13060
13393
|
* @remarks Time O(1), Space O(1)
|
|
13061
13394
|
*/
|
|
13062
13395
|
_validateCount(n) {
|
|
13063
|
-
if (!Number.isSafeInteger(n) || n < 0) throw new RangeError("
|
|
13396
|
+
if (!Number.isSafeInteger(n) || n < 0) throw new RangeError(ERR.invalidArgument("count must be a safe integer >= 0.", "TreeMultiSet"));
|
|
13064
13397
|
}
|
|
13065
13398
|
/**
|
|
13066
13399
|
* Total occurrences (sumCounts).
|
|
@@ -13483,9 +13816,7 @@ var dataStructureTyped = (() => {
|
|
|
13483
13816
|
super(elements, {
|
|
13484
13817
|
comparator: (a, b) => {
|
|
13485
13818
|
if (typeof a === "object" || typeof b === "object") {
|
|
13486
|
-
throw TypeError(
|
|
13487
|
-
`When comparing object types, a custom comparator must be defined in the constructor's options parameter.`
|
|
13488
|
-
);
|
|
13819
|
+
throw new TypeError(ERR.comparatorRequired("MaxPriorityQueue"));
|
|
13489
13820
|
}
|
|
13490
13821
|
if (a < b) return 1;
|
|
13491
13822
|
if (a > b) return -1;
|
|
@@ -13624,7 +13955,7 @@ var dataStructureTyped = (() => {
|
|
|
13624
13955
|
*/
|
|
13625
13956
|
add(matrix) {
|
|
13626
13957
|
if (!this.isMatchForCalculate(matrix)) {
|
|
13627
|
-
throw new Error("
|
|
13958
|
+
throw new Error(ERR.matrixDimensionMismatch("addition"));
|
|
13628
13959
|
}
|
|
13629
13960
|
const resultData = [];
|
|
13630
13961
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -13656,7 +13987,7 @@ var dataStructureTyped = (() => {
|
|
|
13656
13987
|
*/
|
|
13657
13988
|
subtract(matrix) {
|
|
13658
13989
|
if (!this.isMatchForCalculate(matrix)) {
|
|
13659
|
-
throw new Error("
|
|
13990
|
+
throw new Error(ERR.matrixDimensionMismatch("subtraction"));
|
|
13660
13991
|
}
|
|
13661
13992
|
const resultData = [];
|
|
13662
13993
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -13687,7 +14018,7 @@ var dataStructureTyped = (() => {
|
|
|
13687
14018
|
*/
|
|
13688
14019
|
multiply(matrix) {
|
|
13689
14020
|
if (this.cols !== matrix.rows) {
|
|
13690
|
-
throw new Error("
|
|
14021
|
+
throw new Error(ERR.matrixDimensionMismatch("multiplication (A.cols must equal B.rows)"));
|
|
13691
14022
|
}
|
|
13692
14023
|
const resultData = [];
|
|
13693
14024
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -13721,7 +14052,7 @@ var dataStructureTyped = (() => {
|
|
|
13721
14052
|
*/
|
|
13722
14053
|
transpose() {
|
|
13723
14054
|
if (this.data.some((row) => row.length !== this.rows)) {
|
|
13724
|
-
throw new Error(
|
|
14055
|
+
throw new Error(ERR.matrixNotRectangular());
|
|
13725
14056
|
}
|
|
13726
14057
|
const resultData = [];
|
|
13727
14058
|
for (let j = 0; j < this.cols; j++) {
|
|
@@ -13746,7 +14077,7 @@ var dataStructureTyped = (() => {
|
|
|
13746
14077
|
inverse() {
|
|
13747
14078
|
var _a;
|
|
13748
14079
|
if (this.rows !== this.cols) {
|
|
13749
|
-
throw new Error(
|
|
14080
|
+
throw new Error(ERR.matrixNotSquare());
|
|
13750
14081
|
}
|
|
13751
14082
|
const augmentedMatrixData = [];
|
|
13752
14083
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -13768,12 +14099,12 @@ var dataStructureTyped = (() => {
|
|
|
13768
14099
|
pivotRow++;
|
|
13769
14100
|
}
|
|
13770
14101
|
if (pivotRow === this.rows) {
|
|
13771
|
-
throw new Error(
|
|
14102
|
+
throw new Error(ERR.matrixSingular());
|
|
13772
14103
|
}
|
|
13773
14104
|
augmentedMatrix._swapRows(i, pivotRow);
|
|
13774
14105
|
const pivotElement = (_a = augmentedMatrix.get(i, i)) != null ? _a : 1;
|
|
13775
14106
|
if (pivotElement === 0) {
|
|
13776
|
-
throw new Error(
|
|
14107
|
+
throw new Error(ERR.matrixSingular());
|
|
13777
14108
|
}
|
|
13778
14109
|
augmentedMatrix._scaleRow(i, 1 / pivotElement);
|
|
13779
14110
|
for (let j = 0; j < this.rows; j++) {
|
|
@@ -13803,9 +14134,7 @@ var dataStructureTyped = (() => {
|
|
|
13803
14134
|
*/
|
|
13804
14135
|
dot(matrix) {
|
|
13805
14136
|
if (this.cols !== matrix.rows) {
|
|
13806
|
-
throw new Error(
|
|
13807
|
-
"Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product."
|
|
13808
|
-
);
|
|
14137
|
+
throw new Error(ERR.matrixDimensionMismatch("dot product (A.cols must equal B.rows)"));
|
|
13809
14138
|
}
|
|
13810
14139
|
const resultData = [];
|
|
13811
14140
|
for (let i = 0; i < this.rows; i++) {
|
|
@@ -14419,7 +14748,7 @@ var dataStructureTyped = (() => {
|
|
|
14419
14748
|
for (const x of this) {
|
|
14420
14749
|
const v = thisArg === void 0 ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
|
|
14421
14750
|
if (typeof v !== "string") {
|
|
14422
|
-
throw new TypeError(
|
|
14751
|
+
throw new TypeError(ERR.callbackReturnType("string", typeof v, "Trie.map"));
|
|
14423
14752
|
}
|
|
14424
14753
|
newTrie.add(v);
|
|
14425
14754
|
}
|