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.
Files changed (45) hide show
  1. package/dist/cjs/index.cjs +152 -70
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs-legacy/index.cjs +150 -68
  4. package/dist/cjs-legacy/index.cjs.map +1 -1
  5. package/dist/esm/index.mjs +152 -71
  6. package/dist/esm/index.mjs.map +1 -1
  7. package/dist/esm-legacy/index.mjs +150 -69
  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/binary-tree-typed.js +149 -67
  19. package/dist/umd/binary-tree-typed.js.map +1 -1
  20. package/dist/umd/binary-tree-typed.min.js +3 -3
  21. package/dist/umd/binary-tree-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
@@ -57,6 +57,55 @@ function makeTrampoline(fn) {
57
57
  }
58
58
  __name(makeTrampoline, "makeTrampoline");
59
59
 
60
+ // src/common/error.ts
61
+ var ERR = {
62
+ // Range / index
63
+ indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
64
+ invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
65
+ // Type / argument
66
+ invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
67
+ comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
68
+ invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
69
+ notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
70
+ invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
71
+ invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
72
+ invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
73
+ reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
74
+ callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
75
+ // State / operation
76
+ invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
77
+ // Matrix
78
+ matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
79
+ matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
80
+ matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
81
+ matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
82
+ matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
83
+ };
84
+
85
+ // src/common/index.ts
86
+ var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
87
+ DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
88
+ DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
89
+ return DFSOperation2;
90
+ })(DFSOperation || {});
91
+ var Range = class {
92
+ constructor(low, high, includeLow = true, includeHigh = true) {
93
+ this.low = low;
94
+ this.high = high;
95
+ this.includeLow = includeLow;
96
+ this.includeHigh = includeHigh;
97
+ }
98
+ static {
99
+ __name(this, "Range");
100
+ }
101
+ // Determine whether a key is within the range
102
+ isInRange(key, comparator) {
103
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
104
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
105
+ return lowCheck && highCheck;
106
+ }
107
+ };
108
+
60
109
  // src/data-structures/base/iterable-element-base.ts
