linked-list-typed 2.4.4 → 2.5.0

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 (85) hide show
  1. package/README.md +14 -50
  2. package/dist/cjs/index.cjs +1537 -267
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/cjs-legacy/index.cjs +1543 -264
  5. package/dist/cjs-legacy/index.cjs.map +1 -1
  6. package/dist/esm/index.mjs +1537 -268
  7. package/dist/esm/index.mjs.map +1 -1
  8. package/dist/esm-legacy/index.mjs +1543 -265
  9. package/dist/esm-legacy/index.mjs.map +1 -1
  10. package/dist/types/common/error.d.ts +23 -0
  11. package/dist/types/common/index.d.ts +1 -0
  12. package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
  13. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
  14. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
  15. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
  16. package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
  17. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
  18. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
  19. package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
  20. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
  21. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
  22. package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
  23. package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
  24. package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
  25. package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
  26. package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
  27. package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
  28. package/dist/types/data-structures/heap/heap.d.ts +287 -99
  29. package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
  30. package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
  31. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
  32. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
  33. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
  34. package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
  35. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
  36. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
  37. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
  38. package/dist/types/data-structures/queue/deque.d.ts +313 -66
  39. package/dist/types/data-structures/queue/queue.d.ts +211 -42
  40. package/dist/types/data-structures/stack/stack.d.ts +174 -32
  41. package/dist/types/data-structures/trie/trie.d.ts +213 -43
  42. package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
  43. package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
  44. package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
  45. package/dist/umd/linked-list-typed.js +1540 -262
  46. package/dist/umd/linked-list-typed.js.map +1 -1
  47. package/dist/umd/linked-list-typed.min.js +1 -1
  48. package/dist/umd/linked-list-typed.min.js.map +1 -1
  49. package/package.json +2 -2
  50. package/src/common/error.ts +60 -0
  51. package/src/common/index.ts +2 -0
  52. package/src/data-structures/base/iterable-element-base.ts +2 -2
  53. package/src/data-structures/binary-tree/avl-tree.ts +134 -51
  54. package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
  55. package/src/data-structures/binary-tree/binary-tree.ts +542 -121
  56. package/src/data-structures/binary-tree/bst.ts +346 -37
  57. package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
  58. package/src/data-structures/binary-tree/segment-tree.ts +372 -248
  59. package/src/data-structures/binary-tree/tree-map.ts +1292 -13
  60. package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
  61. package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
  62. package/src/data-structures/binary-tree/tree-set.ts +1143 -15
  63. package/src/data-structures/graph/abstract-graph.ts +106 -1
  64. package/src/data-structures/graph/directed-graph.ts +223 -47
  65. package/src/data-structures/graph/map-graph.ts +59 -1
  66. package/src/data-structures/graph/undirected-graph.ts +299 -59
  67. package/src/data-structures/hash/hash-map.ts +243 -79
  68. package/src/data-structures/heap/heap.ts +291 -102
  69. package/src/data-structures/heap/max-heap.ts +48 -3
  70. package/src/data-structures/heap/min-heap.ts +59 -0
  71. package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
  72. package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
  73. package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
  74. package/src/data-structures/matrix/matrix.ts +425 -22
  75. package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
  76. package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
  77. package/src/data-structures/priority-queue/priority-queue.ts +60 -0
  78. package/src/data-structures/queue/deque.ts +343 -68
  79. package/src/data-structures/queue/queue.ts +211 -42
  80. package/src/data-structures/stack/stack.ts +174 -32
  81. package/src/data-structures/trie/trie.ts +215 -44
  82. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
  83. package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
  84. package/src/types/data-structures/queue/deque.ts +7 -0
  85. package/src/utils/utils.ts +4 -2
@@ -725,11 +725,37 @@ var SinglyLinkedList = class extends LinearLinkedBase {
725
725
  return list;
726
726
  }
