bst-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.
Files changed (45) hide show
  1. package/dist/cjs/index.cjs +160 -72
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +158 -70
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +160 -73
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +158 -71
  8. package/dist/esm-legacy/index.mjs.map +1 -1
  9. package/dist/types/common/error.d.ts +23 -0
  10. package/dist/types/common/index.d.ts +1 -0
  11. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +10 -0
  12. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +7 -1
  13. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  14. package/dist/types/data-structures/graph/directed-graph.d.ts +1 -0
  15. package/dist/types/data-structures/graph/undirected-graph.d.ts +14 -0
  16. package/dist/types/data-structures/queue/deque.d.ts +41 -1
  17. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  18. package/dist/umd/bst-typed.js +157 -69
  19. package/dist/umd/bst-typed.js.map +1 -1
  20. package/dist/umd/bst-typed.min.js +3 -3
  21. package/dist/umd/bst-typed.min.js.map +1 -1
  22. package/package.json +2 -2
  23. package/src/common/error.ts +60 -0
  24. package/src/common/index.ts +2 -0
  25. package/src/data-structures/base/iterable-element-base.ts +3 -2
  26. package/src/data-structures/binary-tree/binary-indexed-tree.ts +6 -5
  27. package/src/data-structures/binary-tree/binary-tree.ts +113 -42
  28. package/src/data-structures/binary-tree/bst.ts +11 -3
  29. package/src/data-structures/binary-tree/red-black-tree.ts +20 -0
  30. package/src/data-structures/binary-tree/tree-map.ts +8 -7
  31. package/src/data-structures/binary-tree/tree-multi-map.ts +4 -4
  32. package/src/data-structures/binary-tree/tree-multi-set.ts +5 -4
  33. package/src/data-structures/binary-tree/tree-set.ts +7 -6
  34. package/src/data-structures/graph/abstract-graph.ts +106 -1
  35. package/src/data-structures/graph/directed-graph.ts +4 -0
  36. package/src/data-structures/graph/undirected-graph.ts +95 -0
  37. package/src/data-structures/hash/hash-map.ts +13 -2
  38. package/src/data-structures/heap/heap.ts +4 -3
  39. package/src/data-structures/heap/max-heap.ts +2 -3
  40. package/src/data-structures/matrix/matrix.ts +9 -10
  41. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -3
  42. package/src/data-structures/queue/deque.ts +71 -3
  43. package/src/data-structures/trie/trie.ts +2 -1
  44. package/src/types/data-structures/queue/deque.ts +7 -0
  45. package/src/utils/utils.ts +4 -2
@@ -59,6 +59,55 @@ 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 {
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
+ static {
101
+ __name(this, "Range");
102
+ }
103
+ // Determine whether a key is within the range
104
+ isInRange(key, comparator) {
105
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
106
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
107
+ return lowCheck && highCheck;
108
+ }
109
+ };
110
+
62
111
  // src/data-structures/base/iterable-element-base.ts