61
110
  var IterableElementBase = class {
62
111
  static {
@@ -75,7 +124,7 @@ var IterableElementBase = class {
75
124
  if (options) {
76
125
  const { toElementFn } = options;
77
126
  if (typeof toElementFn === "function") this._toElementFn = toElementFn;
78
- else if (toElementFn) throw new TypeError("toElementFn must be a function type");
127
+ else if (toElementFn) throw new TypeError(ERR.notAFunction("toElementFn"));
79
128
  }
80
129
  }
81
130
  /**
@@ -238,7 +287,7 @@ var IterableElementBase = class {
238
287
  acc = initialValue;
239
288
  } else {
240
289
  const first = iter.next();
241
- if (first.done) throw new TypeError("Reduce of empty structure with no initial value");
290
+ if (first.done) throw new TypeError(ERR.reduceEmpty());
242
291
  acc = first.value;
243
292
  index = 1;
244
293
  }
@@ -1023,30 +1072,6 @@ var IterableEntryBase = class {
1023
1072
  }
1024
1073
  };
1025
1074
 
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 {
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
- static {
1040
- __name(this, "Range");
1041
- }
1042
- // Determine whether a key is within the range
1043
- isInRange(key, comparator) {
1044
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
1045
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
1046
- return lowCheck && highCheck;
1047
- }
1048
- };
1049
-
1050
1075
  // src/data-structures/binary-tree/binary-tree.ts
1051
1076
  var BinaryTreeNode = class {
1052
1077
  static {
@@ -1185,7 +1210,7 @@ var BinaryTreeNode = class {
1185
1210
  return "MAL_NODE";
1186
1211
  }
1187
1212
  };
1188
- var BinaryTree = class extends IterableEntryBase {
1213
+ var BinaryTree = class _BinaryTree extends IterableEntryBase {
1189
1214
  static {
1190
1215
  __name(this, "BinaryTree");
1191
1216
  }
@@ -1205,7 +1230,7 @@ var BinaryTree = class extends IterableEntryBase {
1205
1230
  if (isMapMode !== void 0) this._isMapMode = isMapMode;
1206
1231
  if (isDuplicate !== void 0) this._isDuplicate = isDuplicate;
1207
1232
  if (typeof toEntryFn === "function") this._toEntryFn = toEntryFn;
1208
- else if (toEntryFn) throw TypeError("toEntryFn must be a function type");
1233
+ else if (toEntryFn) throw new TypeError(ERR.notAFunction("toEntryFn", "BinaryTree"));
1209
1234
  }
1210
1235
  if (keysNodesEntriesOrRaws) this.setMany(keysNodesEntriesOrRaws);
1211
1236
  }
@@ -1443,7 +1468,7 @@ var BinaryTree = class extends IterableEntryBase {
1443
1468
  if (!this._root) {
1444
1469
  this._setRoot(newNode);
1445
1470
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
1446
- this._size = 1;
1471
+ if (newNode !== null) this._size = 1;
1447
1472
  return true;
1448
1473
  }
1449
1474
  const queue = new Queue([this._root]);
@@ -1475,7 +1500,7 @@ var BinaryTree = class extends IterableEntryBase {
1475
1500
  potentialParent.right = newNode;
1476
1501
  }
1477
1502
  if (this._isMapMode && newNode !== null && newNode !== void 0) this._store.set(newNode.key, newNode);
1478
- this._size++;
1503
+ if (newNode !== null) this._size++;
1479
1504
  return true;
1480
1505
  }
1481
1506
  return false;
@@ -2043,7 +2068,7 @@ var BinaryTree = class extends IterableEntryBase {
2043
2068
  }
2044
2069
  /**
2045
2070
  * Finds all leaf nodes in the tree.
2046
- * @remarks Time O(N), visits every node. Space O(H) for recursive stack or O(N) for iterative queue.
2071
+ * @remarks Time O(N), visits every node. Space O(H) for recursive or iterative stack.
2047
2072
  *
2048
2073
  * @template C - The type of the callback function.
2049
2074
  * @param [callback=this._DEFAULT_NODE_CALLBACK] - Function to call on each leaf node.
@@ -2066,15 +2091,15 @@ var BinaryTree = class extends IterableEntryBase {
2066
2091
  }, "dfs");
2067
2092
  dfs(startNode);
2068
2093
  } else {
2069
- const queue = new Queue([startNode]);
2070
- while (queue.length > 0) {
2071
- const cur = queue.shift();
2094
+ const stack = [startNode];
2095
+ while (stack.length > 0) {
2096
+ const cur = stack.pop();
2072
2097
  if (this.isRealNode(cur)) {
2073
2098
  if (this.isLeaf(cur)) {
2074
2099
  leaves.push(callback(cur));
2075
2100
  }
2076
- if (this.isRealNode(cur.left)) queue.push(cur.left);
2077
- if (this.isRealNode(cur.right)) queue.push(cur.right);
2101
+ if (this.isRealNode(cur.right)) stack.push(cur.right);
2102
+ if (this.isRealNode(cur.left)) stack.push(cur.left);
2078
2103
  }
2079
2104
  }
2080
2105
  }
@@ -2536,42 +2561,98 @@ var BinaryTree = class extends IterableEntryBase {
2536
2561
  _displayAux(node, options) {
2537
2562
  const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
2538
2563
  const emptyDisplayLayout = [["\u2500"], 1, 0, 0];
2539
- if (node === null && !isShowNull) {
2540
- return emptyDisplayLayout;
2541
- } else if (node === void 0 && !isShowUndefined) {
2542
- return emptyDisplayLayout;
2543
- } else if (this.isNIL(node) && !isShowRedBlackNIL) {
2544
- return emptyDisplayLayout;
2545
- } else if (node !== null && node !== void 0) {
2546
- const key = node.key, line = this.isNIL(node) ? "S" : String(key), width = line.length;
2547
- return _buildNodeDisplay(
2548
- line,
2549
- width,
2550
- this._displayAux(node.left, options),
2551
- this._displayAux(node.right, options)
2552
- );
2553
- } else {
2554
- const line = node === void 0 ? "U" : "N", width = line.length;
2555
- return _buildNodeDisplay(line, width, [[""], 1, 0, 0], [[""], 1, 0, 0]);
2556
- }
2557
- function _buildNodeDisplay(line, width, left, right) {
2558
- const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
2559
- const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
2560
- 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));
2561
- const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
2562
- const mergedLines = [firstLine, secondLine];
2563
- for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
2564
- const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
2565
- const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
2566
- mergedLines.push(leftLine + " ".repeat(width) + rightLine);
2564
+ const newFrame = /* @__PURE__ */ __name((n) => ({
2565
+ node: n,
2566
+ stage: 0,
2567
+ leftLayout: emptyDisplayLayout,
2568
+ rightLayout: emptyDisplayLayout
2569
+ }), "newFrame");
2570
+ const stack = [newFrame(node)];
2571
+ let result = emptyDisplayLayout;
2572
+ const setChildResult = /* @__PURE__ */ __name((layout) => {
2573
+ if (stack.length === 0) {
2574
+ result = layout;
2575
+ return;
2567
2576
  }
2568
- return [
2569
- mergedLines,
2570
- leftWidth + width + rightWidth,
2571
- Math.max(leftHeight, rightHeight) + 2,
2572
- leftWidth + Math.floor(width / 2)
2573
- ];
2577
+ const parent = stack[stack.length - 1];
2578
+ if (parent.stage === 1) parent.leftLayout = layout;
2579
+ else parent.rightLayout = layout;
2580
+ }, "setChildResult");
2581
+ while (stack.length > 0) {
2582
+ const frame = stack[stack.length - 1];
2583
+ const cur = frame.node;
2584
+ if (frame.stage === 0) {
2585
+ if (this._isDisplayLeaf(cur, options)) {
2586
+ stack.pop();
2587
+ const layout = this._resolveDisplayLeaf(cur, options, emptyDisplayLayout);
2588
+ setChildResult(layout);
2589
+ continue;
2590
+ }
2591
+ frame.stage = 1;
2592
+ stack.push(newFrame(cur.left));
2593
+ } else if (frame.stage === 1) {
2594
+ frame.stage = 2;
2595
+ stack.push(newFrame(cur.right));
2596
+ } else {
2597
+ stack.pop();
2598
+ const line = this.isNIL(cur) ? "S" : String(cur.key);
2599
+ const layout = _BinaryTree._buildNodeDisplay(line, line.length, frame.leftLayout, frame.rightLayout);
2600
+ setChildResult(layout);
2601
+ }
2602
+ }
2603
+ return result;
2604
+ }
2605
+ static _buildNodeDisplay(line, width, left, right) {
2606
+ const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
2607
+ const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
2608
+ 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));
2609
+ const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
2610
+ const mergedLines = [firstLine, secondLine];
2611
+ for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
2612
+ const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
2613
+ const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
2614
+ mergedLines.push(leftLine + " ".repeat(width) + rightLine);
2615
+ }
2616
+ return [
2617
+ mergedLines,
2618
+ leftWidth + width + rightWidth,
2619
+ Math.max(leftHeight, rightHeight) + 2,
2620
+ leftWidth + Math.floor(width / 2)
2621
+ ];
2622
+ }
2623
+ /**
2624
+ * Check if a node is a display leaf (empty, null, undefined, NIL, or real leaf).
2625
+ */
2626
+ _isDisplayLeaf(node, options) {
2627
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
2628
+ if (node === null && !isShowNull) return true;
2629
+ if (node === void 0 && !isShowUndefined) return true;
2630
+ if (this.isNIL(node) && !isShowRedBlackNIL) return true;
2631
+ if (node === null || node === void 0) return true;
2632
+ const hasDisplayableLeft = this._hasDisplayableChild(node.left, options);
2633
+ const hasDisplayableRight = this._hasDisplayableChild(node.right, options);
2634
+ return !hasDisplayableLeft && !hasDisplayableRight;
2635
+ }
2636
+ _hasDisplayableChild(child, options) {
2637
+ if (child === null) return !!options.isShowNull;
2638
+ if (child === void 0) return !!options.isShowUndefined;
2639
+ if (this.isNIL(child)) return !!options.isShowRedBlackNIL;
2640
+ return true;
2641
+ }
2642
+ /**
2643
+ * Resolve a display leaf node to its layout.
2644
+ */
2645
+ _resolveDisplayLeaf(node, options, emptyDisplayLayout) {
2646
+ const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
2647
+ if (node === null && !isShowNull) return emptyDisplayLayout;
2648
+ if (node === void 0 && !isShowUndefined) return emptyDisplayLayout;
2649
+ if (this.isNIL(node) && !isShowRedBlackNIL) return emptyDisplayLayout;
2650
+ if (node !== null && node !== void 0) {
2651
+ const line2 = this.isNIL(node) ? "S" : String(node.key);
2652
+ return _BinaryTree._buildNodeDisplay(line2, line2.length, emptyDisplayLayout, emptyDisplayLayout);
2574
2653
  }
2654
+ const line = node === void 0 ? "U" : "N";
2655
+ return _BinaryTree._buildNodeDisplay(line, line.length, [[""], 1, 0, 0], [[""], 1, 0, 0]);
2575
2656
  }
2576
2657
  /**
2577
2658
  * (Protected) Swaps the key/value properties of two nodes.
@@ -2715,6 +2796,6 @@ var BinaryTree = class extends IterableEntryBase {
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