727
727
  /**
728
- * Append an element/node to the tail.
729
- * @remarks Time O(1), Space O(1)
730
- * @param elementOrNode - Element or node to append.
731
- * @returns True when appended.
732
- */
728
+ * Append an element/node to the tail.
729
+ * @remarks Time O(1), Space O(1)
730
+ * @param elementOrNode - Element or node to append.
731
+ * @returns True when appended.
732
+
733
+
734
+
735
+
736
+
737
+
738
+
739
+
740
+
741
+
742
+
743
+ * @example
744
+ * // basic SinglyLinkedList creation and push operation
745
+ * // Create a simple SinglyLinkedList with initial values
746
+ * const list = new SinglyLinkedList([1, 2, 3, 4, 5]);
747
+ *
748
+ * // Verify the list maintains insertion order
749
+ * console.log([...list]); // [1, 2, 3, 4, 5];
750
+ *
751
+ * // Check length
752
+ * console.log(list.length); // 5;
753
+ *
754
+ * // Push a new element to the end
755
+ * list.push(6);
756
+ * console.log(list.length); // 6;
757
+ * console.log([...list]); // [1, 2, 3, 4, 5, 6];
758
+ */
733
759
  push(elementOrNode) {
734
760
  const newNode = this._ensureNode(elementOrNode);
735
761
  if (!this.head) {
@@ -743,10 +769,36 @@ var SinglyLinkedList = class extends LinearLinkedBase {
743
769
  return true;
744
770
  }
745
771
  /**
746
- * Remove and return the tail element.
747
- * @remarks Time O(N), Space O(1)
748
- * @returns Removed element or undefined.
749
- */
772
+ * Remove and return the tail element.
773
+ * @remarks Time O(N), Space O(1)
774
+ * @returns Removed element or undefined.
775
+
776
+
777
+
778
+
779
+
780
+
781
+
782
+
783
+
784
+
785
+
786
+ * @example
787
+ * // SinglyLinkedList pop and shift operations
788
+ * const list = new SinglyLinkedList<number>([10, 20, 30, 40, 50]);
789
+ *
790
+ * // Pop removes from the end
791
+ * const last = list.pop();
792
+ * console.log(last); // 50;
793
+ *
794
+ * // Shift removes from the beginning
795
+ * const first = list.shift();
796
+ * console.log(first); // 10;
797
+ *
798
+ * // Verify remaining elements
799
+ * console.log([...list]); // [20, 30, 40];
800
+ * console.log(list.length); // 3;
801
+ */
750
802
  pop() {
751
803
  if (!this.head) return void 0;
752
804
  if (this.head === this.tail) {
@@ -765,10 +817,26 @@ var SinglyLinkedList = class extends LinearLinkedBase {
765
817
  return value;
766
818
  }
767
819
  /**
768
- * Remove and return the head element.
769
- * @remarks Time O(1), Space O(1)
770
- * @returns Removed element or undefined.
771
- */
820
+ * Remove and return the head element.
821
+ * @remarks Time O(1), Space O(1)
822
+ * @returns Removed element or undefined.
823
+
824
+
825
+
826
+
827
+
828
+
829
+
830
+
831
+
832
+
833
+
834
+ * @example
835
+ * // Remove from the front
836
+ * const list = new SinglyLinkedList<number>([10, 20, 30]);
837
+ * console.log(list.shift()); // 10;
838
+ * console.log(list.length); // 2;
839
+ */
772
840
  shift() {
773
841
  if (!this.head) return void 0;
774
842
  const removed = this.head;
@@ -778,11 +846,42 @@ var SinglyLinkedList = class extends LinearLinkedBase {
778
846
  return removed.value;
779
847
  }
780
848
  /**
781
- * Prepend an element/node to the head.
782
- * @remarks Time O(1), Space O(1)
783
- * @param elementOrNode - Element or node to prepend.
784
- * @returns True when prepended.
785
- */
849
+ * Prepend an element/node to the head.
850
+ * @remarks Time O(1), Space O(1)
851
+ * @param elementOrNode - Element or node to prepend.
852
+ * @returns True when prepended.
853
+
854
+
855
+
856
+
857
+
858
+
859
+
860
+
861
+
862
+
863
+
864
+ * @example
865
+ * // SinglyLinkedList unshift and forward traversal
866
+ * const list = new SinglyLinkedList<number>([20, 30, 40]);
867
+ *
868
+ * // Unshift adds to the beginning
869
+ * list.unshift(10);
870
+ * console.log([...list]); // [10, 20, 30, 40];
871
+ *
872
+ * // Access elements (forward traversal only for singly linked)
873
+ * const second = list.at(1);
874
+ * console.log(second); // 20;
875
+ *
876
+ * // SinglyLinkedList allows forward iteration only
877
+ * const elements: number[] = [];
878
+ * for (const item of list) {
879
+ * elements.push(item);
880
+ * }
881
+ * console.log(elements); // [10, 20, 30, 40];
882
+ *
883
+ * console.log(list.length); // 4;
884
+ */
786
885
  unshift(elementOrNode) {
787
886
  const newNode = this._ensureNode(elementOrNode);
788
887
  if (!this.head) {
@@ -838,11 +937,28 @@ var SinglyLinkedList = class extends LinearLinkedBase {
838
937
  return void 0;
839
938
  }
840
939
  /**
841
- * Get the element at a given index.
842
- * @remarks Time O(N), Space O(1)
843
- * @param index - Zero-based index.
844
- * @returns Element or undefined.
845
- */
940
+ * Get the element at a given index.
941
+ * @remarks Time O(N), Space O(1)
942
+ * @param index - Zero-based index.
943
+ * @returns Element or undefined.
944
+
945
+
946
+
947
+
948
+
949
+
950
+
951
+
952
+
953
+
954
+
955
+ * @example
956
+ * // Access element by index
957
+ * const list = new SinglyLinkedList<string>(['a', 'b', 'c', 'd']);
958
+ * console.log(list.at(0)); // 'a';
959
+ * console.log(list.at(2)); // 'c';
960
+ * console.log(list.at(3)); // 'd';
961
+ */
846
962
  at(index) {
847
963
  if (index < 0 || index >= this._length) return void 0;
848
964
  let current = this.head;
@@ -859,11 +975,23 @@ var SinglyLinkedList = class extends LinearLinkedBase {
859
975
  return elementNodeOrPredicate instanceof SinglyLinkedListNode;
860
976
  }
861
977
  /**
862
- * Get the node reference at a given index.
863
- * @remarks Time O(N), Space O(1)
864
- * @param index - Zero-based index.
865
- * @returns Node or undefined.
866
- */
978
+ * Get the node reference at a given index.
979
+ * @remarks Time O(N), Space O(1)
980
+ * @param index - Zero-based index.
981
+ * @returns Node or undefined.
982
+
983
+
984
+
985
+
986
+
987
+
988
+
989
+
990
+ * @example
991
+ * // Get node at index
992
+ * const list = new SinglyLinkedList<string>(['a', 'b', 'c']);
993
+ * console.log(list.getNodeAt(1)?.value); // 'b';
994
+ */
867
995
  getNodeAt(index) {
868
996
  if (index < 0 || index >= this._length) return void 0;
869
997
  let current = this.head;
@@ -871,11 +999,24 @@ var SinglyLinkedList = class extends LinearLinkedBase {
871
999
  return current;
872
1000
  }
873
1001
  /**
874
- * Delete the element at an index.
875
- * @remarks Time O(N), Space O(1)
876
- * @param index - Zero-based index.
877
- * @returns Removed element or undefined.
878
- */
1002
+ * Delete the element at an index.
1003
+ * @remarks Time O(N), Space O(1)
1004
+ * @param index - Zero-based index.
1005
+ * @returns Removed element or undefined.
1006
+
1007
+
1008
+
1009
+
1010
+
1011
+
1012
+
1013
+
1014
+ * @example
1015
+ * // Remove by index
1016
+ * const list = new SinglyLinkedList<string>(['a', 'b', 'c']);
1017
+ * list.deleteAt(1);
1018
+ * console.log(list.toArray()); // ['a', 'c'];
1019
+ */
879
1020
  deleteAt(index) {
880
1021
  if (index < 0 || index >= this._length) return void 0;
881
1022
  if (index === 0) return this.shift();
@@ -888,11 +1029,24 @@ var SinglyLinkedList = class extends LinearLinkedBase {
888
1029
  return value;
889
1030
  }
890
1031
  /**
891
- * Delete the first match by value/node.
892
- * @remarks Time O(N), Space O(1)
893
- * @param [elementOrNode] - Element or node to remove; if omitted/undefined, nothing happens.
894
- * @returns True if removed.
895
- */
1032
+ * Delete the first match by value/node.
1033
+ * @remarks Time O(N), Space O(1)
1034
+ * @param [elementOrNode] - Element or node to remove; if omitted/undefined, nothing happens.
1035
+ * @returns True if removed.
1036
+
1037
+
1038
+
1039
+
1040
+
1041
+
1042
+
1043
+
1044
+ * @example
1045
+ * // Remove first occurrence
1046
+ * const list = new SinglyLinkedList<number>([1, 2, 3, 2]);
1047
+ * list.delete(2);
1048
+ * console.log(list.toArray()); // [1, 3, 2];
1049
+ */
896
1050
  delete(elementOrNode) {
897
1051
  if (elementOrNode === void 0 || !this.head) return false;
898
1052
  const node = this.isNode(elementOrNode) ? elementOrNode : this.getNode(elementOrNode);
@@ -909,12 +1063,25 @@ var SinglyLinkedList = class extends LinearLinkedBase {
909
1063
  return true;
910
1064
  }
911
1065
  /**
912
- * Insert a new element/node at an index, shifting following nodes.
913
- * @remarks Time O(N), Space O(1)
914
- * @param index - Zero-based index.
915
- * @param newElementOrNode - Element or node to insert.
916
- * @returns True if inserted.
917
- */
1066
+ * Insert a new element/node at an index, shifting following nodes.
1067
+ * @remarks Time O(N), Space O(1)
1068
+ * @param index - Zero-based index.
1069
+ * @param newElementOrNode - Element or node to insert.
1070
+ * @returns True if inserted.
1071
+
1072
+
1073
+
1074
+
1075
+
1076
+
1077
+
1078
+
1079
+ * @example
1080
+ * // Insert at index
1081
+ * const list = new SinglyLinkedList<number>([1, 3]);
1082
+ * list.addAt(1, 2);
1083
+ * console.log(list.toArray()); // [1, 2, 3];
1084
+ */
918
1085
  addAt(index, newElementOrNode) {
919
1086
  if (index < 0 || index > this._length) return false;
920
1087
  if (index === 0) return this.unshift(newElementOrNode);
@@ -940,28 +1107,70 @@ var SinglyLinkedList = class extends LinearLinkedBase {
940
1107
  return true;
941
1108
  }
942
1109
  /**
943
- * Check whether the list is empty.
944
- * @remarks Time O(1), Space O(1)
945
- * @returns True if length is 0.
946
- */
1110
+ * Check whether the list is empty.
1111
+ * @remarks Time O(1), Space O(1)
1112
+ * @returns True if length is 0.
1113
+
1114
+
1115
+
1116
+
1117
+
1118
+
1119
+
1120
+
1121
+
1122
+ * @example
1123
+ * // Check empty
1124
+ * console.log(new SinglyLinkedList().isEmpty()); // true;
1125
+ */
947
1126
  isEmpty() {
948
1127
  return this._length === 0;
949
1128
  }
950
1129
  /**
951
- * Remove all nodes and reset length.
952
- * @remarks Time O(N), Space O(1)
953
- * @returns void
954
- */
1130
+ * Remove all nodes and reset length.
1131
+ * @remarks Time O(N), Space O(1)
1132
+ * @returns void
1133
+
1134
+
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+ * @example
1143
+ * // Remove all
1144
+ * const list = new SinglyLinkedList<number>([1, 2, 3]);
1145
+ * list.clear();
1146
+ * console.log(list.isEmpty()); // true;
1147
+ */
955
1148
  clear() {
956
1149
  this._head = void 0;
957
1150
  this._tail = void 0;
958
1151
  this._length = 0;
959
1152
  }
960
1153
  /**
961
- * Reverse the list in place.
962
- * @remarks Time O(N), Space O(1)
963
- * @returns This list.
964
- */
1154
+ * Reverse the list in place.
1155
+ * @remarks Time O(N), Space O(1)
1156
+ * @returns This list.
1157
+
1158
+
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+
1168
+ * @example
1169
+ * // Reverse the list in-place
1170
+ * const list = new SinglyLinkedList<number>([1, 2, 3, 4]);
1171
+ * list.reverse();
1172
+ * console.log([...list]); // [4, 3, 2, 1];
1173
+ */
965
1174
  reverse() {
966
1175
  if (!this.head || this.head === this.tail) return this;
967
1176
  let prev;
@@ -1136,22 +1345,64 @@ var SinglyLinkedList = class extends LinearLinkedBase {
1136
1345
  return false;
1137
1346
  }
1138
1347
  /**
1139
- * Deep clone this list (values are copied by reference).
1140
- * @remarks Time O(N), Space O(N)
1141
- * @returns A new list with the same element sequence.
1142
- */
1348
+ * Deep clone this list (values are copied by reference).
1349
+ * @remarks Time O(N), Space O(N)
1350
+ * @returns A new list with the same element sequence.
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+
1360
+ * @example
1361
+ * // Deep copy
1362
+ * const list = new SinglyLinkedList<number>([1, 2, 3]);
1363
+ * const copy = list.clone();
1364
+ * copy.pop();
1365
+ * console.log(list.length); // 3;
1366
+ * console.log(copy.length); // 2;
1367
+ */
1143
1368
  clone() {
1144
1369
  const out = this._createInstance();
1145
1370
  for (const v of this) out.push(v);
1146
1371
  return out;
1147
1372
  }
1148
1373
  /**
1149
- * Filter values into a new list of the same class.
1150
- * @remarks Time O(N), Space O(N)
1151
- * @param callback - Predicate (value, index, list) → boolean to keep value.
1152
- * @param [thisArg] - Value for `this` inside the callback.
1153
- * @returns A new list with kept values.
1154
- */
1374
+ * Filter values into a new list of the same class.
1375
+ * @remarks Time O(N), Space O(N)
1376
+ * @param callback - Predicate (value, index, list) → boolean to keep value.
1377
+ * @param [thisArg] - Value for `this` inside the callback.
1378
+ * @returns A new list with kept values.
1379
+
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+
1389
+
1390
+ * @example
1391
+ * // SinglyLinkedList filter and map operations
1392
+ * const list = new SinglyLinkedList<number>([1, 2, 3, 4, 5]);
1393
+ *
1394
+ * // Filter even numbers
1395
+ * const filtered = list.filter(value => value % 2 === 0);
1396
+ * console.log(filtered.length); // 2;
1397
+ *
1398
+ * // Map to double values
1399
+ * const doubled = list.map(value => value * 2);
1400
+ * console.log(doubled.length); // 5;
1401
+ *
1402
+ * // Use reduce to sum
1403
+ * const sum = list.reduce((acc, value) => acc + value, 0);
1404
+ * console.log(sum); // 15;
1405
+ */
1155
1406
  filter(callback, thisArg) {
1156
1407
  const out = this._createInstance();
1157
1408
  let index = 0;
@@ -1175,15 +1426,31 @@ var SinglyLinkedList = class extends LinearLinkedBase {
1175
1426
  return out;
1176
1427
  }
1177
1428
  /**
1178
- * Map values into a new list (possibly different element type).
1179
- * @remarks Time O(N), Space O(N)
1180
- * @template EM
1181
- * @template RM
1182
- * @param callback - Mapping function (value, index, list) → newElement.
1183
- * @param [options] - Options for the output list (e.g., maxLen, toElementFn).
1184
- * @param [thisArg] - Value for `this` inside the callback.
1185
- * @returns A new SinglyLinkedList with mapped values.
1186
- */
1429
+ * Map values into a new list (possibly different element type).
1430
+ * @remarks Time O(N), Space O(N)
1431
+ * @template EM
1432
+ * @template RM
1433
+ * @param callback - Mapping function (value, index, list) → newElement.
1434
+ * @param [options] - Options for the output list (e.g., maxLen, toElementFn).
1435
+ * @param [thisArg] - Value for `this` inside the callback.
1436
+ * @returns A new SinglyLinkedList with mapped values.
1437
+
1438
+
1439
+
1440
+
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+ * @example
1449
+ * // Transform elements
1450
+ * const list = new SinglyLinkedList<number>([1, 2, 3]);
1451
+ * const doubled = list.map(n => n * 2);
1452
+ * console.log([...doubled]); // [2, 4, 6];
1453
+ */
1187
1454
  map(callback, options, thisArg) {
1188
1455
  const out = this._createLike([], { ...options ?? {}, maxLen: this._maxLen });
1189
1456
  let index = 0;
@@ -1459,11 +1726,37 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1459
1726
  return elementNodeOrPredicate instanceof DoublyLinkedListNode;
1460
1727
  }
1461
1728
  /**
1462
- * Append an element/node to the tail.
1463
- * @remarks Time O(1), Space O(1)
1464
- * @param elementOrNode - Element or node to append.
1465
- * @returns True when appended.
1466
- */
1729
+ * Append an element/node to the tail.
1730
+ * @remarks Time O(1), Space O(1)
1731
+ * @param elementOrNode - Element or node to append.
1732
+ * @returns True when appended.
1733
+
1734
+
1735
+
1736
+
1737
+
1738
+
1739
+
1740
+
1741
+
1742
+
1743
+
1744
+ * @example
1745
+ * // basic DoublyLinkedList creation and push operation
1746
+ * // Create a simple DoublyLinkedList with initial values
1747
+ * const list = new DoublyLinkedList([1, 2, 3, 4, 5]);
1748
+ *
1749
+ * // Verify the list maintains insertion order
1750
+ * console.log([...list]); // [1, 2, 3, 4, 5];
1751
+ *
1752
+ * // Check length
1753
+ * console.log(list.length); // 5;
1754
+ *
1755
+ * // Push a new element to the end
1756
+ * list.push(6);
1757
+ * console.log(list.length); // 6;
1758
+ * console.log([...list]); // [1, 2, 3, 4, 5, 6];
1759
+ */
1467
1760
  push(elementOrNode) {
1468
1761
  const newNode = this._ensureNode(elementOrNode);
1469
1762
  if (!this.head) {
@@ -1479,10 +1772,36 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1479
1772
  return true;
1480
1773
  }
1481
1774
  /**
1482
- * Remove and return the tail element.
1483
- * @remarks Time O(1), Space O(1)
1484
- * @returns Removed element or undefined.
1485
- */
1775
+ * Remove and return the tail element.
1776
+ * @remarks Time O(1), Space O(1)
1777
+ * @returns Removed element or undefined.
1778
+
1779
+
1780
+
1781
+
1782
+
1783
+
1784
+
1785
+
1786
+
1787
+
1788
+
1789
+ * @example
1790
+ * // DoublyLinkedList pop and shift operations
1791
+ * const list = new DoublyLinkedList<number>([10, 20, 30, 40, 50]);
1792
+ *
1793
+ * // Pop removes from the end
1794
+ * const last = list.pop();
1795
+ * console.log(last); // 50;
1796
+ *
1797
+ * // Shift removes from the beginning
1798
+ * const first = list.shift();
1799
+ * console.log(first); // 10;
1800
+ *
1801
+ * // Verify remaining elements
1802
+ * console.log([...list]); // [20, 30, 40];
1803
+ * console.log(list.length); // 3;
1804
+ */
1486
1805
  pop() {
1487
1806
  if (!this.tail) return void 0;
1488
1807
  const removed = this.tail;
@@ -1497,10 +1816,26 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1497
1816
  return removed.value;
1498
1817
  }
1499
1818
  /**
1500
- * Remove and return the head element.
1501
- * @remarks Time O(1), Space O(1)
1502
- * @returns Removed element or undefined.
1503
- */
1819
+ * Remove and return the head element.
1820
+ * @remarks Time O(1), Space O(1)
1821
+ * @returns Removed element or undefined.
1822
+
1823
+
1824
+
1825
+
1826
+
1827
+
1828
+
1829
+
1830
+
1831
+
1832
+
1833
+ * @example
1834
+ * // Remove from the front
1835
+ * const list = new DoublyLinkedList<number>([10, 20, 30]);
1836
+ * console.log(list.shift()); // 10;
1837
+ * console.log(list.first); // 20;
1838
+ */
1504
1839
  shift() {
1505
1840
  if (!this.head) return void 0;
1506
1841
  const removed = this.head;
@@ -1515,11 +1850,27 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1515
1850
  return removed.value;
1516
1851
  }
1517
1852
  /**
1518
- * Prepend an element/node to the head.
1519
- * @remarks Time O(1), Space O(1)
1520
- * @param elementOrNode - Element or node to prepend.
1521
- * @returns True when prepended.
1522
- */
1853
+ * Prepend an element/node to the head.
1854
+ * @remarks Time O(1), Space O(1)
1855
+ * @param elementOrNode - Element or node to prepend.
1856
+ * @returns True when prepended.
1857
+
1858
+
1859
+
1860
+
1861
+
1862
+
1863
+
1864
+
1865
+
1866
+
1867
+
1868
+ * @example
1869
+ * // Add to the front
1870
+ * const list = new DoublyLinkedList<number>([2, 3]);
1871
+ * list.unshift(1);
1872
+ * console.log([...list]); // [1, 2, 3];
1873
+ */
1523
1874
  unshift(elementOrNode) {
1524
1875
  const newNode = this._ensureNode(elementOrNode);
1525
1876
  if (!this.head) {
@@ -1563,11 +1914,27 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1563
1914
  return ans;
1564
1915
  }
1565
1916
  /**
1566
- * Get the element at a given index.
1567
- * @remarks Time O(N), Space O(1)
1568
- * @param index - Zero-based index.
1569
- * @returns Element or undefined.
1570
- */
1917
+ * Get the element at a given index.
1918
+ * @remarks Time O(N), Space O(1)
1919
+ * @param index - Zero-based index.
1920
+ * @returns Element or undefined.
1921
+
1922
+
1923
+
1924
+
1925
+
1926
+
1927
+
1928
+
1929
+
1930
+
1931
+
1932
+ * @example
1933
+ * // Access by index
1934
+ * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
1935
+ * console.log(list.at(1)); // 'b';
1936
+ * console.log(list.at(2)); // 'c';
1937
+ */
1571
1938
  at(index) {
1572
1939
  if (index < 0 || index >= this._length) return void 0;
1573
1940
  let current = this.head;
@@ -1575,11 +1942,23 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1575
1942
  return current?.value;
1576
1943
  }
1577
1944
  /**
1578
- * Get the node reference at a given index.
1579
- * @remarks Time O(N), Space O(1)
1580
- * @param index - Zero-based index.
1581
- * @returns Node or undefined.
1582
- */
1945
+ * Get the node reference at a given index.
1946
+ * @remarks Time O(N), Space O(1)
1947
+ * @param index - Zero-based index.
1948
+ * @returns Node or undefined.
1949
+
1950
+
1951
+
1952
+
1953
+
1954
+
1955
+
1956
+
1957
+ * @example
1958
+ * // Get node at index
1959
+ * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
1960
+ * console.log(list.getNodeAt(1)?.value); // 'b';
1961
+ */
1583
1962
  getNodeAt(index) {
1584
1963
  if (index < 0 || index >= this._length) return void 0;
1585
1964
  let current = this.head;
@@ -1618,12 +1997,25 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1618
1997
  return void 0;
1619
1998
  }
1620
1999
  /**
1621
- * Insert a new element/node at an index, shifting following nodes.
1622
- * @remarks Time O(N), Space O(1)
1623
- * @param index - Zero-based index.
1624
- * @param newElementOrNode - Element or node to insert.
1625
- * @returns True if inserted.
1626
- */
2000
+ * Insert a new element/node at an index, shifting following nodes.
2001
+ * @remarks Time O(N), Space O(1)
2002
+ * @param index - Zero-based index.
2003
+ * @param newElementOrNode - Element or node to insert.
2004
+ * @returns True if inserted.
2005
+
2006
+
2007
+
2008
+
2009
+
2010
+
2011
+
2012
+
2013
+ * @example
2014
+ * // Insert at position
2015
+ * const list = new DoublyLinkedList<number>([1, 3]);
2016
+ * list.addAt(1, 2);
2017
+ * console.log(list.toArray()); // [1, 2, 3];
2018
+ */
1627
2019
  addAt(index, newElementOrNode) {
1628
2020
  if (index < 0 || index > this._length) return false;
1629
2021
  if (index === 0) return this.unshift(newElementOrNode);
@@ -1690,11 +2082,24 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1690
2082
  return true;
1691
2083
  }
1692
2084
  /**
1693
- * Delete the element at an index.
1694
- * @remarks Time O(N), Space O(1)
1695
- * @param index - Zero-based index.
1696
- * @returns Removed element or undefined.
1697
- */
2085
+ * Delete the element at an index.
2086
+ * @remarks Time O(N), Space O(1)
2087
+ * @param index - Zero-based index.
2088
+ * @returns Removed element or undefined.
2089
+
2090
+
2091
+
2092
+
2093
+
2094
+
2095
+
2096
+
2097
+ * @example
2098
+ * // Remove by index
2099
+ * const list = new DoublyLinkedList<string>(['a', 'b', 'c']);
2100
+ * list.deleteAt(1);
2101
+ * console.log(list.toArray()); // ['a', 'c'];
2102
+ */
1698
2103
  deleteAt(index) {
1699
2104
  if (index < 0 || index >= this._length) return;
1700
2105
  if (index === 0) return this.shift();
@@ -1708,11 +2113,24 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1708
2113
  return removedNode.value;
1709
2114
  }
1710
2115
  /**
1711
- * Delete the first match by value/node.
1712
- * @remarks Time O(N), Space O(1)
1713
- * @param [elementOrNode] - Element or node to remove.
1714
- * @returns True if removed.
1715
- */
2116
+ * Delete the first match by value/node.
2117
+ * @remarks Time O(N), Space O(1)
2118
+ * @param [elementOrNode] - Element or node to remove.
2119
+ * @returns True if removed.
2120
+
2121
+
2122
+
2123
+
2124
+
2125
+
2126
+
2127
+
2128
+ * @example
2129
+ * // Remove first occurrence
2130
+ * const list = new DoublyLinkedList<number>([1, 2, 3, 2]);
2131
+ * list.delete(2);
2132
+ * console.log(list.toArray()); // [1, 3, 2];
2133
+ */
1716
2134
  delete(elementOrNode) {
1717
2135
  const node = this.getNode(elementOrNode);
1718
2136
  if (!node) return false;
@@ -1728,29 +2146,68 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1728
2146
  return true;
1729
2147
  }
1730
2148
  /**
1731
- * Check whether the list is empty.
1732
- * @remarks Time O(1), Space O(1)
1733
- * @returns True if length is 0.
1734
- */
2149
+ * Check whether the list is empty.
2150
+ * @remarks Time O(1), Space O(1)
2151
+ * @returns True if length is 0.
2152
+
2153
+
2154
+
2155
+
2156
+
2157
+
2158
+
2159
+
2160
+
2161
+ * @example
2162
+ * // Check empty
2163
+ * console.log(new DoublyLinkedList().isEmpty()); // true;
2164
+ */
1735
2165
  isEmpty() {
1736
2166
  return this._length === 0;
1737
2167
  }
1738
2168
  /**
1739
- * Remove all nodes and reset length.
1740
- * @remarks Time O(N), Space O(1)
1741
- * @returns void
1742
- */
2169
+ * Remove all nodes and reset length.
2170
+ * @remarks Time O(N), Space O(1)
2171
+ * @returns void
2172
+
2173
+
2174
+
2175
+
2176
+
2177
+
2178
+
2179
+
2180
+
2181
+ * @example
2182
+ * // Remove all
2183
+ * const list = new DoublyLinkedList<number>([1, 2]);
2184
+ * list.clear();
2185
+ * console.log(list.isEmpty()); // true;
2186
+ */
1743
2187
  clear() {
1744
2188
  this._head = void 0;
1745
2189
  this._tail = void 0;
1746
2190
  this._length = 0;
1747
2191
  }
1748
2192
  /**
1749
- * Find the first value matching a predicate scanning forward.
1750
- * @remarks Time O(N), Space O(1)
1751
- * @param elementNodeOrPredicate - Element, node, or predicate to match.
1752
- * @returns Matched value or undefined.
1753
- */
2193
+ * Find the first value matching a predicate scanning forward.
2194
+ * @remarks Time O(N), Space O(1)
2195
+ * @param elementNodeOrPredicate - Element, node, or predicate to match.
2196
+ * @returns Matched value or undefined.
2197
+
2198
+
2199
+
2200
+
2201
+
2202
+
2203
+
2204
+
2205
+ * @example
2206
+ * // Search with predicate
2207
+ * const list = new DoublyLinkedList<number>([10, 20, 30]);
2208
+ * const found = list.search(node => node.value > 15);
2209
+ * console.log(found); // 20;
2210
+ */
1754
2211
  search(elementNodeOrPredicate) {
1755
2212
  const predicate = this._ensurePredicate(elementNodeOrPredicate);
1756
2213
  let current = this.head;
@@ -1761,11 +2218,25 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1761
2218
  return void 0;
1762
2219
  }
1763
2220
  /**
1764
- * Find the first value matching a predicate scanning backward.
1765
- * @remarks Time O(N), Space O(1)
1766
- * @param elementNodeOrPredicate - Element, node, or predicate to match.
1767
- * @returns Matched value or undefined.
1768
- */
2221
+ * Find the first value matching a predicate scanning backward.
2222
+ * @remarks Time O(N), Space O(1)
2223
+ * @param elementNodeOrPredicate - Element, node, or predicate to match.
2224
+ * @returns Matched value or undefined.
2225
+
2226
+
2227
+
2228
+
2229
+
2230
+
2231
+
2232
+
2233
+ * @example
2234
+ * // Find value scanning from tail
2235
+ * const list = new DoublyLinkedList<number>([1, 2, 3, 4]);
2236
+ * // getBackward scans from tail to head, returns first match
2237
+ * const found = list.getBackward(node => node.value < 4);
2238
+ * console.log(found); // 3;
2239
+ */
1769
2240
  getBackward(elementNodeOrPredicate) {
1770
2241
  const predicate = this._ensurePredicate(elementNodeOrPredicate);
1771
2242
  let current = this.tail;
@@ -1776,10 +2247,26 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1776
2247
  return void 0;
1777
2248
  }
1778
2249
  /**
1779
- * Reverse the list in place.
1780
- * @remarks Time O(N), Space O(1)
1781
- * @returns This list.
1782
- */
2250
+ * Reverse the list in place.
2251
+ * @remarks Time O(N), Space O(1)
2252
+ * @returns This list.
2253
+
2254
+
2255
+
2256
+
2257
+
2258
+
2259
+
2260
+
2261
+
2262
+
2263
+
2264
+ * @example
2265
+ * // Reverse in-place
2266
+ * const list = new DoublyLinkedList<number>([1, 2, 3]);
2267
+ * list.reverse();
2268
+ * console.log([...list]); // [3, 2, 1];
2269
+ */
1783
2270
  reverse() {
1784
2271
  let current = this.head;
1785
2272
  [this._head, this._tail] = [this.tail, this.head];
@@ -1801,22 +2288,53 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1801
2288
  return this;
1802
2289
  }
1803
2290
  /**
1804
- * Deep clone this list (values are copied by reference).
1805
- * @remarks Time O(N), Space O(N)
1806
- * @returns A new list with the same element sequence.
1807
- */
2291
+ * Deep clone this list (values are copied by reference).
2292
+ * @remarks Time O(N), Space O(N)
2293
+ * @returns A new list with the same element sequence.
2294
+
2295
+
2296
+
2297
+
2298
+
2299
+
2300
+
2301
+
2302
+
2303
+ * @example
2304
+ * // Deep copy
2305
+ * const list = new DoublyLinkedList<number>([1, 2, 3]);
2306
+ * const copy = list.clone();
2307
+ * copy.pop();
2308
+ * console.log(list.length); // 3;
2309
+ */
1808
2310
  clone() {
1809
2311
  const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1810
2312
  for (const v of this) out.push(v);
1811
2313
  return out;
1812
2314
  }
1813
2315
  /**
1814
- * Filter values into a new list of the same class.
1815
- * @remarks Time O(N), Space O(N)
1816
- * @param callback - Predicate (value, index, list) → boolean to keep value.
1817
- * @param [thisArg] - Value for `this` inside the callback.
1818
- * @returns A new list with kept values.
1819
- */
2316
+ * Filter values into a new list of the same class.
2317
+ * @remarks Time O(N), Space O(N)
2318
+ * @param callback - Predicate (value, index, list) → boolean to keep value.
2319
+ * @param [thisArg] - Value for `this` inside the callback.
2320
+ * @returns A new list with kept values.
2321
+
2322
+
2323
+
2324
+
2325
+
2326
+
2327
+
2328
+
2329
+
2330
+
2331
+
2332
+ * @example
2333
+ * // Filter elements
2334
+ * const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
2335
+ * const evens = list.filter(n => n % 2 === 0);
2336
+ * console.log([...evens]); // [2, 4];
2337
+ */
1820
2338
  filter(callback, thisArg) {
1821
2339
  const out = this._createInstance({ toElementFn: this._toElementFn, maxLen: this._maxLen });
1822
2340
  let index = 0;
@@ -1840,15 +2358,40 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1840
2358
  return out;
1841
2359
  }
1842
2360
  /**
1843
- * Map values into a new list (possibly different element type).
1844
- * @remarks Time O(N), Space O(N)
1845
- * @template EM
1846
- * @template RM
1847
- * @param callback - Mapping function (value, index, list) → newElement.
1848
- * @param [options] - Options for the output list (e.g., maxLen, toElementFn).
1849
- * @param [thisArg] - Value for `this` inside the callback.
1850
- * @returns A new DoublyLinkedList with mapped values.
1851
- */
2361
+ * Map values into a new list (possibly different element type).
2362
+ * @remarks Time O(N), Space O(N)
2363
+ * @template EM
2364
+ * @template RM
2365
+ * @param callback - Mapping function (value, index, list) → newElement.
2366
+ * @param [options] - Options for the output list (e.g., maxLen, toElementFn).
2367
+ * @param [thisArg] - Value for `this` inside the callback.
2368
+ * @returns A new DoublyLinkedList with mapped values.
2369
+
2370
+
2371
+
2372
+
2373
+
2374
+
2375
+
2376
+
2377
+
2378
+
2379
+
2380
+ * @example
2381
+ * // DoublyLinkedList for...of iteration and map operation
2382
+ * const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);
2383
+ *
2384
+ * // Iterate through list
2385
+ * const doubled = list.map(value => value * 2);
2386
+ * console.log(doubled.length); // 5;
2387
+ *
2388
+ * // Use for...of loop
2389
+ * const result: number[] = [];
2390
+ * for (const item of list) {
2391
+ * result.push(item);
2392
+ * }
2393
+ * console.log(result); // [1, 2, 3, 4, 5];
2394
+ */
1852
2395
  map(callback, options, thisArg) {
1853
2396
  const out = this._createLike([], { ...options ?? {}, maxLen: this._maxLen });
1854
2397
  let index = 0;
@@ -1937,6 +2480,237 @@ var DoublyLinkedList = class extends LinearLinkedBase {
1937
2480
  }
1938
2481
  };
1939
2482
 
2483
+ // src/common/error.ts
2484
+ var ERR = {
2485
+ // Range / index
2486
+ indexOutOfRange: /* @__PURE__ */ __name((index, min, max, ctx) => `${ctx ? ctx + ": " : ""}Index ${index} is out of range [${min}, ${max}].`, "indexOutOfRange"),
2487
+ invalidIndex: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Index must be an integer.`, "invalidIndex"),
2488
+ // Type / argument
2489
+ invalidArgument: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidArgument"),
2490
+ comparatorRequired: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Comparator is required for non-number/non-string/non-Date keys.`, "comparatorRequired"),
2491
+ invalidKey: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidKey"),
2492
+ notAFunction: /* @__PURE__ */ __name((name, ctx) => `${ctx ? ctx + ": " : ""}${name} must be a function.`, "notAFunction"),
2493
+ invalidEntry: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Each entry must be a [key, value] tuple.`, "invalidEntry"),
2494
+ invalidNaN: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}NaN is not a valid key.`, "invalidNaN"),
2495
+ invalidDate: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Invalid Date key.`, "invalidDate"),
2496
+ reduceEmpty: /* @__PURE__ */ __name((ctx) => `${ctx ? ctx + ": " : ""}Reduce of empty structure with no initial value.`, "reduceEmpty"),
2497
+ callbackReturnType: /* @__PURE__ */ __name((expected, got, ctx) => `${ctx ? ctx + ": " : ""}Callback must return ${expected}; got ${got}.`, "callbackReturnType"),
2498
+ // State / operation
2499
+ invalidOperation: /* @__PURE__ */ __name((reason, ctx) => `${ctx ? ctx + ": " : ""}${reason}`, "invalidOperation"),
2500
+ // Matrix
2501
+ matrixDimensionMismatch: /* @__PURE__ */ __name((op) => `Matrix: Dimensions must be compatible for ${op}.`, "matrixDimensionMismatch"),
2502
+ matrixSingular: /* @__PURE__ */ __name(() => "Matrix: Singular matrix, inverse does not exist.", "matrixSingular"),
2503
+ matrixNotSquare: /* @__PURE__ */ __name(() => "Matrix: Must be square for inversion.", "matrixNotSquare"),
2504
+ matrixNotRectangular: /* @__PURE__ */ __name(() => "Matrix: Must be rectangular for transposition.", "matrixNotRectangular"),
2505
+ matrixRowMismatch: /* @__PURE__ */ __name((expected, got) => `Matrix: Expected row length ${expected}, but got ${got}.`, "matrixRowMismatch")
2506
+ };
2507
+
2508
+ // src/common/index.ts
2509
+ var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
2510
+ DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
2511
+ DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
2512
+ return DFSOperation2;
2513
+ })(DFSOperation || {});
2514
+ var Range = class {
2515
+ constructor(low, high, includeLow = true, includeHigh = true) {
2516
+ this.low = low;
2517
+ this.high = high;
2518
+ this.includeLow = includeLow;
2519
+ this.includeHigh = includeHigh;
2520
+ }
2521
+ static {
2522
+ __name(this, "Range");
2523
+ }
2524
+ // Determine whether a key is within the range
2525
+ isInRange(key, comparator) {
2526
+ const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
2527
+ const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
2528
+ return lowCheck && highCheck;
2529
+ }
2530
+ };
2531
+
2532
+ // src/data-structures/base/iterable-entry-base.ts
2533
+ var IterableEntryBase = class {
2534
+ static {
2535
+ __name(this, "IterableEntryBase");
2536
+ }
2537
+ /**
2538
+ * Default iterator yielding `[key, value]` entries.
2539
+ * @returns Iterator of `[K, V]`.
2540
+ * @remarks Time O(n) to iterate, Space O(1)
2541
+ */
2542
+ *[Symbol.iterator](...args) {
2543
+ yield* this._getIterator(...args);
2544
+ }
2545
+ /**
2546
+ * Iterate over `[key, value]` pairs (may yield `undefined` values).
2547
+ * @returns Iterator of `[K, V | undefined]`.
2548
+ * @remarks Time O(n), Space O(1)
2549
+ */
2550
+ *entries() {
2551
+ for (const item of this) {
2552
+ yield item;
2553
+ }
2554
+ }
2555
+ /**
2556
+ * Iterate over keys only.
2557
+ * @returns Iterator of keys.
2558
+ * @remarks Time O(n), Space O(1)
2559
+ */
2560
+ *keys() {
2561
+ for (const item of this) {
2562
+ yield item[0];
2563
+ }
2564
+ }
2565
+ /**
2566
+ * Iterate over values only.
2567
+ * @returns Iterator of values.
2568
+ * @remarks Time O(n), Space O(1)
2569
+ */
2570
+ *values() {
2571
+ for (const item of this) {
2572
+ yield item[1];
2573
+ }
2574
+ }
2575
+ /**
2576
+ * Test whether all entries satisfy the predicate.
2577
+ * @param predicate - `(key, value, index, self) => boolean`.
2578
+ * @param thisArg - Optional `this` for callback.
2579
+ * @returns `true` if all pass; otherwise `false`.
2580
+ * @remarks Time O(n), Space O(1)
2581
+ */
2582
+ every(predicate, thisArg) {
2583
+ let index = 0;
2584
+ for (const item of this) {
2585
+ if (!predicate.call(thisArg, item[1], item[0], index++, this)) {
2586
+ return false;
2587
+ }
2588
+ }
2589
+ return true;
2590
+ }
2591
+ /**
2592
+ * Test whether any entry satisfies the predicate.
2593
+ * @param predicate - `(key, value, index, self) => boolean`.
2594
+ * @param thisArg - Optional `this` for callback.
2595
+ * @returns `true` if any passes; otherwise `false`.
2596
+ * @remarks Time O(n), Space O(1)
2597
+ */
2598
+ some(predicate, thisArg) {
2599
+ let index = 0;
2600
+ for (const item of this) {
2601
+ if (predicate.call(thisArg, item[1], item[0], index++, this)) {
2602
+ return true;
2603
+ }
2604
+ }
2605
+ return false;
2606
+ }
2607
+ /**
2608
+ * Visit each entry, left-to-right.
2609
+ * @param callbackfn - `(key, value, index, self) => void`.
2610
+ * @param thisArg - Optional `this` for callback.
2611
+ * @remarks Time O(n), Space O(1)
2612
+ */
2613
+ forEach(callbackfn, thisArg) {
2614
+ let index = 0;
2615
+ for (const item of this) {
2616
+ const [key, value] = item;
2617
+ callbackfn.call(thisArg, value, key, index++, this);
2618
+ }
2619
+ }
2620
+ /**
2621
+ * Find the first entry that matches a predicate.
2622
+ * @param callbackfn - `(key, value, index, self) => boolean`.
2623
+ * @param thisArg - Optional `this` for callback.
2624
+ * @returns Matching `[key, value]` or `undefined`.
2625
+ * @remarks Time O(n), Space O(1)
2626
+ */
2627
+ find(callbackfn, thisArg) {
2628
+ let index = 0;
2629
+ for (const item of this) {
2630
+ const [key, value] = item;
2631
+ if (callbackfn.call(thisArg, value, key, index++, this)) return item;
2632
+ }
2633
+ return;
2634
+ }
2635
+ /**
2636
+ * Whether the given key exists.
2637
+ * @param key - Key to test.
2638
+ * @returns `true` if found; otherwise `false`.
2639
+ * @remarks Time O(n) generic, Space O(1)
2640
+ */
2641
+ has(key) {
2642
+ for (const item of this) {
2643
+ const [itemKey] = item;
2644
+ if (itemKey === key) return true;
2645
+ }
2646
+ return false;
2647
+ }
2648
+ /**
2649
+ * Whether there exists an entry with the given value.
2650
+ * @param value - Value to test.
2651
+ * @returns `true` if found; otherwise `false`.
2652
+ * @remarks Time O(n), Space O(1)
2653
+ */
2654
+ hasValue(value) {
2655
+ for (const [, elementValue] of this) {
2656
+ if (elementValue === value) return true;
2657
+ }
2658
+ return false;
2659
+ }
2660
+ /**
2661
+ * Get the value under a key.
2662
+ * @param key - Key to look up.
2663
+ * @returns Value or `undefined`.
2664
+ * @remarks Time O(n) generic, Space O(1)
2665
+ */
2666
+ get(key) {
2667
+ for (const item of this) {
2668
+ const [itemKey, value] = item;
2669
+ if (itemKey === key) return value;
2670
+ }
2671
+ return;
2672
+ }
2673
+ /**
2674
+ * Reduce entries into a single accumulator.
2675
+ * @param callbackfn - `(acc, value, key, index, self) => acc`.
2676
+ * @param initialValue - Initial accumulator.
2677
+ * @returns Final accumulator.
2678
+ * @remarks Time O(n), Space O(1)
2679
+ */
2680
+ reduce(callbackfn, initialValue) {
2681
+ let accumulator = initialValue;
2682
+ let index = 0;
2683
+ for (const item of this) {
2684
+ const [key, value] = item;
2685
+ accumulator = callbackfn(accumulator, value, key, index++, this);
2686
+ }
2687
+ return accumulator;
2688
+ }
2689
+ /**
2690
+ * Converts data structure to `[key, value]` pairs.
2691
+ * @returns Array of entries.
2692
+ * @remarks Time O(n), Space O(n)
2693
+ */
2694
+ toArray() {
2695
+ return [...this];
2696
+ }
2697
+ /**
2698
+ * Visualize the iterable as an array of `[key, value]` pairs (or a custom string).
2699
+ * @returns Array of entries (default) or a string.
2700
+ * @remarks Time O(n), Space O(n)
2701
+ */
2702
+ toVisual() {
2703
+ return [...this];
2704
+ }
2705
+ /**
2706
+ * Print a human-friendly representation to the console.
2707
+ * @remarks Time O(n), Space O(n)
2708
+ */
2709
+ print() {
2710
+ console.log(this.toVisual());
2711
+ }
2712
+ };
2713
+
1940
2714
  // src/data-structures/linked-list/skip-linked-list.ts
1941
2715
  var SkipListNode = class {
1942
2716
  static {
@@ -1948,165 +2722,660 @@ var SkipListNode = class {
1948
2722
  constructor(key, value, level) {
1949
2723
  this.key = key;
1950
2724
  this.value = value;
1951
- this.forward = new Array(level);
2725
+ this.forward = new Array(level).fill(void 0);
1952
2726
  }
1953
2727
  };
1954
- var SkipList = class {
2728
+ var SkipList = class _SkipList extends IterableEntryBase {
1955
2729
  static {
1956
2730
  __name(this, "SkipList");
1957
2731
  }
1958
- constructor(elements = [], options) {
1959
- if (options) {
1960
- const { maxLevel, probability } = options;
1961
- if (typeof maxLevel === "number") this._maxLevel = maxLevel;
1962
- if (typeof probability === "number") this._probability = probability;
1963
- }
1964
- if (elements) {
1965
- for (const [key, value] of elements) this.add(key, value);
2732
+ #comparator;
2733
+ #isDefaultComparator;
2734
+ constructor(entries = [], options = {}) {
2735
+ super();
2736
+ const { comparator, toEntryFn, maxLevel, probability } = options;
2737
+ if (typeof maxLevel === "number" && maxLevel > 0) this._maxLevel = maxLevel;
2738
+ if (typeof probability === "number" && probability > 0 && probability < 1) this._probability = probability;
2739
+ this.#isDefaultComparator = comparator === void 0;
2740
+ this.#comparator = comparator ?? _SkipList.createDefaultComparator();
2741
+ this._head = new SkipListNode(void 0, void 0, this._maxLevel);
2742
+ for (const item of entries) {
2743
+ let k;
2744
+ let v;
2745
+ if (toEntryFn) {
2746
+ [k, v] = toEntryFn(item);
2747
+ } else {
2748
+ if (!Array.isArray(item) || item.length < 2) {
2749
+ throw new TypeError(ERR.invalidEntry("SkipList"));
2750
+ }
2751
+ [k, v] = item;
2752
+ }
2753
+ this.set(k, v);
1966
2754
  }
1967
2755
  }
1968
- _head = new SkipListNode(void 0, void 0, this.maxLevel);
1969
- get head() {
1970
- return this._head;
2756
+ /**
2757
+ * Creates a default comparator supporting number, string, Date, and bigint.
2758
+ */
2759
+ static createDefaultComparator() {
2760
+ return (a, b) => {
2761
+ if (typeof a === "number" && typeof b === "number") {
2762
+ if (Number.isNaN(a) || Number.isNaN(b)) throw new TypeError(ERR.invalidNaN("SkipList"));
2763
+ return a - b;
2764
+ }
2765
+ if (typeof a === "string" && typeof b === "string") {
2766
+ return a < b ? -1 : a > b ? 1 : 0;
2767
+ }
2768
+ if (a instanceof Date && b instanceof Date) {
2769
+ const ta = a.getTime(), tb = b.getTime();
2770
+ if (Number.isNaN(ta) || Number.isNaN(tb)) throw new TypeError(ERR.invalidDate("SkipList"));
2771
+ return ta - tb;
2772
+ }
2773
+ if (typeof a === "bigint" && typeof b === "bigint") {
2774
+ return a < b ? -1 : a > b ? 1 : 0;
2775
+ }
2776
+ throw new TypeError(ERR.comparatorRequired("SkipList"));
2777
+ };
1971
2778
  }
2779
+ // ─── Internal state ──────────────────────────────────────────
2780
+ _head;
1972
2781
  _level = 0;
1973
- get level() {
1974
- return this._level;
1975
- }
2782
+ _size = 0;
1976
2783
  _maxLevel = 16;
2784
+ _probability = 0.5;
2785
+ // ─── Size & lifecycle ────────────────────────────────────────
2786
+ get size() {
2787
+ return this._size;
2788
+ }
1977
2789
  get maxLevel() {
1978
2790
  return this._maxLevel;
1979
2791
  }
1980
- _probability = 0.5;
1981
2792
  get probability() {
1982
2793
  return this._probability;
1983
2794
  }
1984
- get first() {
1985
- const firstNode = this.head.forward[0];
1986
- return firstNode ? firstNode.value : void 0;
2795
+ get comparator() {
2796
+ return this.#comparator;
2797
+ }
2798
+ /**
2799
+ * Check if empty
2800
+
2801
+
2802
+
2803
+
2804
+
2805
+
2806
+
2807
+
2808
+ * @example
2809
+ * // Check if empty
2810
+ * const sl = new SkipList<number, string>();
2811
+ * console.log(sl.isEmpty()); // true;
2812
+ */
2813
+ isEmpty() {
2814
+ return this._size === 0;
2815
+ }
2816
+ /**
2817
+ * Remove all entries
2818
+
2819
+
2820
+
2821
+
2822
+
2823
+
2824
+
2825
+
2826
+ * @example
2827
+ * // Remove all entries
2828
+ * const sl = new SkipList<number, string>([[1, 'a'], [2, 'b']]);
2829
+ * sl.clear();
2830
+ * console.log(sl.isEmpty()); // true;
2831
+ */
2832
+ clear() {
2833
+ this._head = new SkipListNode(void 0, void 0, this._maxLevel);
2834
+ this._level = 0;
2835
+ this._size = 0;
2836
+ }
2837
+ /**
2838
+ * Create independent copy
2839
+
2840
+
2841
+
2842
+
2843
+
2844
+
2845
+
2846
+
2847
+ * @example
2848
+ * // Create independent copy
2849
+ * const sl = new SkipList<number, string>([[1, 'a'], [2, 'b']]);
2850
+ * const copy = sl.clone();
2851
+ * copy.delete(1);
2852
+ * console.log(sl.has(1)); // true;
2853
+ */
2854
+ clone() {
2855
+ return new _SkipList(this, {
2856
+ comparator: this.#isDefaultComparator ? void 0 : this.#comparator,
2857
+ maxLevel: this._maxLevel,
2858
+ probability: this._probability
2859
+ });
2860
+ }
2861
+ // ─── Core CRUD ───────────────────────────────────────────────
2862
+ /**
2863
+ * Insert or update a key-value pair. Returns `this` for chaining.
2864
+ * Unique keys only — if key exists, value is updated in place.
2865
+
2866
+
2867
+
2868
+
2869
+
2870
+
2871
+
2872
+
2873
+
2874
+
2875
+
2876
+ * @example
2877
+ * // In-memory sorted key-value store
2878
+ * const store = new SkipList<number, string>();
2879
+ *
2880
+ * store.set(3, 'three');
2881
+ * store.set(1, 'one');
2882
+ * store.set(5, 'five');
2883
+ * store.set(2, 'two');
2884
+ *
2885
+ * console.log(store.get(3)); // 'three';
2886
+ * console.log(store.get(1)); // 'one';
2887
+ * console.log(store.get(5)); // 'five';
2888
+ *
2889
+ * // Update existing key
2890
+ * store.set(3, 'THREE');
2891
+ * console.log(store.get(3)); // 'THREE';
2892
+ */
2893
+ set(key, value) {
2894
+ const cmp = this.#comparator;
2895
+ const update = this._findUpdate(key);
2896
+ const existing = update[0].forward[0];
2897
+ if (existing && cmp(existing.key, key) === 0) {
2898
+ existing.value = value;
2899
+ return this;
2900
+ }
2901
+ const newLevel = this._randomLevel();
2902
+ const newNode = new SkipListNode(key, value, newLevel);
2903
+ if (newLevel > this._level) {
2904
+ for (let i = this._level; i < newLevel; i++) {
2905
+ update[i] = this._head;
2906
+ }
2907
+ this._level = newLevel;
2908
+ }
2909
+ for (let i = 0; i < newLevel; i++) {
2910
+ newNode.forward[i] = update[i].forward[i];
2911
+ update[i].forward[i] = newNode;
2912
+ }
2913
+ this._size++;
2914
+ return this;
1987
2915
  }
1988
- get last() {
1989
- let current = this.head;
1990
- for (let i = this.level - 1; i >= 0; i--) {
2916
+ /**
2917
+ * Get the value for a key, or `undefined` if not found.
2918
+ * Overrides base O(n) with O(log n) skip-list search.
2919
+
2920
+
2921
+
2922
+
2923
+
2924
+
2925
+
2926
+
2927
+
2928
+
2929
+
2930
+ * @example
2931
+ * // Building a sorted index
2932
+ * type Product = { id: number; name: string; price: number };
2933
+ * const products: Product[] = [
2934
+ * { id: 1, name: 'Widget', price: 25 },
2935
+ * { id: 2, name: 'Gadget', price: 50 },
2936
+ * { id: 3, name: 'Doohickey', price: 15 }
2937
+ * ];
2938
+ *
2939
+ * const index = new SkipList<number, Product>(products as any, {
2940
+ * toEntryFn: (p: any) => [p.price, p]
2941
+ * });
2942
+ *
2943
+ * // Iterate in sorted order by price
2944
+ * const names = [...index.values()].map(p => p!.name);
2945
+ * console.log(names); // ['Doohickey', 'Widget', 'Gadget'];
2946
+ *
2947
+ * // Range search: products between $20 and $60
2948
+ * const range = index.rangeSearch([20, 60]);
2949
+ * console.log(range.map(([, p]) => p!.name)); // ['Widget', 'Gadget'];
2950
+ */
2951
+ get(key) {
2952
+ const node = this._findNode(key);
2953
+ return node ? node.value : void 0;
2954
+ }
2955
+ /**
2956
+ * Check if a key exists.
2957
+ * Overrides base O(n) with O(log n) skip-list search.
2958
+
2959
+
2960
+
2961
+
2962
+
2963
+
2964
+
2965
+
2966
+
2967
+
2968
+
2969
+ * @example
2970
+ * // Check key existence
2971
+ * const sl = new SkipList<number, string>([[1, 'a'], [3, 'c'], [5, 'e']]);
2972
+ * console.log(sl.has(3)); // true;
2973
+ * console.log(sl.has(4)); // false;
2974
+ */
2975
+ has(key) {
2976
+ return this._findNode(key) !== void 0;
2977
+ }
2978
+ /**
2979
+ * Delete a key. Returns `true` if the key was found and removed.
2980
+
2981
+
2982
+
2983
+
2984
+
2985
+
2986
+
2987
+
2988
+
2989
+
2990
+
2991
+ * @example
2992
+ * // Fast lookup with deletion
2993
+ * const cache = new SkipList<string, number>();
2994
+ *
2995
+ * cache.set('alpha', 1);
2996
+ * cache.set('beta', 2);
2997
+ * cache.set('gamma', 3);
2998
+ *
2999
+ * console.log(cache.has('beta')); // true;
3000
+ * cache.delete('beta');
3001
+ * console.log(cache.has('beta')); // false;
3002
+ * console.log(cache.size); // 2;
3003
+ */
3004
+ delete(key) {
3005
+ const cmp = this.#comparator;
3006
+ const update = this._findUpdate(key);
3007
+ const target = update[0].forward[0];
3008
+ if (!target || cmp(target.key, key) !== 0) return false;
3009
+ for (let i = 0; i < this._level; i++) {
3010
+ if (update[i].forward[i] !== target) break;
3011
+ update[i].forward[i] = target.forward[i];
3012
+ }
3013
+ while (this._level > 0 && !this._head.forward[this._level - 1]) {
3014
+ this._level--;
3015
+ }
3016
+ this._size--;
3017
+ return true;
3018
+ }
3019
+ // ─── Navigation ──────────────────────────────────────────────
3020
+ /**
3021
+ * Returns the first (smallest key) entry, or `undefined` if empty.
3022
+
3023
+
3024
+
3025
+
3026
+
3027
+
3028
+
3029
+
3030
+
3031
+
3032
+
3033
+ * @example
3034
+ * // Access the minimum entry
3035
+ * const sl = new SkipList<number, string>([[5, 'e'], [1, 'a'], [3, 'c']]);
3036
+ * console.log(sl.first()); // [1, 'a'];
3037
+ */
3038
+ first() {
3039
+ const node = this._head.forward[0];
3040
+ return node ? [node.key, node.value] : void 0;
3041
+ }
3042
+ /**
3043
+ * Returns the last (largest key) entry, or `undefined` if empty.
3044
+
3045
+
3046
+
3047
+
3048
+
3049
+
3050
+
3051
+
3052
+
3053
+
3054
+
3055
+ * @example
3056
+ * // Access the maximum entry
3057
+ * const sl = new SkipList<number, string>([[5, 'e'], [1, 'a'], [3, 'c']]);
3058
+ * console.log(sl.last()); // [5, 'e'];
3059
+ */
3060
+ last() {
3061
+ let current = this._head;
3062
+ for (let i = this._level - 1; i >= 0; i--) {
1991
3063
  while (current.forward[i]) {
1992
3064
  current = current.forward[i];
1993
3065
  }
1994
3066
  }
1995
- return current.value;
1996
- }
1997
- add(key, value) {
1998
- const newNode = new SkipListNode(key, value, this._randomLevel());
1999
- const update = new Array(this.maxLevel).fill(this.head);
2000
- let current = this.head;
2001
- for (let i = this.level - 1; i >= 0; i--) {
2002
- while (current.forward[i] && current.forward[i].key < key) {
3067
+ return current === this._head ? void 0 : [current.key, current.value];
3068
+ }
3069
+ /**
3070
+ * Remove and return the first (smallest key) entry.
3071
+
3072
+
3073
+
3074
+
3075
+
3076
+
3077
+
3078
+
3079
+ * @example
3080
+ * // Remove and return smallest
3081
+ * const sl = new SkipList<number, string>([[1, 'a'], [2, 'b'], [3, 'c']]);
3082
+ * console.log(sl.pollFirst()); // [1, 'a'];
3083
+ * console.log(sl.size); // 2;
3084
+ */
3085
+ pollFirst() {
3086
+ const entry = this.first();
3087
+ if (!entry) return void 0;
3088
+ this.delete(entry[0]);
3089
+ return entry;
3090
+ }
3091
+ /**
3092
+ * Remove and return the last (largest key) entry.
3093
+
3094
+
3095
+
3096
+
3097
+
3098
+
3099
+
3100
+
3101
+ * @example
3102
+ * // Remove and return largest
3103
+ * const sl = new SkipList<number, string>([[1, 'a'], [2, 'b'], [3, 'c']]);
3104
+ * console.log(sl.pollLast()); // [3, 'c'];
3105
+ * console.log(sl.size); // 2;
3106
+ */
3107
+ pollLast() {
3108
+ const entry = this.last();
3109
+ if (!entry) return void 0;
3110
+ this.delete(entry[0]);
3111
+ return entry;
3112
+ }
3113
+ /**
3114
+ * Least entry ≥ key, or `undefined`.
3115
+
3116
+
3117
+
3118
+
3119
+
3120
+
3121
+
3122
+
3123
+
3124
+
3125
+
3126
+ * @example
3127
+ * // Least entry ≥ key
3128
+ * const sl = new SkipList<number, string>([[10, 'a'], [20, 'b'], [30, 'c']]);
3129
+ * console.log(sl.ceiling(15)); // [20, 'b'];
3130
+ * console.log(sl.ceiling(20)); // [20, 'b'];
3131
+ */
3132
+ ceiling(key) {
3133
+ const cmp = this.#comparator;
3134
+ let current = this._head;
3135
+ for (let i = this._level - 1; i >= 0; i--) {
3136
+ while (current.forward[i] && cmp(current.forward[i].key, key) < 0) {
2003
3137
  current = current.forward[i];
2004
3138
  }
2005
- update[i] = current;
2006
- }
2007
- for (let i = 0; i < newNode.forward.length; i++) {
2008
- newNode.forward[i] = update[i].forward[i];
2009
- update[i].forward[i] = newNode;
2010
3139
  }
2011
- if (!newNode.forward[0]) {
2012
- this._level = Math.max(this.level, newNode.forward.length);
3140
+ const node = current.forward[0];
3141
+ return node ? [node.key, node.value] : void 0;
3142
+ }
3143
+ /**
3144
+ * Greatest entry ≤ key, or `undefined`.
3145
+
3146
+
3147
+
3148
+
3149
+
3150
+
3151
+
3152
+
3153
+
3154
+
3155
+
3156
+ * @example
3157
+ * // Greatest entry ≤ key
3158
+ * const sl = new SkipList<number, string>([[10, 'a'], [20, 'b'], [30, 'c']]);
3159
+ * console.log(sl.floor(25)); // [20, 'b'];
3160
+ * console.log(sl.floor(5)); // undefined;
3161
+ */
3162
+ floor(key) {
3163
+ const cmp = this.#comparator;
3164
+ let current = this._head;
3165
+ for (let i = this._level - 1; i >= 0; i--) {
3166
+ while (current.forward[i] && cmp(current.forward[i].key, key) <= 0) {
3167
+ current = current.forward[i];
3168
+ }
2013
3169
  }
3170
+ const result = current === this._head ? void 0 : current;
3171
+ if (result && cmp(result.key, key) <= 0) return [result.key, result.value];
3172
+ return void 0;
2014
3173
  }
2015
- get(key) {
2016
- let current = this.head;
2017
- for (let i = this.level - 1; i >= 0; i--) {
2018
- while (current.forward[i] && current.forward[i].key < key) {
3174
+ /**
3175
+ * Least entry strictly > key, or `undefined`.
3176
+
3177
+
3178
+
3179
+
3180
+
3181
+
3182
+
3183
+
3184
+ * @example
3185
+ * // Strictly greater entry
3186
+ * const sl = new SkipList<number, string>([[10, 'a'], [20, 'b'], [30, 'c']]);
3187
+ * console.log(sl.higher(15)); // [20, 'b'];
3188
+ * console.log(sl.higher(30)); // undefined;
3189
+ */
3190
+ higher(key) {
3191
+ const cmp = this.#comparator;
3192
+ let current = this._head;
3193
+ for (let i = this._level - 1; i >= 0; i--) {
3194
+ while (current.forward[i] && cmp(current.forward[i].key, key) <= 0) {
2019
3195
  current = current.forward[i];
2020
3196
  }
2021
3197
  }
2022
- current = current.forward[0];
2023
- if (current && current.key === key) {
2024
- return current.value;
3198
+ const node = current.forward[0];
3199
+ return node ? [node.key, node.value] : void 0;
3200
+ }
3201
+ /**
3202
+ * Greatest entry strictly < key, or `undefined`.
3203
+
3204
+
3205
+
3206
+
3207
+
3208
+
3209
+
3210
+
3211
+ * @example
3212
+ * // Strictly less entry
3213
+ * const sl = new SkipList<number, string>([[10, 'a'], [20, 'b'], [30, 'c']]);
3214
+ * console.log(sl.lower(25)); // [20, 'b'];
3215
+ * console.log(sl.lower(10)); // undefined;
3216
+ */
3217
+ lower(key) {
3218
+ const cmp = this.#comparator;
3219
+ let current = this._head;
3220
+ let result;
3221
+ for (let i = this._level - 1; i >= 0; i--) {
3222
+ while (current.forward[i] && cmp(current.forward[i].key, key) < 0) {
3223
+ current = current.forward[i];
3224
+ }
3225
+ if (current !== this._head && cmp(current.key, key) < 0) {
3226
+ result = current;
3227
+ }
2025
3228
  }
2026
- return void 0;
2027
- }
2028
- has(key) {
2029
- return this.get(key) !== void 0;
2030
- }
2031
- delete(key) {
2032
- const update = new Array(this.maxLevel).fill(this.head);
2033
- let current = this.head;
2034
- for (let i = this.level - 1; i >= 0; i--) {
2035
- while (current.forward[i] && current.forward[i].key < key) {
3229
+ return result ? [result.key, result.value] : void 0;
3230
+ }
3231
+ /**
3232
+ * Returns entries within the given key range.
3233
+
3234
+
3235
+
3236
+
3237
+
3238
+
3239
+
3240
+
3241
+
3242
+
3243
+
3244
+ * @example
3245
+ * // Find entries in a range
3246
+ * const sl = new SkipList<number, string>([[1, 'a'], [2, 'b'], [3, 'c'], [4, 'd'], [5, 'e']]);
3247
+ * const result = sl.rangeSearch([2, 4]);
3248
+ * console.log(result); // [[2, 'b'], [3, 'c'], [4, 'd']];
3249
+ */
3250
+ rangeSearch(range, options = {}) {
3251
+ const { lowInclusive = true, highInclusive = true } = options;
3252
+ const [low, high] = range;
3253
+ const cmp = this.#comparator;
3254
+ const out = [];
3255
+ let current = this._head;
3256
+ for (let i = this._level - 1; i >= 0; i--) {
3257
+ while (current.forward[i] && cmp(current.forward[i].key, low) < 0) {
2036
3258
  current = current.forward[i];
2037
3259
  }
2038
- update[i] = current;
2039
3260
  }
2040
3261
  current = current.forward[0];
2041
- if (current && current.key === key) {
2042
- for (let i = 0; i < this.level; i++) {
2043
- if (update[i].forward[i] !== current) {
2044
- break;
2045
- }
2046
- update[i].forward[i] = current.forward[i];
2047
- }
2048
- while (this.level > 0 && !this.head.forward[this.level - 1]) {
2049
- this._level--;
3262
+ while (current) {
3263
+ const cmpHigh = cmp(current.key, high);
3264
+ if (cmpHigh > 0) break;
3265
+ if (cmpHigh === 0 && !highInclusive) break;
3266
+ const cmpLow = cmp(current.key, low);
3267
+ if (cmpLow > 0 || cmpLow === 0 && lowInclusive) {
3268
+ out.push([current.key, current.value]);
2050
3269
  }
2051
- return true;
3270
+ current = current.forward[0];
2052
3271
  }
2053
- return false;
3272
+ return out;
2054
3273
  }
2055
- higher(key) {
2056
- let current = this.head;
2057
- for (let i = this.level - 1; i >= 0; i--) {
2058
- while (current.forward[i] && current.forward[i].key <= key) {
3274
+ // ─── Functional (overrides) ──────────────────────────────────
3275
+ /**
3276
+ * Creates a new SkipList with entries transformed by callback.
3277
+
3278
+
3279
+
3280
+
3281
+
3282
+
3283
+
3284
+
3285
+ * @example
3286
+ * // Transform entries
3287
+ * const sl = new SkipList<number, string>([[1, 'a'], [2, 'b']]);
3288
+ * const mapped = sl.map((v, k) => [k, v?.toUpperCase()] as [number, string]);
3289
+ * console.log([...mapped.values()]); // ['A', 'B'];
3290
+ */
3291
+ map(callback, options) {
3292
+ const out = new _SkipList([], options ?? {});
3293
+ let i = 0;
3294
+ for (const [k, v] of this) {
3295
+ const [nk, nv] = callback(v, k, i++, this);
3296
+ out.set(nk, nv);
3297
+ }
3298
+ return out;
3299
+ }
3300
+ /**
3301
+ * Creates a new SkipList with entries that pass the predicate.
3302
+
3303
+
3304
+
3305
+
3306
+
3307
+
3308
+
3309
+
3310
+ * @example
3311
+ * // Filter entries
3312
+ * const sl = new SkipList<number, string>([[1, 'a'], [2, 'b'], [3, 'c']]);
3313
+ * const result = sl.filter((v, k) => k > 1);
3314
+ * console.log(result.size); // 2;
3315
+ */
3316
+ filter(callbackfn, thisArg) {
3317
+ const out = new _SkipList([], {
3318
+ comparator: this.#isDefaultComparator ? void 0 : this.#comparator,
3319
+ maxLevel: this._maxLevel,
3320
+ probability: this._probability
3321
+ });
3322
+ let i = 0;
3323
+ for (const [k, v] of this) {
3324
+ const ok = callbackfn.call(thisArg, v, k, i++, this);
3325
+ if (ok) out.set(k, v);
3326
+ }
3327
+ return out;
3328
+ }
3329
+ // ─── Iterator (required by IterableEntryBase) ────────────────
3330
+ _getIterator() {
3331
+ const head = this._head;
3332
+ return (function* () {
3333
+ let node = head.forward[0];
3334
+ while (node) {
3335
+ yield [node.key, node.value];
3336
+ node = node.forward[0];
3337
+ }
3338
+ })();
3339
+ }
3340
+ // ─── Internal helpers ────────────────────────────────────────
3341
+ /**
3342
+ * Finds the update array (predecessors at each level) for a given key.
3343
+ */
3344
+ _findUpdate(key) {
3345
+ const cmp = this.#comparator;
3346
+ const update = new Array(this._maxLevel).fill(this._head);
3347
+ let current = this._head;
3348
+ for (let i = this._level - 1; i >= 0; i--) {
3349
+ while (current.forward[i] && cmp(current.forward[i].key, key) < 0) {
2059
3350
  current = current.forward[i];
2060
3351
  }
3352
+ update[i] = current;
2061
3353
  }
2062
- const nextNode = current.forward[0];
2063
- return nextNode ? nextNode.value : void 0;
3354
+ return update;
2064
3355
  }
2065
- lower(key) {
2066
- let current = this.head;
2067
- let lastLess = void 0;
2068
- for (let i = this.level - 1; i >= 0; i--) {
2069
- while (current.forward[i] && current.forward[i].key < key) {
3356
+ /**
3357
+ * Finds the node for a given key, or undefined.
3358
+ */
3359
+ _findNode(key) {
3360
+ const cmp = this.#comparator;
3361
+ let current = this._head;
3362
+ for (let i = this._level - 1; i >= 0; i--) {
3363
+ while (current.forward[i] && cmp(current.forward[i].key, key) < 0) {
2070
3364
  current = current.forward[i];
2071
3365
  }
2072
- if (current.key < key) {
2073
- lastLess = current;
2074
- }
2075
3366
  }
2076
- return lastLess ? lastLess.value : void 0;
3367
+ const candidate = current.forward[0];
3368
+ if (candidate && cmp(candidate.key, key) === 0) return candidate;
3369
+ return void 0;
2077
3370
  }
2078
3371
  _randomLevel() {
2079
3372
  let level = 1;
2080
- while (Math.random() < this.probability && level < this.maxLevel) {
3373
+ while (Math.random() < this._probability && level < this._maxLevel) {
2081
3374
  level++;
2082
3375
  }
2083
3376
  return level;
2084
3377
  }
2085
3378
  };
2086
-
2087
- // src/common/index.ts
2088
- var DFSOperation = /* @__PURE__ */ ((DFSOperation2) => {
2089
- DFSOperation2[DFSOperation2["VISIT"] = 0] = "VISIT";
2090
- DFSOperation2[DFSOperation2["PROCESS"] = 1] = "PROCESS";
2091
- return DFSOperation2;
2092
- })(DFSOperation || {});
2093
- var Range = class {
2094
- constructor(low, high, includeLow = true, includeHigh = true) {
2095
- this.low = low;
2096
- this.high = high;
2097
- this.includeLow = includeLow;
2098
- this.includeHigh = includeHigh;
2099
- }
2100
- static {
2101
- __name(this, "Range");
2102
- }
2103
- // Determine whether a key is within the range
2104
- isInRange(key, comparator) {
2105
- const lowCheck = this.includeLow ? comparator(key, this.low) >= 0 : comparator(key, this.low) > 0;
2106
- const highCheck = this.includeHigh ? comparator(key, this.high) <= 0 : comparator(key, this.high) < 0;
2107
- return lowCheck && highCheck;
2108
- }
2109
- };
2110
3379
  /**
2111
3380
  * data-structure-typed
2112
3381
  *
@@ -2118,6 +3387,7 @@ var Range = class {
2118
3387
  exports.DFSOperation = DFSOperation;
2119
3388
  exports.DoublyLinkedList = DoublyLinkedList;
2120
3389
  exports.DoublyLinkedListNode = DoublyLinkedListNode;
3390
+ exports.ERR = ERR;
2121
3391
  exports.Range = Range;
2122
3392
  exports.SinglyLinkedList = SinglyLinkedList;
2123
3393
  exports.SinglyLinkedListNode = SinglyLinkedListNode;