63
112
  var IterableElementBase = class {
64
113
  static {
@@ -77,7 +126,7 @@ var IterableElementBase = class {
77
126
  if (options) {
78
127
  const { toElementFn } = options;
79
128
  if (typeof toElementFn === "function") this._toElementFn = toElementFn;
80
- else if (toElementFn) throw new TypeError("toElementFn must be a function type");
129
+ else if (toElementFn) throw new TypeError(ERR.notAFunction("toElementFn"));
81
130
  }
82
131
  }
83
132
  /**
@@ -240,7 +289,7 @@ var IterableElementBase = class {
240
289
  acc = initialValue;
241
290
  } else {
242
291
  const first = iter.next();
243
- if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
292
+ if (first.done) throw new TypeError(ERR.reduceEmpty());
244
293
  acc = first.value;
245
294
  index = 1;
246
295
  }
@@ -1025,30 +1074,6 @@ var IterableEntryBase = class {
1025
1074
  }
1026
1075
  };
1027
1076
 
1028
- // src/common/index.ts
1029
- var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
1030
- DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
1031
- DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
1032
- return DFSOperation2;
1033
- })(DFSOperation || {});
1034
- var Range = class {
1035
- constructor(low, high, includeLow = true, includeHigh = true) {
1036
- this.low = low;
1037
- this.high = high;
1038
- this.includeLow = includeLow;
1039
- this.includeHigh = includeHigh;
1040
- }
1041
- static {
1042
- __name(this, "Range");
1043
- }
1044
- // Determine whether a key is within the range
1045
- isInRange(key, comparator) {
1046
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
1047
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
1048
- return lowCheck && highCheck;
1049
- }
1050
- };
1051
-
1052
1077
  // src/data-structures/binary-tree/binary-tree.ts
1053
1078
  var BinaryTreeNode = class {
1054
1079
  static {
@@ -1187,7 +1212,7 @@ var BinaryTreeNode = class {
1187
1212
  return "MAL_NODE";
1188
1213
  }
1189
1214
  };
1190
- var BinaryTree = class extends IterableEntryBase {
1215
+ var BinaryTree = class _BinaryTree extends IterableEntryBase {
1191
1216
  static {
1192
1217
  __name(this, "BinaryTree");
1193
1218
  }
@@ -1207,7 +1232,7 @@ var BinaryTree = class extends IterableEntryBase {
1207
1232
  if (isMapMode !== void 0) this._isMapMode = isMapMode;
1208
1233
  if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
1209
1234
  if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
1210
- else if (toEntryFn) throw TypeError("toEntryFn must be a function type");
1235
+ else if (toEntryFn) throw new TypeError(ERR.notAFunction("toEntryFn", "BinaryTree"));
1211
1236
  }
1212
1237
  if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
1213
1238
  }
@@ -1445,7 +1470,7 @@ var BinaryTree = class extends IterableEntryBase {
1445
1470
  if (!this._root) {
1446
1471
  this._setRoot(newNode);
1447
1472
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
1448
- this._size = 1;
1473
+ if (newNode !== null) this._size = 1;
1449
1474
  return true;
1450
1475
  }
1451
1476
  const queue = new Queue([this._root]);
@@ -1477,7 +1502,7 @@ var BinaryTree = class extends IterableEntryBase {
1477
1502
  potentialParent.right = newNode;
1478
1503
  }
1479
1504
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
1480
- this._size++;
1505
+ if (newNode !== null) this._size++;
1481
1506
  return true;
1482
1507
  }
1483
1508
  return false;
@@ -2045,7 +2070,7 @@ var BinaryTree = class extends IterableEntryBase {
2045
2070
  }
2046
2071
  /**
2047
2072
  * Finds all leaf nodes in the tree.
2048
- * @remarks Time O(N), visits every node. Space O(H) for recursive stack or O(N) for iterative queue.
2073
+ * @remarks Time O(N), visits every node. Space O(H) for recursive or iterative stack.
2049
2074
  *
2050
2075
  * @template C - The type of the callback function.
2051
2076
  * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
@@ -2068,15 +2093,15 @@ var BinaryTree = class extends IterableEntryBase {
2068
2093
  }, "dfs");
2069
2094
  dfs(startNode);
2070
2095
  } else {
2071
- const queue = new Queue([startNode]);
2072
- while (queue.length > 0) {
2073
- const cur = queue.shift();
2096
+ const stack = [startNode];
2097
+ while (stack.length > 0) {
2098
+ const cur = stack.pop();
2074
2099
  if (this.isRealNode(cur)) {
2075
2100
  if (this.isLeaf(cur)) {
2076
2101
  leaves.push(callback(cur));
2077
2102
  }
2078
- if (this.isRealNode(cur.left)) queue.push(cur.left);
2079
- if (this.isRealNode(cur.right)) queue.push(cur.right);
2103
+ if (this.isRealNode(cur.right)) stack.push(cur.right);
2104
+ if (this.isRealNode(cur.left)) stack.push(cur.left);
2080
2105
  }
2081
2106
  }
2082
2107
  }
@@ -2538,42 +2563,98 @@ var BinaryTree = class extends IterableEntryBase {
2538
2563
  _displayAux(node, options) {
2539
2564
  const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
2540
2565
  const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
2541
- if (node === null && !isShowNull) {
2542
- return emptyDisplayLayout;
2543
- } else if (node === void 0 && !isShowUndefined) {
2544
- return emptyDisplayLayout;
2545
- } else if (this.isNIL(node) && !isShowRedBlackNIL) {
2546
- return emptyDisplayLayout;
2547
- } else if (node !== null && node !== void 0) {
2548
- const key = node.key, line = this.isNIL(node) ? "S" : String(key), width = line.length;
2549
- return _buildNodeDisplay(
2550
- line,
2551
- width,
2552
- this._displayAux(node.left, options),
2553
- this._displayAux(node.right, options)
2554
- );
2555
- } else {
2556
- const line = node === void 0 ? "U" : "N", width = line.length;
2557
- return _buildNodeDisplay(line, width, [[""], 1, 0, 0], [[""], 1, 0, 0]);
2558
- }
2559
- function _buildNodeDisplay(line, width, left, right) {
2560
- const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
2561
- const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
2562
- 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));
2563
- const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
2564
- const mergedLines = [firstLine, secondLine];
2565
- for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
2566
- const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
2567
- const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
2568
- mergedLines.push(leftLine + " ".repeat(width) + rightLine);
2566
+ const newFrame = /* @__PURE__ */ __name((n) => ({
2567
+ node: n,
2568
+ stage: 0,
2569
+ leftLayout: emptyDisplayLayout,
2570
+ rightLayout: emptyDisplayLayout
2571
+ }), "newFrame");
2572
+ const stack = [newFrame(node)];
2573
+ let result = emptyDisplayLayout;
2574
+ const setChildResult = /* @__PURE__ */ __name((layout) => {
2575
+ if (stack.length === 0) {
2576
+ result = layout;
2577
+ return;
2578
+ }
2579
+ const parent = stack[stack.length - 1];
2580
+ if (parent.stage === 1) parent.leftLayout = layout;
2581
+ else parent.rightLayout = layout;
2582
+ }, "setChildResult");
2583
+ while (stack.length > 0) {
2584
+ const frame = stack[stack.length - 1];
2585
+ const cur = frame.node;
2586
+ if (frame.stage === 0) {
2587
+ if (this._isDisplayLeaf(cur, options)) {
2588
+ stack.pop();
2589
+ const layout = this._resolveDisplayLeaf(cur, options, emptyDisplayLayout);
2590
+ setChildResult(layout);
2591
+ continue;
2592
+ }
2593
+ frame.stage = 1;
2594
+ stack.push(newFrame(cur.left));
2595
+ } else if (frame.stage === 1) {
2596
+ frame.stage = 2;
2597
+ stack.push(newFrame(cur.right));
2598
+ } else {
2599
+ stack.pop();
2600
+ const line = this.isNIL(cur) ? "S" : String(cur.key);
2601
+ const layout = _BinaryTree._buildNodeDisplay(line, line.length, frame.leftLayout, frame.rightLayout);
2602
+ setChildResult(layout);
2569
2603
  }
2570
- return [
2571
- mergedLines,
2572
- leftWidth + width + rightWidth,
2573
- Math.max(leftHeight, rightHeight) + 2,
2574
- leftWidth + Math.floor(width / 2)
2575
- ];
2576
2604
  }
2605
+ return result;
2606
+ }
2607
+ static _buildNodeDisplay(line, width, left, right) {
2608
+ const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
2609
+ const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
2610
+ 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));
2611
+ const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
2612
+ const mergedLines = [firstLine, secondLine];
2613
+ for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
2614
+ const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
2615
+ const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
2616
+ mergedLines.push(leftLine + " ".repeat(width) + rightLine);
2617
+ }
2618
+ return [
2619
+ mergedLines,
2620
+ leftWidth + width + rightWidth,
2621
+ Math.max(leftHeight, rightHeight) + 2,
2622
+ leftWidth + Math.floor(width / 2)
2623
+ ];
2624
+ }
2625
+ /**
2626
+ * Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
2627
+ */
2628
+ _isDisplayLeaf(node, options) {
2629
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
2630
+ if (node === null && !isShowNull) return true;
2631
+ if (node === void 0 && !isShowUndefined) return true;
2632
+ if (this.isNIL(node) && !isShowRedBlackNIL) return true;
2633
+ if (node === null || node === void 0) return true;
2634
+ const hasDisplayableLeft = this._hasDisplayableChild(node.left, options);
2635
+ const hasDisplayableRight = this._hasDisplayableChild(node.right, options);
2636
+ return !hasDisplayableLeft && !hasDisplayableRight;
2637
+ }
2638
+ _hasDisplayableChild(child, options) {
2639
+ if (child === null) return !!options.isShowNull;
2640
+ if (child === void 0) return !!options.isShowUndefined;
2641
+ if (this.isNIL(child)) return !!options.isShowRedBlackNIL;
2642
+ return true;
2643
+ }
2644
+ /**
2645
+ * Resolve a display leaf node to its layout.
2646
+ */
2647
+ _resolveDisplayLeaf(node, options, emptyDisplayLayout) {
2648
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
2649
+ if (node === null && !isShowNull) return emptyDisplayLayout;
2650
+ if (node === void 0 && !isShowUndefined) return emptyDisplayLayout;
2651
+ if (this.isNIL(node) && !isShowRedBlackNIL) return emptyDisplayLayout;
2652
+ if (node !== null && node !== void 0) {
2653
+ const line2 = this.isNIL(node) ? "S" : String(node.key);
2654
+ return _BinaryTree._buildNodeDisplay(line2, line2.length, emptyDisplayLayout, emptyDisplayLayout);
2655
+ }
2656
+ const line = node === void 0 ? "U" : "N";
2657
+ return _BinaryTree._buildNodeDisplay(line, line.length, [[""], 1, 0, 0], [[""], 1, 0, 0]);
2577
2658
  }
