binary-tree-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/dist/cjs/index.cjs +152 -70
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +150 -68
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +152 -71
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +150 -69
- package/dist/esm-legacy/index.mjs.map +1 -1
- 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/binary-tree-typed.js +149 -67
- package/dist/umd/binary-tree-typed.js.map +1 -1
- package/dist/umd/binary-tree-typed.min.js +3 -3
- package/dist/umd/binary-tree-typed.min.js.map +1 -1
- 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
|
@@ -59,6 +59,54 @@ function makeTrampoline(fn) {
|
|
|
59
59
|
}
|
|
60
60
|
__name(makeTrampoline, "makeTrampoline");
|
|
61
61
|
|
|
62
|
+
// src/common/error.ts
|
|
63
|
+
var ERR = {
|
|
64
|
+
// Range / index
|
|
65
|
+
indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
|
|
66
|
+
invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
|
|
67
|
+
// Type / argument
|
|
68
|
+
invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
|
|
69
|
+
comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
|
|
70
|
+
invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
|
|
71
|
+
notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
|
|
72
|
+
invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
|
|
73
|
+
invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
|
|
74
|
+
invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
|
|
75
|
+
reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
|
|
76
|
+
callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
|
|
77
|
+
// State / operation
|
|
78
|
+
invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
|
|
79
|
+
// Matrix
|
|
80
|
+
matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
|
|
81
|
+
matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
|
|
82
|
+
matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
|
|
83
|
+
matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
|
|
84
|
+
matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// src/common/index.ts
|
|
88
|
+
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
89
|
+
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
90
|
+
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
91
|
+
return DFSOperation2;
|
|
92
|
+
})(DFSOperation || {});
|
|
93
|
+
var _Range = class _Range {
|
|
94
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
95
|
+
this.low = low;
|
|
96
|
+
this.high = high;
|
|
97
|
+
this.includeLow = includeLow;
|
|
98
|
+
this.includeHigh = includeHigh;
|
|
99
|
+
}
|
|
100
|
+
// Determine whether a key is within the range
|
|
101
|
+
isInRange(key, comparator) {
|
|
102
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
103
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
104
|
+
return lowCheck && highCheck;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
__name(_Range, "Range");
|
|
108
|
+
var Range = _Range;
|
|
109
|
+
|
|
62
110
|
// src/data-structures/base/iterable-element-base.ts
|
|
63
111
|
var _IterableElementBase = class _IterableElementBase {
|
|
64
112
|
/**
|
|
@@ -81,7 +129,7 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
81
129
|
if (options) {
|
|
82
130
|
const { toElementFn } = options;
|
|
83
131
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
84
|
-
else if (toElementFn) throw new TypeError("toElementFn
|
|
132
|
+
else if (toElementFn) throw new TypeError(ERR.notAFunction("toElementFn"));
|
|
85
133
|
}
|
|
86
134
|
}
|
|
87
135
|
/**
|
|
@@ -237,7 +285,7 @@ var _IterableElementBase = class _IterableElementBase {
|
|
|
237
285
|
acc = initialValue;
|
|
238
286
|
} else {
|
|
239
287
|
const first = iter.next();
|
|
240
|
-
if (first.done) throw new TypeError(
|
|
288
|
+
if (first.done) throw new TypeError(ERR.reduceEmpty());
|
|
241
289
|
acc = first.value;
|
|
242
290
|
index = 1;
|
|
243
291
|
}
|
|
@@ -1023,29 +1071,6 @@ var _IterableEntryBase = class _IterableEntryBase {
|
|
|
1023
1071
|
__name(_IterableEntryBase, "IterableEntryBase");
|
|
1024
1072
|
var IterableEntryBase = _IterableEntryBase;
|
|
1025
1073
|
|
|
1026
|
-
// src/common/index.ts
|
|
1027
|
-
var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
|
|
1028
|
-
DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
|
|
1029
|
-
DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
|
|
1030
|
-
return DFSOperation2;
|
|
1031
|
-
})(DFSOperation || {});
|
|
1032
|
-
var _Range = class _Range {
|
|
1033
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
1034
|
-
this.low = low;
|
|
1035
|
-
this.high = high;
|
|
1036
|
-
this.includeLow = includeLow;
|
|
1037
|
-
this.includeHigh = includeHigh;
|
|
1038
|
-
}
|
|
1039
|
-
// Determine whether a key is within the range
|
|
1040
|
-
isInRange(key, comparator) {
|
|
1041
|
-
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
1042
|
-
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
1043
|
-
return lowCheck && highCheck;
|
|
1044
|
-
}
|
|
1045
|
-
};
|
|
1046
|
-
__name(_Range, "Range");
|
|
1047
|
-
var Range = _Range;
|
|
1048
|
-
|
|
1049
1074
|
// src/data-structures/binary-tree/binary-tree.ts
|
|
1050
1075
|
var _BinaryTreeNode = class _BinaryTreeNode {
|
|
1051
1076
|
/**
|
|
@@ -1218,7 +1243,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1218
1243
|
if (isMapMode !== void 0) this._isMapMode = isMapMode;
|
|
1219
1244
|
if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
|
|
1220
1245
|
if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
|
|
1221
|
-
else if (toEntryFn) throw TypeError("toEntryFn
|
|
1246
|
+
else if (toEntryFn) throw new TypeError(ERR.notAFunction("toEntryFn", "BinaryTree"));
|
|
1222
1247
|
}
|
|
1223
1248
|
if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
|
|
1224
1249
|
}
|
|
@@ -1446,7 +1471,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1446
1471
|
if (!this._root) {
|
|
1447
1472
|
this._setRoot(newNode);
|
|
1448
1473
|
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
1449
|
-
this._size = 1;
|
|
1474
|
+
if (newNode !== null) this._size = 1;
|
|
1450
1475
|
return true;
|
|
1451
1476
|
}
|
|
1452
1477
|
const queue = new Queue([this._root]);
|
|
@@ -1478,7 +1503,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
1478
1503
|
potentialParent.right = newNode;
|
|
1479
1504
|
}
|
|
1480
1505
|
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
1481
|
-
this._size++;
|
|
1506
|
+
if (newNode !== null) this._size++;
|
|
1482
1507
|
return true;
|
|
1483
1508
|
}
|
|
1484
1509
|
return false;
|
|
@@ -2047,7 +2072,7 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
2047
2072
|
}
|
|
2048
2073
|
/**
|
|
2049
2074
|
* Finds all leaf nodes in the tree.
|
|
2050
|
-
* @remarks Time O(N), visits every node. Space O(H) for recursive
|
|
2075
|
+
* @remarks Time O(N), visits every node. Space O(H) for recursive or iterative stack.
|
|
2051
2076
|
*
|
|
2052
2077
|
* @template C - The type of the callback function.
|
|
2053
2078
|
* @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
|
|
@@ -2070,15 +2095,15 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
2070
2095
|
}, "dfs");
|
|
2071
2096
|
dfs(startNode);
|
|
2072
2097
|
} else {
|
|
2073
|
-
const
|
|
2074
|
-
while (
|
|
2075
|
-
const cur =
|
|
2098
|
+
const stack = [startNode];
|
|
2099
|
+
while (stack.length > 0) {
|
|
2100
|
+
const cur = stack.pop();
|
|
2076
2101
|
if (this.isRealNode(cur)) {
|
|
2077
2102
|
if (this.isLeaf(cur)) {
|
|
2078
2103
|
leaves.push(callback(cur));
|
|
2079
2104
|
}
|
|
2080
|
-
if (this.isRealNode(cur.
|
|
2081
|
-
if (this.isRealNode(cur.
|
|
2105
|
+
if (this.isRealNode(cur.right)) stack.push(cur.right);
|
|
2106
|
+
if (this.isRealNode(cur.left)) stack.push(cur.left);
|
|
2082
2107
|
}
|
|
2083
2108
|
}
|
|
2084
2109
|
}
|
|
@@ -2534,42 +2559,98 @@ var _BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
|
2534
2559
|
_displayAux(node, options) {
|
|
2535
2560
|
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
2536
2561
|
const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
const
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2562
|
+
const newFrame = /* @__PURE__ */ __name((n) => ({
|
|
2563
|
+
node: n,
|
|
2564
|
+
stage: 0,
|
|
2565
|
+
leftLayout: emptyDisplayLayout,
|
|
2566
|
+
rightLayout: emptyDisplayLayout
|
|
2567
|
+
}), "newFrame");
|
|
2568
|
+
const stack = [newFrame(node)];
|
|
2569
|
+
let result = emptyDisplayLayout;
|
|
2570
|
+
const setChildResult = /* @__PURE__ */ __name((layout) => {
|
|
2571
|
+
if (stack.length === 0) {
|
|
2572
|
+
result = layout;
|
|
2573
|
+
return;
|
|
2574
|
+
}
|
|
2575
|
+
const parent = stack[stack.length - 1];
|
|
2576
|
+
if (parent.stage === 1) parent.leftLayout = layout;
|
|
2577
|
+
else parent.rightLayout = layout;
|
|
2578
|
+
}, "setChildResult");
|
|
2579
|
+
while (stack.length > 0) {
|
|
2580
|
+
const frame = stack[stack.length - 1];
|
|
2581
|
+
const cur = frame.node;
|
|
2582
|
+
if (frame.stage === 0) {
|
|
2583
|
+
if (this._isDisplayLeaf(cur, options)) {
|
|
2584
|
+
stack.pop();
|
|
2585
|
+
const layout = this._resolveDisplayLeaf(cur, options, emptyDisplayLayout);
|
|
2586
|
+
setChildResult(layout);
|
|
2587
|
+
continue;
|
|
2588
|
+
}
|
|
2589
|
+
frame.stage = 1;
|
|
2590
|
+
stack.push(newFrame(cur.left));
|
|
2591
|
+
} else if (frame.stage === 1) {
|
|
2592
|
+
frame.stage = 2;
|
|
2593
|
+
stack.push(newFrame(cur.right));
|
|
2594
|
+
} else {
|
|
2595
|
+
stack.pop();
|
|
2596
|
+
const line = this.isNIL(cur) ? "S" : String(cur.key);
|
|
2597
|
+
const layout = _BinaryTree._buildNodeDisplay(line, line.length, frame.leftLayout, frame.rightLayout);
|
|
2598
|
+
setChildResult(layout);
|
|
2565
2599
|
}
|
|
2566
|
-
return [
|
|
2567
|
-
mergedLines,
|
|
2568
|
-
leftWidth + width + rightWidth,
|
|
2569
|
-
Math.max(leftHeight, rightHeight) + 2,
|
|
2570
|
-
leftWidth + Math.floor(width / 2)
|
|
2571
|
-
];
|
|
2572
2600
|
}
|
|
2601
|
+
return result;
|
|
2602
|
+
}
|
|
2603
|
+
static _buildNodeDisplay(line, width, left, right) {
|
|
2604
|
+
const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
|
|
2605
|
+
const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
|
|
2606
|
+
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));
|
|
2607
|
+
const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
|
|
2608
|
+
const mergedLines = [firstLine, secondLine];
|
|
2609
|
+
for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
|
|
2610
|
+
const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
|
|
2611
|
+
const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
|
|
2612
|
+
mergedLines.push(leftLine + " ".repeat(width) + rightLine);
|
|
2613
|
+
}
|
|
2614
|
+
return [
|
|
2615
|
+
mergedLines,
|
|
2616
|
+
leftWidth + width + rightWidth,
|
|
2617
|
+
Math.max(leftHeight, rightHeight) + 2,
|
|
2618
|
+
leftWidth + Math.floor(width / 2)
|
|
2619
|
+
];
|
|
2620
|
+
}
|
|
2621
|
+
/**
|
|
2622
|
+
* Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
|
|
2623
|
+
*/
|
|
2624
|
+
_isDisplayLeaf(node, options) {
|
|
2625
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
2626
|
+
if (node === null && !isShowNull) return true;
|
|
2627
|
+
if (node === void 0 && !isShowUndefined) return true;
|
|
2628
|
+
if (this.isNIL(node) && !isShowRedBlackNIL) return true;
|
|
2629
|
+
if (node === null || node === void 0) return true;
|
|
2630
|
+
const hasDisplayableLeft = this._hasDisplayableChild(node.left, options);
|
|
2631
|
+
const hasDisplayableRight = this._hasDisplayableChild(node.right, options);
|
|
2632
|
+
return !hasDisplayableLeft && !hasDisplayableRight;
|
|
2633
|
+
}
|
|
2634
|
+
_hasDisplayableChild(child, options) {
|
|
2635
|
+
if (child === null) return !!options.isShowNull;
|
|
2636
|
+
if (child === void 0) return !!options.isShowUndefined;
|
|
2637
|
+
if (this.isNIL(child)) return !!options.isShowRedBlackNIL;
|
|
2638
|
+
return true;
|
|
2639
|
+
}
|
|
2640
|
+
/**
|
|
2641
|
+
* Resolve a display leaf node to its layout.
|
|
2642
|
+
*/
|
|
2643
|
+
_resolveDisplayLeaf(node, options, emptyDisplayLayout) {
|
|
2644
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
2645
|
+
if (node === null && !isShowNull) return emptyDisplayLayout;
|
|
2646
|
+
if (node === void 0 && !isShowUndefined) return emptyDisplayLayout;
|
|
2647
|
+
if (this.isNIL(node) && !isShowRedBlackNIL) return emptyDisplayLayout;
|
|
2648
|
+
if (node !== null && node !== void 0) {
|
|
2649
|
+
const line2 = this.isNIL(node) ? "S" : String(node.key);
|
|
2650
|
+
return _BinaryTree._buildNodeDisplay(line2, line2.length, emptyDisplayLayout, emptyDisplayLayout);
|
|
2651
|
+
}
|
|
2652
|
+
const line = node === void 0 ? "U" : "N";
|
|
2653
|
+
return _BinaryTree._buildNodeDisplay(line, line.length, [[""], 1, 0, 0], [[""], 1, 0, 0]);
|
|
2573
2654
|
}
|
|
2574
2655
|
/**
|
|
2575
2656
|
* (Protected) Swaps the key/value properties of two nodes.
|
|
@@ -2715,6 +2796,6 @@ var BinaryTree = _BinaryTree;
|
|
|
2715
2796
|
* @license MIT License
|
|
2716
2797
|
*/
|
|
2717
2798
|
|
|
2718
|
-
export { BinaryTree, BinaryTreeNode, DFSOperation, Range };
|
|
2799
|
+
export { BinaryTree, BinaryTreeNode, DFSOperation, ERR, Range };
|
|
2719
2800
|
//# sourceMappingURL=index.mjs.map
|
|
2720
2801
|
//# sourceMappingURL=index.mjs.map
|