avl-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 +154 -67
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +152 -65
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +154 -67
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +152 -65
- 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/avl-tree-typed.js +151 -64
- package/dist/umd/avl-tree-typed.js.map +1 -1
- package/dist/umd/avl-tree-typed.min.js +3 -3
- package/dist/umd/avl-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
package/dist/cjs/index.cjs
CHANGED
|
@@ -59,6 +59,50 @@ 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 Range = class {
|
|
89
|
+
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
90
|
+
this.low = low;
|
|
91
|
+
this.high = high;
|
|
92
|
+
this.includeLow = includeLow;
|
|
93
|
+
this.includeHigh = includeHigh;
|
|
94
|
+
}
|
|
95
|
+
static {
|
|
96
|
+
__name(this, "Range");
|
|
97
|
+
}
|
|
98
|
+
// Determine whether a key is within the range
|
|
99
|
+
isInRange(key, comparator) {
|
|
100
|
+
const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
|
|
101
|
+
const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
|
|
102
|
+
return lowCheck && highCheck;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
62
106
|
// src/data-structures/base/iterable-element-base.ts
|
|
63
107
|
var IterableElementBase = class {
|
|
64
108
|
static {
|
|
@@ -77,7 +121,7 @@ var IterableElementBase = class {
|
|
|
77
121
|
if (options) {
|
|
78
122
|
const { toElementFn } = options;
|
|
79
123
|
if (typeof toElementFn === "function") this._toElementFn = toElementFn;
|
|
80
|
-
else if (toElementFn) throw new TypeError("toElementFn
|
|
124
|
+
else if (toElementFn) throw new TypeError(ERR.notAFunction("toElementFn"));
|
|
81
125
|
}
|
|
82
126
|
}
|
|
83
127
|
/**
|
|
@@ -240,7 +284,7 @@ var IterableElementBase = class {
|
|
|
240
284
|
acc = initialValue;
|
|
241
285
|
} else {
|
|
242
286
|
const first = iter.next();
|
|
243
|
-
if (first.done) throw new TypeError(
|
|
287
|
+
if (first.done) throw new TypeError(ERR.reduceEmpty());
|
|
244
288
|
acc = first.value;
|
|
245
289
|
index = 1;
|
|
246
290
|
}
|
|
@@ -1025,25 +1069,6 @@ var IterableEntryBase = class {
|
|
|
1025
1069
|
}
|
|
1026
1070
|
};
|
|
1027
1071
|
|
|
1028
|
-
// src/common/index.ts
|
|
1029
|
-
var Range = class {
|
|
1030
|
-
constructor(low, high, includeLow = true, includeHigh = true) {
|
|
1031
|
-
this.low = low;
|
|
1032
|
-
this.high = high;
|
|
1033
|
-
this.includeLow = includeLow;
|
|
1034
|
-
this.includeHigh = includeHigh;
|
|
1035
|
-
}
|
|
1036
|
-
static {
|
|
1037
|
-
__name(this, "Range");
|
|
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
|
-
|
|
1047
1072
|
// src/data-structures/binary-tree/binary-tree.ts
|
|
1048
1073
|
var BinaryTreeNode = class {
|
|
1049
1074
|
static {
|
|
@@ -1182,7 +1207,7 @@ var BinaryTreeNode = class {
|
|
|
1182
1207
|
return "MAL_NODE";
|
|
1183
1208
|
}
|
|
1184
1209
|
};
|
|
1185
|
-
var BinaryTree = class extends IterableEntryBase {
|
|
1210
|
+
var BinaryTree = class _BinaryTree extends IterableEntryBase {
|
|
1186
1211
|
static {
|
|
1187
1212
|
__name(this, "BinaryTree");
|
|
1188
1213
|
}
|
|
@@ -1202,7 +1227,7 @@ var BinaryTree = class extends IterableEntryBase {
|
|
|
1202
1227
|
if (isMapMode !== void 0) this._isMapMode = isMapMode;
|
|
1203
1228
|
if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
|
|
1204
1229
|
if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
|
|
1205
|
-
else if (toEntryFn) throw TypeError("toEntryFn
|
|
1230
|
+
else if (toEntryFn) throw new TypeError(ERR.notAFunction("toEntryFn", "BinaryTree"));
|
|
1206
1231
|
}
|
|
1207
1232
|
if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
|
|
1208
1233
|
}
|
|
@@ -1440,7 +1465,7 @@ var BinaryTree = class extends IterableEntryBase {
|
|
|
1440
1465
|
if (!this._root) {
|
|
1441
1466
|
this._setRoot(newNode);
|
|
1442
1467
|
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
1443
|
-
this._size = 1;
|
|
1468
|
+
if (newNode !== null) this._size = 1;
|
|
1444
1469
|
return true;
|
|
1445
1470
|
}
|
|
1446
1471
|
const queue = new Queue([this._root]);
|
|
@@ -1472,7 +1497,7 @@ var BinaryTree = class extends IterableEntryBase {
|
|
|
1472
1497
|
potentialParent.right = newNode;
|
|
1473
1498
|
}
|
|
1474
1499
|
if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
|
|
1475
|
-
this._size++;
|
|
1500
|
+
if (newNode !== null) this._size++;
|
|
1476
1501
|
return true;
|
|
1477
1502
|
}
|
|
1478
1503
|
return false;
|
|
@@ -2040,7 +2065,7 @@ var BinaryTree = class extends IterableEntryBase {
|
|
|
2040
2065
|
}
|
|
2041
2066
|
/**
|
|
2042
2067
|
* Finds all leaf nodes in the tree.
|
|
2043
|
-
* @remarks Time O(N), visits every node. Space O(H) for recursive
|
|
2068
|
+
* @remarks Time O(N), visits every node. Space O(H) for recursive or iterative stack.
|
|
2044
2069
|
*
|
|
2045
2070
|
* @template C - The type of the callback function.
|
|
2046
2071
|
* @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
|
|
@@ -2063,15 +2088,15 @@ var BinaryTree = class extends IterableEntryBase {
|
|
|
2063
2088
|
}, "dfs");
|
|
2064
2089
|
dfs(startNode);
|
|
2065
2090
|
} else {
|
|
2066
|
-
const
|
|
2067
|
-
while (
|
|
2068
|
-
const cur =
|
|
2091
|
+
const stack = [startNode];
|
|
2092
|
+
while (stack.length > 0) {
|
|
2093
|
+
const cur = stack.pop();
|
|
2069
2094
|
if (this.isRealNode(cur)) {
|
|
2070
2095
|
if (this.isLeaf(cur)) {
|
|
2071
2096
|
leaves.push(callback(cur));
|
|
2072
2097
|
}
|
|
2073
|
-
if (this.isRealNode(cur.
|
|
2074
|
-
if (this.isRealNode(cur.
|
|
2098
|
+
if (this.isRealNode(cur.right)) stack.push(cur.right);
|
|
2099
|
+
if (this.isRealNode(cur.left)) stack.push(cur.left);
|
|
2075
2100
|
}
|
|
2076
2101
|
}
|
|
2077
2102
|
}
|
|
@@ -2533,42 +2558,98 @@ var BinaryTree = class extends IterableEntryBase {
|
|
|
2533
2558
|
_displayAux(node, options) {
|
|
2534
2559
|
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
2535
2560
|
const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
const
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2561
|
+
const newFrame = /* @__PURE__ */ __name((n) => ({
|
|
2562
|
+
node: n,
|
|
2563
|
+
stage: 0,
|
|
2564
|
+
leftLayout: emptyDisplayLayout,
|
|
2565
|
+
rightLayout: emptyDisplayLayout
|
|
2566
|
+
}), "newFrame");
|
|
2567
|
+
const stack = [newFrame(node)];
|
|
2568
|
+
let result = emptyDisplayLayout;
|
|
2569
|
+
const setChildResult = /* @__PURE__ */ __name((layout) => {
|
|
2570
|
+
if (stack.length === 0) {
|
|
2571
|
+
result = layout;
|
|
2572
|
+
return;
|
|
2573
|
+
}
|
|
2574
|
+
const parent = stack[stack.length - 1];
|
|
2575
|
+
if (parent.stage === 1) parent.leftLayout = layout;
|
|
2576
|
+
else parent.rightLayout = layout;
|
|
2577
|
+
}, "setChildResult");
|
|
2578
|
+
while (stack.length > 0) {
|
|
2579
|
+
const frame = stack[stack.length - 1];
|
|
2580
|
+
const cur = frame.node;
|
|
2581
|
+
if (frame.stage === 0) {
|
|
2582
|
+
if (this._isDisplayLeaf(cur, options)) {
|
|
2583
|
+
stack.pop();
|
|
2584
|
+
const layout = this._resolveDisplayLeaf(cur, options, emptyDisplayLayout);
|
|
2585
|
+
setChildResult(layout);
|
|
2586
|
+
continue;
|
|
2587
|
+
}
|
|
2588
|
+
frame.stage = 1;
|
|
2589
|
+
stack.push(newFrame(cur.left));
|
|
2590
|
+
} else if (frame.stage === 1) {
|
|
2591
|
+
frame.stage = 2;
|
|
2592
|
+
stack.push(newFrame(cur.right));
|
|
2593
|
+
} else {
|
|
2594
|
+
stack.pop();
|
|
2595
|
+
const line = this.isNIL(cur) ? "S" : String(cur.key);
|
|
2596
|
+
const layout = _BinaryTree._buildNodeDisplay(line, line.length, frame.leftLayout, frame.rightLayout);
|
|
2597
|
+
setChildResult(layout);
|
|
2564
2598
|
}
|
|
2565
|
-
return [
|
|
2566
|
-
mergedLines,
|
|
2567
|
-
leftWidth + width + rightWidth,
|
|
2568
|
-
Math.max(leftHeight, rightHeight) + 2,
|
|
2569
|
-
leftWidth + Math.floor(width / 2)
|
|
2570
|
-
];
|
|
2571
2599
|
}
|
|
2600
|
+
return result;
|
|
2601
|
+
}
|
|
2602
|
+
static _buildNodeDisplay(line, width, left, right) {
|
|
2603
|
+
const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
|
|
2604
|
+
const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
|
|
2605
|
+
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));
|
|
2606
|
+
const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
|
|
2607
|
+
const mergedLines = [firstLine, secondLine];
|
|
2608
|
+
for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
|
|
2609
|
+
const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
|
|
2610
|
+
const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
|
|
2611
|
+
mergedLines.push(leftLine + " ".repeat(width) + rightLine);
|
|
2612
|
+
}
|
|
2613
|
+
return [
|
|
2614
|
+
mergedLines,
|
|
2615
|
+
leftWidth + width + rightWidth,
|
|
2616
|
+
Math.max(leftHeight, rightHeight) + 2,
|
|
2617
|
+
leftWidth + Math.floor(width / 2)
|
|
2618
|
+
];
|
|
2619
|
+
}
|
|
2620
|
+
/**
|
|
2621
|
+
* Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
|
|
2622
|
+
*/
|
|
2623
|
+
_isDisplayLeaf(node, options) {
|
|
2624
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
2625
|
+
if (node === null && !isShowNull) return true;
|
|
2626
|
+
if (node === void 0 && !isShowUndefined) return true;
|
|
2627
|
+
if (this.isNIL(node) && !isShowRedBlackNIL) return true;
|
|
2628
|
+
if (node === null || node === void 0) return true;
|
|
2629
|
+
const hasDisplayableLeft = this._hasDisplayableChild(node.left, options);
|
|
2630
|
+
const hasDisplayableRight = this._hasDisplayableChild(node.right, options);
|
|
2631
|
+
return !hasDisplayableLeft && !hasDisplayableRight;
|
|
2632
|
+
}
|
|
2633
|
+
_hasDisplayableChild(child, options) {
|
|
2634
|
+
if (child === null) return !!options.isShowNull;
|
|
2635
|
+
if (child === void 0) return !!options.isShowUndefined;
|
|
2636
|
+
if (this.isNIL(child)) return !!options.isShowRedBlackNIL;
|
|
2637
|
+
return true;
|
|
2638
|
+
}
|
|
2639
|
+
/**
|
|
2640
|
+
* Resolve a display leaf node to its layout.
|
|
2641
|
+
*/
|
|
2642
|
+
_resolveDisplayLeaf(node, options, emptyDisplayLayout) {
|
|
2643
|
+
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
|
|
2644
|
+
if (node === null && !isShowNull) return emptyDisplayLayout;
|
|
2645
|
+
if (node === void 0 && !isShowUndefined) return emptyDisplayLayout;
|
|
2646
|
+
if (this.isNIL(node) && !isShowRedBlackNIL) return emptyDisplayLayout;
|
|
2647
|
+
if (node !== null && node !== void 0) {
|
|
2648
|
+
const line2 = this.isNIL(node) ? "S" : String(node.key);
|
|
2649
|
+
return _BinaryTree._buildNodeDisplay(line2, line2.length, emptyDisplayLayout, emptyDisplayLayout);
|
|
2650
|
+
}
|
|
2651
|
+
const line = node === void 0 ? "U" : "N";
|
|
2652
|
+
return _BinaryTree._buildNodeDisplay(line, line.length, [[""], 1, 0, 0], [[""], 1, 0, 0]);
|
|
2572
2653
|
}
|
|
2573
2654
|
/**
|
|
2574
2655
|
* (Protected) Swaps the key/value properties of two nodes.
|
|
@@ -3574,9 +3655,15 @@ var BST = class extends BinaryTree {
|
|
|
3574
3655
|
if (a < b) return -1;
|
|
3575
3656
|
return 0;
|
|
3576
3657
|
}
|
|
3658
|
+
if (a instanceof Date && b instanceof Date) {
|
|
3659
|
+
const ta = a.getTime();
|
|
3660
|
+
const tb = b.getTime();
|
|
3661
|
+
if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("BST"));
|
|
3662
|
+
return ta > tb ? 1 : ta < tb ? -1 : 0;
|
|
3663
|
+
}
|
|
3577
3664
|
if (typeof a === "object" || typeof b === "object") {
|
|
3578
|
-
throw TypeError(
|
|
3579
|
-
|
|
3665
|
+
throw new TypeError(
|
|
3666
|
+
ERR.comparatorRequired("BST")
|
|
3580
3667
|
);
|
|
3581
3668
|
}
|
|
3582
3669
|
return 0;
|