2578
2659
  /**
2579
2660
  * (Protected) Swaps the key/value properties of two nodes.
@@ -3579,9 +3660,15 @@ var BST = class extends BinaryTree {
3579
3660
  if (a < b) return -1;
3580
3661
  return 0;
3581
3662
  }
3663
+ if (a instanceof Date && b instanceof Date) {
3664
+ const ta = a.getTime();
3665
+ const tb = b.getTime();
3666
+ if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("BST"));
3667
+ return ta > tb ? 1 : ta < tb ? -1 : 0;
3668
+ }
3582
3669
  if (typeof a === "object" || typeof b === "object") {
3583
- throw TypeError(
3584
- `When comparing object type keys, a custom comparator must be provided in the constructor's options!`
3670
+ throw new TypeError(
3671
+ ERR.comparatorRequired("BST")
3585
3672
  );
3586
3673
  }
3587
3674
  return 0;
@@ -4001,6 +4088,7 @@ exports.BSTNode = BSTNode;
4001
4088
  exports.BinaryTree = BinaryTree;
4002
4089
  exports.BinaryTreeNode = BinaryTreeNode;
4003
4090
  exports.DFSOperation = DFSOperation;
4091
+ exports.ERR = ERR;
4004
4092
  exports.Range = Range;
4005
4093
  //# sourceMappingURL=index.cjs.map
4006
4094
  //# sourceMappingURL=index.cjs.map