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
@@ -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 must be a function type");
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("Reduce of empty structure with no initial value");
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 must be a function type");
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 stack or O(N) for iterative queue.
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 queue = new Queue([startNode]);
2074
- while (queue.length > 0) {
2075
- const cur = queue.shift();
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.left)) queue.push(cur.left);
2081
- if (this.isRealNode(cur.right)) queue.push(cur.right);
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
- if (node === null && !isShowNull) {
2538
- return emptyDisplayLayout;
2539
- } else if (node === void 0 && !isShowUndefined) {
2540
- return emptyDisplayLayout;
2541
- } else if (this.isNIL(node) && !isShowRedBlackNIL) {
2542
- return emptyDisplayLayout;
2543
- } else if (node !== null && node !== void 0) {
2544
- const key = node.key, line = this.isNIL(node) ? "S" : String(key), width = line.length;
2545
- return _buildNodeDisplay(
2546
- line,
2547
- width,
2548
- this._displayAux(node.left, options),
2549
- this._displayAux(node.right, options)
2550
- );
2551
- } else {
2552
- const line = node === void 0 ? "U" : "N", width = line.length;
2553
- return _buildNodeDisplay(line, width, [[""], 1, 0, 0], [[""], 1, 0, 0]);
2554
- }
2555
- function _buildNodeDisplay(line, width, left, right) {
2556
- const [leftLines, leftWidth, leftHeight, leftMiddle] = left;
2557
- const [rightLines, rightWidth, rightHeight, rightMiddle] = right;
2558
- 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));
2559
- const secondLine = (leftHeight > 0 ? " ".repeat(leftMiddle) + "/" + " ".repeat(leftWidth - leftMiddle - 1) : " ".repeat(leftWidth)) + " ".repeat(width) + (rightHeight > 0 ? " ".repeat(rightMiddle) + "\\" + " ".repeat(rightWidth - rightMiddle - 1) : " ".repeat(rightWidth));
2560
- const mergedLines = [firstLine, secondLine];
2561
- for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {
2562
- const leftLine = i < leftHeight ? leftLines[i] : " ".repeat(leftWidth);
2563
- const rightLine = i < rightHeight ? rightLines[i] : " ".repeat(rightWidth);
2564
- mergedLines.push(leftLine + " ".repeat(width) + rightLine);
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