data-structure-typed 2.5.0 → 2.5.2

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 (246) hide show
  1. package/.vitepress/cache/deps_temp_51f5f1b0/chunk-7OIKW5WK.js +12984 -0
  2. package/.vitepress/cache/deps_temp_51f5f1b0/package.json +3 -0
  3. package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vue_devtools-api.js +4505 -0
  4. package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vueuse_core.js +9731 -0
  5. package/.vitepress/cache/deps_temp_51f5f1b0/vue.js +347 -0
  6. package/CHANGELOG.md +5 -1
  7. package/README.md +124 -29
  8. package/dist/cjs/binary-tree.cjs +26282 -0
  9. package/dist/cjs/graph.cjs +5422 -0
  10. package/dist/cjs/hash.cjs +1310 -0
  11. package/dist/cjs/heap.cjs +1602 -0
  12. package/dist/cjs/index.cjs +31257 -14673
  13. package/dist/cjs/linked-list.cjs +4576 -0
  14. package/dist/cjs/matrix.cjs +1080 -0
  15. package/dist/cjs/priority-queue.cjs +1376 -0
  16. package/dist/cjs/queue.cjs +4264 -0
  17. package/dist/cjs/stack.cjs +907 -0
  18. package/dist/cjs/trie.cjs +1223 -0
  19. package/dist/cjs-legacy/binary-tree.cjs +26319 -0
  20. package/dist/cjs-legacy/graph.cjs +5420 -0
  21. package/dist/cjs-legacy/hash.cjs +1310 -0
  22. package/dist/cjs-legacy/heap.cjs +1599 -0
  23. package/dist/cjs-legacy/index.cjs +31268 -14679
  24. package/dist/cjs-legacy/linked-list.cjs +4582 -0
  25. package/dist/cjs-legacy/matrix.cjs +1083 -0
  26. package/dist/cjs-legacy/priority-queue.cjs +1374 -0
  27. package/dist/cjs-legacy/queue.cjs +4262 -0
  28. package/dist/cjs-legacy/stack.cjs +907 -0
  29. package/dist/cjs-legacy/trie.cjs +1222 -0
  30. package/dist/esm/binary-tree.mjs +26267 -0
  31. package/dist/esm/graph.mjs +5409 -0
  32. package/dist/esm/hash.mjs +1307 -0
  33. package/dist/esm/heap.mjs +1596 -0
  34. package/dist/esm/index.mjs +31254 -14674
  35. package/dist/esm/linked-list.mjs +4569 -0
  36. package/dist/esm/matrix.mjs +1076 -0
  37. package/dist/esm/priority-queue.mjs +1372 -0
  38. package/dist/esm/queue.mjs +4260 -0
  39. package/dist/esm/stack.mjs +905 -0
  40. package/dist/esm/trie.mjs +1220 -0
  41. package/dist/esm-legacy/binary-tree.mjs +26304 -0
  42. package/dist/esm-legacy/graph.mjs +5407 -0
  43. package/dist/esm-legacy/hash.mjs +1307 -0
  44. package/dist/esm-legacy/heap.mjs +1593 -0
  45. package/dist/esm-legacy/index.mjs +31265 -14680
  46. package/dist/esm-legacy/linked-list.mjs +4575 -0
  47. package/dist/esm-legacy/matrix.mjs +1079 -0
  48. package/dist/esm-legacy/priority-queue.mjs +1370 -0
  49. package/dist/esm-legacy/queue.mjs +4258 -0
  50. package/dist/esm-legacy/stack.mjs +905 -0
  51. package/dist/esm-legacy/trie.mjs +1219 -0
  52. package/dist/types/common/error.d.ts +9 -0
  53. package/dist/types/common/index.d.ts +1 -1
  54. package/dist/types/data-structures/base/index.d.ts +1 -0
  55. package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
  56. package/dist/types/data-structures/base/linear-base.d.ts +3 -3
  57. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +288 -0
  58. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +336 -0
  59. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +618 -18
  60. package/dist/types/data-structures/binary-tree/bst.d.ts +676 -1
  61. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +456 -0
  62. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +144 -1
  63. package/dist/types/data-structures/binary-tree/tree-map.d.ts +3307 -399
  64. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3285 -360
  65. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2674 -325
  66. package/dist/types/data-structures/binary-tree/tree-set.d.ts +3072 -287
  67. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
  68. package/dist/types/data-structures/graph/directed-graph.d.ts +240 -0
  69. package/dist/types/data-structures/graph/undirected-graph.d.ts +216 -0
  70. package/dist/types/data-structures/hash/hash-map.d.ts +274 -10
  71. package/dist/types/data-structures/heap/heap.d.ts +336 -0
  72. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +411 -3
  73. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +363 -3
  74. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +434 -2
  75. package/dist/types/data-structures/matrix/matrix.d.ts +192 -0
  76. package/dist/types/data-structures/queue/deque.d.ts +364 -4
  77. package/dist/types/data-structures/queue/queue.d.ts +288 -0
  78. package/dist/types/data-structures/stack/stack.d.ts +240 -0
  79. package/dist/types/data-structures/trie/trie.d.ts +292 -4
  80. package/dist/types/interfaces/graph.d.ts +1 -1
  81. package/dist/types/types/common.d.ts +2 -2
  82. package/dist/types/types/data-structures/binary-tree/bst.d.ts +1 -0
  83. package/dist/types/types/data-structures/binary-tree/tree-map.d.ts +5 -0
  84. package/dist/types/types/data-structures/binary-tree/tree-multi-set.d.ts +4 -0
  85. package/dist/types/types/data-structures/binary-tree/tree-set.d.ts +4 -0
  86. package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
  87. package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
  88. package/dist/types/types/utils/validate-type.d.ts +4 -4
  89. package/dist/umd/data-structure-typed.js +31196 -14608
  90. package/dist/umd/data-structure-typed.min.js +11 -5
  91. package/docs-site-docusaurus/README.md +41 -0
  92. package/docs-site-docusaurus/docs/api/README.md +52 -0
  93. package/docs-site-docusaurus/docs/api/classes/AVLTree.md +6644 -0
  94. package/docs-site-docusaurus/docs/api/classes/AVLTreeNode.md +282 -0
  95. package/docs-site-docusaurus/docs/api/classes/AbstractGraph.md +2266 -0
  96. package/docs-site-docusaurus/docs/api/classes/BST.md +6293 -0
  97. package/docs-site-docusaurus/docs/api/classes/BSTNode.md +333 -0
  98. package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +455 -0
  99. package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +4647 -0
  100. package/docs-site-docusaurus/docs/api/classes/BinaryTreeNode.md +331 -0
  101. package/docs-site-docusaurus/docs/api/classes/Deque.md +2767 -0
  102. package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +2999 -0
  103. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +2685 -0
  104. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedListNode.md +221 -0
  105. package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +253 -0
  106. package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +21 -0
  107. package/docs-site-docusaurus/docs/api/classes/HashMap.md +1333 -0
  108. package/docs-site-docusaurus/docs/api/classes/Heap.md +1881 -0
  109. package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +800 -0
  110. package/docs-site-docusaurus/docs/api/classes/IterableEntryBase.md +644 -0
  111. package/docs-site-docusaurus/docs/api/classes/LinearBase.md +1632 -0
  112. package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +1853 -0
  113. package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +1108 -0
  114. package/docs-site-docusaurus/docs/api/classes/LinkedListNode.md +156 -0
  115. package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +2824 -0
  116. package/docs-site-docusaurus/docs/api/classes/MapGraph.md +2929 -0
  117. package/docs-site-docusaurus/docs/api/classes/Matrix.md +1026 -0
  118. package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +1866 -0
  119. package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +1883 -0
  120. package/docs-site-docusaurus/docs/api/classes/MinHeap.md +1879 -0
  121. package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +1882 -0
  122. package/docs-site-docusaurus/docs/api/classes/Navigator.md +109 -0
  123. package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +1839 -0
  124. package/docs-site-docusaurus/docs/api/classes/Queue.md +2244 -0
  125. package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +6888 -0
  126. package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +372 -0
  127. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +2897 -0
  128. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedListNode.md +169 -0
  129. package/docs-site-docusaurus/docs/api/classes/SkipList.md +1229 -0
  130. package/docs-site-docusaurus/docs/api/classes/Stack.md +1573 -0
  131. package/docs-site-docusaurus/docs/api/classes/TreeMap.md +1389 -0
  132. package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +1591 -0
  133. package/docs-site-docusaurus/docs/api/classes/TreeSet.md +1246 -0
  134. package/docs-site-docusaurus/docs/api/classes/Trie.md +1708 -0
  135. package/docs-site-docusaurus/docs/api/classes/TrieNode.md +199 -0
  136. package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +2979 -0
  137. package/docs-site-docusaurus/docs/guide/_category_.json +6 -0
  138. package/docs-site-docusaurus/docs/guide/architecture.md +615 -0
  139. package/docs-site-docusaurus/docs/guide/concepts.md +451 -0
  140. package/docs-site-docusaurus/docs/guide/faq.md +180 -0
  141. package/docs-site-docusaurus/docs/guide/guides.md +597 -0
  142. package/docs-site-docusaurus/docs/guide/installation.md +62 -0
  143. package/docs-site-docusaurus/docs/guide/integrations.md +825 -0
  144. package/docs-site-docusaurus/docs/guide/overview.md +645 -0
  145. package/docs-site-docusaurus/docs/guide/performance.md +835 -0
  146. package/docs-site-docusaurus/docs/guide/quick-start.md +104 -0
  147. package/docs-site-docusaurus/docs/guide/use-cases/_category_.json +6 -0
  148. package/docs-site-docusaurus/docs/guide/use-cases/array-sort-alternative.md +158 -0
  149. package/docs-site-docusaurus/docs/guide/use-cases/heap-vs-sorting.md +92 -0
  150. package/docs-site-docusaurus/docs/guide/use-cases/map-vs-treemap.md +151 -0
  151. package/docs-site-docusaurus/docs/guide/use-cases/priority-queue-typescript.md +113 -0
  152. package/docs-site-docusaurus/docs/guide/use-cases/treemap-javascript.md +151 -0
  153. package/docs-site-docusaurus/docusaurus.config.ts +159 -0
  154. package/docs-site-docusaurus/fix-mdx-generics.mjs +75 -0
  155. package/docs-site-docusaurus/package-lock.json +18667 -0
  156. package/docs-site-docusaurus/package.json +50 -0
  157. package/docs-site-docusaurus/prefix-class-to-methods.mjs +48 -0
  158. package/docs-site-docusaurus/sidebars.ts +23 -0
  159. package/docs-site-docusaurus/sort-protected.mjs +87 -0
  160. package/docs-site-docusaurus/src/css/custom.css +96 -0
  161. package/docs-site-docusaurus/src/pages/index.module.css +13 -0
  162. package/docs-site-docusaurus/src/pages/index.tsx +120 -0
  163. package/docs-site-docusaurus/src/pages/markdown-page.md +7 -0
  164. package/docs-site-docusaurus/src/theme/TOCItems/index.tsx +34 -0
  165. package/docs-site-docusaurus/static/.nojekyll +0 -0
  166. package/docs-site-docusaurus/static/img/docusaurus-social-card.jpg +0 -0
  167. package/docs-site-docusaurus/static/img/docusaurus.png +0 -0
  168. package/docs-site-docusaurus/static/img/favicon.ico +0 -0
  169. package/docs-site-docusaurus/static/img/favicon.png +0 -0
  170. package/docs-site-docusaurus/static/img/logo-180.png +0 -0
  171. package/docs-site-docusaurus/static/img/logo.jpg +0 -0
  172. package/docs-site-docusaurus/static/img/logo.png +0 -0
  173. package/docs-site-docusaurus/static/img/logo.svg +1 -0
  174. package/docs-site-docusaurus/static/img/og-image.png +0 -0
  175. package/docs-site-docusaurus/static/img/undraw_docusaurus_mountain.svg +171 -0
  176. package/docs-site-docusaurus/static/img/undraw_docusaurus_react.svg +170 -0
  177. package/docs-site-docusaurus/static/img/undraw_docusaurus_tree.svg +40 -0
  178. package/docs-site-docusaurus/static/llms.txt +37 -0
  179. package/docs-site-docusaurus/static/robots.txt +4 -0
  180. package/docs-site-docusaurus/typedoc.json +23 -0
  181. package/llms.txt +37 -0
  182. package/package.json +159 -55
  183. package/src/common/error.ts +19 -1
  184. package/src/common/index.ts +1 -1
  185. package/src/data-structures/base/index.ts +1 -0
  186. package/src/data-structures/base/iterable-element-base.ts +3 -2
  187. package/src/data-structures/base/iterable-entry-base.ts +8 -8
  188. package/src/data-structures/base/linear-base.ts +3 -3
  189. package/src/data-structures/binary-tree/avl-tree.ts +287 -0
  190. package/src/data-structures/binary-tree/binary-indexed-tree.ts +327 -5
  191. package/src/data-structures/binary-tree/binary-tree.ts +581 -6
  192. package/src/data-structures/binary-tree/bst.ts +922 -7
  193. package/src/data-structures/binary-tree/red-black-tree.ts +453 -0
  194. package/src/data-structures/binary-tree/segment-tree.ts +139 -2
  195. package/src/data-structures/binary-tree/tree-map.ts +3300 -495
  196. package/src/data-structures/binary-tree/tree-multi-map.ts +3384 -563
  197. package/src/data-structures/binary-tree/tree-multi-set.ts +2757 -493
  198. package/src/data-structures/binary-tree/tree-set.ts +3122 -440
  199. package/src/data-structures/graph/abstract-graph.ts +6 -6
  200. package/src/data-structures/graph/directed-graph.ts +230 -0
  201. package/src/data-structures/graph/undirected-graph.ts +207 -0
  202. package/src/data-structures/hash/hash-map.ts +270 -19
  203. package/src/data-structures/heap/heap.ts +326 -4
  204. package/src/data-structures/heap/max-heap.ts +2 -2
  205. package/src/data-structures/linked-list/doubly-linked-list.ts +394 -3
  206. package/src/data-structures/linked-list/singly-linked-list.ts +348 -3
  207. package/src/data-structures/linked-list/skip-linked-list.ts +421 -7
  208. package/src/data-structures/matrix/matrix.ts +194 -10
  209. package/src/data-structures/priority-queue/max-priority-queue.ts +2 -2
  210. package/src/data-structures/queue/deque.ts +350 -5
  211. package/src/data-structures/queue/queue.ts +276 -0
  212. package/src/data-structures/stack/stack.ts +230 -0
  213. package/src/data-structures/trie/trie.ts +283 -7
  214. package/src/interfaces/graph.ts +1 -1
  215. package/src/types/common.ts +2 -2
  216. package/src/types/data-structures/binary-tree/bst.ts +1 -0
  217. package/src/types/data-structures/binary-tree/tree-map.ts +6 -0
  218. package/src/types/data-structures/binary-tree/tree-multi-set.ts +5 -0
  219. package/src/types/data-structures/binary-tree/tree-set.ts +5 -0
  220. package/src/types/data-structures/heap/heap.ts +1 -0
  221. package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
  222. package/src/types/utils/validate-type.ts +4 -4
  223. package/vercel.json +6 -0
  224. package/dist/leetcode/avl-tree-counter.mjs +0 -2957
  225. package/dist/leetcode/avl-tree-multi-map.mjs +0 -2889
  226. package/dist/leetcode/avl-tree.mjs +0 -2720
  227. package/dist/leetcode/binary-tree.mjs +0 -1594
  228. package/dist/leetcode/bst.mjs +0 -2398
  229. package/dist/leetcode/deque.mjs +0 -683
  230. package/dist/leetcode/directed-graph.mjs +0 -1733
  231. package/dist/leetcode/doubly-linked-list.mjs +0 -709
  232. package/dist/leetcode/hash-map.mjs +0 -493
  233. package/dist/leetcode/heap.mjs +0 -542
  234. package/dist/leetcode/max-heap.mjs +0 -375
  235. package/dist/leetcode/max-priority-queue.mjs +0 -383
  236. package/dist/leetcode/min-heap.mjs +0 -363
  237. package/dist/leetcode/min-priority-queue.mjs +0 -371
  238. package/dist/leetcode/priority-queue.mjs +0 -363
  239. package/dist/leetcode/queue.mjs +0 -943
  240. package/dist/leetcode/red-black-tree.mjs +0 -2765
  241. package/dist/leetcode/singly-linked-list.mjs +0 -754
  242. package/dist/leetcode/stack.mjs +0 -217
  243. package/dist/leetcode/tree-counter.mjs +0 -3039
  244. package/dist/leetcode/tree-multi-map.mjs +0 -2913
  245. package/dist/leetcode/trie.mjs +0 -413
  246. package/dist/leetcode/undirected-graph.mjs +0 -1650
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import type { Comparator, TreeMultiSetOptions } from '../../types';
12
- import { ERR } from '../../common';
12
+ import { ERR, raise } from '../../common';
13
13
  import { RedBlackTree } from './red-black-tree';
14
14
  import { TreeSet } from './tree-set';
15
15
 
@@ -35,7 +35,7 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
35
35
  const toElementFn = options.toElementFn;
36
36
  const comparator = options.comparator ?? TreeSet.createDefaultComparator<K>();
37
37
  this.#isDefaultComparator = options.comparator === undefined;
38
- this.#core = new RedBlackTree<K, number>([], { comparator, isMapMode: options.isMapMode });
38
+ this.#core = new RedBlackTree<K, number>([], { comparator, isMapMode: options.isMapMode, enableOrderStatistic: options.enableOrderStatistic });
39
39
 
40
40
  for (const item of elements) {
41
41
  const k = toElementFn ? toElementFn(item as R) : (item as K);
@@ -51,18 +51,18 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
51
51
  if (!this.#isDefaultComparator) return;
52
52
 
53
53
  if (typeof key === 'number') {
54
- if (Number.isNaN(key)) throw new TypeError(ERR.invalidNaN('TreeMultiSet'));
54
+ if (Number.isNaN(key)) raise(TypeError, ERR.invalidNaN('TreeMultiSet'));
55
55
  return;
56
56
  }
57
57
 
58
58
  if (typeof key === 'string') return;
59
59
 
60
60
  if (key instanceof Date) {
61
- if (Number.isNaN(key.getTime())) throw new TypeError(ERR.invalidDate('TreeMultiSet'));
61
+ if (Number.isNaN(key.getTime())) raise(TypeError, ERR.invalidDate('TreeMultiSet'));
62
62
  return;
63
63
  }
64
64
 
65
- throw new TypeError(ERR.comparatorRequired('TreeMultiSet'));
65
+ raise(TypeError, ERR.comparatorRequired('TreeMultiSet'));
66
66
  }
67
67
 
68
68
  /**
@@ -70,7 +70,7 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
70
70
  * @remarks Time O(1), Space O(1)
71
71
  */
72
72
  private _validateCount(n: number): void {
73
- if (!Number.isSafeInteger(n) || n < 0) throw new RangeError(ERR.invalidArgument('count must be a safe integer >= 0.', 'TreeMultiSet'));
73
+ if (!Number.isSafeInteger(n) || n < 0) raise(RangeError, ERR.invalidArgument('count must be a safe integer >= 0.', 'TreeMultiSet'));
74
74
  }
75
75
 
76
76
  /**
@@ -87,6 +87,29 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
87
87
 
88
88
 
89
89
 
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
90
113
  * @example
91
114
  * // Unique key count
92
115
  * const ms = new TreeMultiSet<number>();
@@ -144,17 +167,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
144
167
 
145
168
 
146
169
 
147
- * @example
148
- * // Check empty
149
- * console.log(new TreeMultiSet().isEmpty()); // true;
150
- */
151
- isEmpty(): boolean {
152
- return this.size === 0;
153
- }
154
-
155
- /**
156
- * Whether the multiset contains the given key.
157
- * @remarks Time O(log n), Space O(1)
158
170
 
159
171
 
160
172
 
@@ -201,39 +213,9 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
201
213
 
202
214
 
203
215
 
204
- * @example
205
- * // Check existence
206
- * const ms = new TreeMultiSet<number>();
207
- * ms.add(1);
208
- * console.log(ms.has(1)); // true;
209
- * console.log(ms.has(2)); // false;
210
- */
211
- has(key: K): boolean {
212
- this._validateKey(key);
213
- return this.count(key) > 0;
214
- }
215
-
216
- /**
217
- * Returns the count of occurrences for the given key.
218
- * @remarks Time O(log n), Space O(1)
219
216
 
220
217
 
221
218
 
222
- * @example
223
- * // Get occurrence count
224
- * const ms = new TreeMultiSet<number>();
225
- * ms.add(1, 5);
226
- * console.log(ms.count(1)); // 5;
227
- */
228
- count(key: K): number {
229
- this._validateKey(key);
230
- return this.#core.get(key) ?? 0;
231
- }
232
-
233
- /**
234
- * Add `n` occurrences of `key`.
235
- * @returns True if the multiset changed.
236
- * @remarks Time O(log n), Space O(1)
237
219
 
238
220
 
239
221
 
@@ -271,60 +253,45 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
271
253
 
272
254
 
273
255
 
274
- * @example
275
- * // Add elements
276
- * const ms = new TreeMultiSet<number>();
277
- * ms.add(1);
278
- * ms.add(1);
279
- * ms.add(2);
280
- * console.log(ms.count(1)); // 2;
281
- * console.log(ms.size); // 3;
282
- */
283
- add(key: K, n = 1): boolean {
284
- this._validateKey(key);
285
- this._validateCount(n);
286
- if (n === 0) return false;
287
-
288
- const old = this.#core.get(key) ?? 0;
289
- const next = old + n;
290
- this.#core.set(key, next);
291
- this._size += n;
292
- return true;
293
- }
294
-
295
- /**
296
- * Set count for `key` to exactly `n`.
297
- * @returns True if changed.
298
- * @remarks Time O(log n), Space O(1)
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
265
+
266
+
267
+
268
+
269
+
270
+
271
+
272
+
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+
281
+
299
282
 
300
283
 
301
284
 
302
285
  * @example
303
- * // Set occurrence count
304
- * const ms = new TreeMultiSet<number>();
305
- * ms.setCount(1, 3);
306
- * console.log(ms.count(1)); // 3;
286
+ * // Check empty
287
+ * console.log(new TreeMultiSet().isEmpty()); // true;
307
288
  */
308
- setCount(key: K, n: number): boolean {
309
- this._validateKey(key);
310
- this._validateCount(n);
311
-
312
- const old = this.#core.get(key) ?? 0;
313
- if (old === n) return false;
314
-
315
- if (n === 0) {
316
- if (old !== 0) this.#core.delete(key);
317
- } else {
318
- this.#core.set(key, n);
319
- }
320
-
321
- this._size += n - old;
322
- return true;
289
+ isEmpty(): boolean {
290
+ return this.size === 0;
323
291
  }
324
292
 
325
293
  /**
326
- * Delete `n` occurrences of `key` (default 1).
327
- * @returns True if any occurrence was removed.
294
+ * Whether the multiset contains the given key.
328
295
  * @remarks Time O(log n), Space O(1)
329
296
 
330
297
 
@@ -372,74 +339,12 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
372
339
 
373
340
 
374
341
 
375
- * @example
376
- * // Remove one occurrence
377
- * const ms = new TreeMultiSet<number>();
378
- * ms.add(1, 3);
379
- * ms.delete(1);
380
- * console.log(ms.count(1)); // 2;
381
- */
382
- delete(key: K, n = 1): boolean {
383
- this._validateKey(key);
384
- this._validateCount(n);
385
- if (n === 0) return false;
386
-
387
- const old = this.#core.get(key) ?? 0;
388
- if (old === 0) return false;
389
-
390
- const removed = Math.min(old, n);
391
- const next = old - removed;
392
-
393
- if (next === 0) this.#core.delete(key);
394
- else this.#core.set(key, next);
395
-
396
- this._size -= removed;
397
- return true;
398
- }
399
-
400
- /**
401
- * Delete all occurrences of the given key.
402
- * @returns True if any occurrence was removed.
403
- * @remarks Time O(log n), Space O(1)
404
342
 
405
343
 
406
344
 
407
- * @example
408
- * // Remove all occurrences
409
- * const ms = new TreeMultiSet<number>();
410
- * ms.add(1, 3);
411
- * ms.deleteAll(1);
412
- * console.log(ms.has(1)); // false;
413
- */
414
- deleteAll(key: K): boolean {
415
- this._validateKey(key);
416
- const old = this.#core.get(key) ?? 0;
417
- if (old === 0) return false;
418
- this.#core.delete(key);
419
- this._size -= old;
420
- return true;
421
- }
422
-
423
- /**
424
- * Iterates over distinct keys (each key yielded once).
425
- * @remarks Time O(n), Space O(1)
426
345
 
427
346
 
428
347
 
429
- * @example
430
- * // Iterate unique keys
431
- * const ms = new TreeMultiSet<number>();
432
- * ms.add(1, 2);
433
- * ms.add(2);
434
- * console.log([...ms.keysDistinct()]); // [1, 2];
435
- */
436
- *keysDistinct(): IterableIterator<K> {
437
- yield* this.#core.keys();
438
- }
439
-
440
- /**
441
- * Iterates over entries as [key, count] pairs.
442
- * @remarks Time O(n), Space O(1)
443
348
 
444
349
 
445
350
 
@@ -483,31 +388,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
483
388
 
484
389
 
485
390
 
486
- * @example
487
- * // Iterate entries
488
- * const ms = new TreeMultiSet<number>();
489
- * ms.add(1, 2);
490
- * console.log([...ms.entries()].length); // > 0;
491
- */
492
- *entries(): IterableIterator<[K, number]> {
493
- for (const [k, v] of this.#core) {
494
- yield [k, v ?? 0];
495
- }
496
- }
497
-
498
- /**
499
- * Expanded iteration (default). Each key is yielded `count(key)` times.
500
- * @remarks Time O(size), Space O(1) where size is total occurrences
501
- */
502
- *[Symbol.iterator](): Iterator<K> {
503
- for (const [k, c] of this.entries()) {
504
- for (let i = 0; i < c; i++) yield k;
505
- }
506
- }
507
-
508
- /**
509
- * Returns an array with all elements (expanded).
510
- * @remarks Time O(size), Space O(size)
511
391
 
512
392
 
513
393
 
@@ -551,65 +431,185 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
551
431
 
552
432
 
553
433
 
554
- * @example
555
- * // All elements (with duplicates)
556
- * const ms = new TreeMultiSet<number>();
557
- * ms.add(1, 2);
558
- * ms.add(2);
559
- * console.log(ms.toArray()); // [1, 1, 2];
560
- */
561
- toArray(): K[] {
562
- return [...this];
563
- }
564
-
565
- /**
566
- * Returns an array with distinct keys only.
567
- * @remarks Time O(n), Space O(n)
568
434
 
569
435
 
570
436
 
571
- * @example
572
- * // Unique keys only
573
- * const ms = new TreeMultiSet<number>();
574
- * ms.add(1, 3);
575
- * ms.add(2);
576
- * console.log(ms.toDistinctArray()); // [1, 2];
577
- */
578
- toDistinctArray(): K[] {
579
- return [...this.keysDistinct()];
580
- }
581
-
582
- /**
583
- * Returns an array of [key, count] entries.
584
- * @remarks Time O(n), Space O(n)
437
+
438
+
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+
451
+
452
+
453
+
585
454
 
586
455
 
587
456
 
588
457
  * @example
589
- * // Key-count pairs
458
+ * // Check existence
590
459
  * const ms = new TreeMultiSet<number>();
591
- * ms.add(1, 2);
592
- * ms.add(3);
593
- * console.log(ms.toEntries()); // [[1, 2], [3, 1]];
460
+ * ms.add(1);
461
+ * console.log(ms.has(1)); // true;
462
+ * console.log(ms.has(2)); // false;
594
463
  */
595
- toEntries(): Array<[K, number]> {
596
- return [...this.entries()];
464
+ has(key: K): boolean {
465
+ this._validateKey(key);
466
+ return this.count(key) > 0;
597
467
  }
598
468
 
599
469
  /**
600
- * Expose comparator for advanced usage/testing (read-only).
601
- * @remarks Time O(1), Space O(1)
470
+ * Returns the count of occurrences for the given key.
471
+ * @remarks Time O(log n), Space O(1)
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+
480
+
481
+
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+
490
+
491
+
492
+
493
+
494
+
495
+
496
+
497
+
498
+ * @example
499
+ * // Get occurrence count
500
+ * const ms = new TreeMultiSet<number>();
501
+ * ms.add(1, 5);
502
+ * console.log(ms.count(1)); // 5;
602
503
  */
603
- get comparator(): Comparator<K> {
604
- return this.#core.comparator;
504
+ count(key: K): number {
505
+ this._validateKey(key);
506
+ return this.#core.get(key) ?? 0;
605
507
  }
606
508
 
607
- // ━━━ clear ━━━
608
-
609
509
  /**
610
- * Remove all elements from the multiset.
611
- * @remarks Time O(1), Space O(1)
612
-
510
+ * Add `n` occurrences of `key`.
511
+ * @returns True if the multiset changed.
512
+ * @remarks Time O(log n), Space O(1)
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+
521
+
522
+
523
+
524
+
525
+
526
+
527
+
528
+
529
+
530
+
531
+
532
+
533
+
534
+
535
+
536
+
537
+
538
+
539
+
540
+
541
+
542
+
543
+
544
+
545
+
546
+
547
+
548
+
549
+
550
+
551
+
552
+
553
+
554
+
555
+
556
+
557
+
558
+
559
+
560
+
561
+
562
+
563
+
564
+
565
+
566
+
567
+
568
+
569
+
570
+
571
+
572
+
573
+
574
+
575
+
576
+
577
+
578
+
579
+
580
+
581
+
582
+
583
+
584
+
585
+
586
+
587
+
588
+
589
+
590
+
591
+
592
+
593
+
594
+
595
+
596
+
597
+
598
+
599
+
600
+
601
+
602
+
603
+
604
+
605
+
606
+
607
+
608
+
609
+
610
+
611
+
612
+
613
613
 
614
614
 
615
615
 
@@ -653,102 +653,2453 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
653
653
 
654
654
 
655
655
 
656
- * @example
657
- * // Remove all
658
- * const ms = new TreeMultiSet<number>();
659
- * ms.add(1);
660
- * ms.clear();
661
- * console.log(ms.isEmpty()); // true;
662
- */
663
- clear(): void {
664
- this.#core.clear();
665
- this._size = 0;
666
- }
667
-
668
- // ━━━ Navigable methods ━━━
669
-
670
- /**
671
- * Returns the smallest key, or undefined if empty.
672
- * @remarks Time O(log n), Space O(1)
673
-
674
656
 
675
657
 
676
658
 
677
- * @example
678
- * // Smallest element
679
- * const ms = new TreeMultiSet<number>();
680
- * ms.add(3);
681
- * ms.add(1);
682
- * console.log(ms.first()); // 1;
683
- */
684
- first(): K | undefined {
685
- return this.#core.getLeftMost();
686
- }
687
-
688
- /**
689
- * Returns the largest key, or undefined if empty.
690
- * @remarks Time O(log n), Space O(1)
691
-
692
659
 
693
660
 
694
661
 
695
- * @example
696
- * // Largest element
697
- * const ms = new TreeMultiSet<number>();
698
- * ms.add(1);
699
- * ms.add(3);
700
- * console.log(ms.last()); // 3;
701
- */
702
- last(): K | undefined {
703
- return this.#core.getRightMost();
704
- }
705
-
706
- /**
707
- * Removes all occurrences of the smallest key and returns it.
708
- * @remarks Time O(log n), Space O(1)
709
-
710
662
 
711
663
 
712
664
 
713
665
  * @example
714
- * // Remove and return smallest
666
+ * // Add elements
715
667
  * const ms = new TreeMultiSet<number>();
716
- * ms.add(2);
717
668
  * ms.add(1);
718
- * console.log(ms.pollFirst()); // 1;
719
- * console.log(ms.has(1)); // false;
669
+ * ms.add(1);
670
+ * ms.add(2);
671
+ * console.log(ms.count(1)); // 2;
672
+ * console.log(ms.size); // 3;
720
673
  */
721
- pollFirst(): K | undefined {
722
- const key = this.first();
723
- if (key === undefined) return undefined;
724
- this.deleteAll(key);
725
- return key;
674
+ add(key: K, n = 1): boolean {
675
+ this._validateKey(key);
676
+ this._validateCount(n);
677
+ if (n === 0) return false;
678
+
679
+ const old = this.#core.get(key) ?? 0;
680
+ const next = old + n;
681
+ this.#core.set(key, next);
682
+ this._size += n;
683
+ return true;
726
684
  }
727
685
 
728
686
  /**
729
- * Removes all occurrences of the largest key and returns it.
687
+ * Set count for `key` to exactly `n`.
688
+ * @returns True if changed.
730
689
  * @remarks Time O(log n), Space O(1)
731
-
732
690
 
733
691
 
734
692
 
735
- * @example
736
- * // Remove and return largest
693
+
694
+
695
+
696
+
697
+
698
+
699
+
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+
708
+
709
+
710
+
711
+
712
+
713
+
714
+
715
+
716
+ * @example
717
+ * // Set occurrence count
718
+ * const ms = new TreeMultiSet<number>();
719
+ * ms.setCount(1, 3);
720
+ * console.log(ms.count(1)); // 3;
721
+ */
722
+ setCount(key: K, n: number): boolean {
723
+ this._validateKey(key);
724
+ this._validateCount(n);
725
+
726
+ const old = this.#core.get(key) ?? 0;
727
+ if (old === n) return false;
728
+
729
+ if (n === 0) {
730
+ if (old !== 0) this.#core.delete(key);
731
+ } else {
732
+ this.#core.set(key, n);
733
+ }
734
+
735
+ this._size += n - old;
736
+ return true;
737
+ }
738
+
739
+ /**
740
+ * Delete `n` occurrences of `key` (default 1).
741
+ * @returns True if any occurrence was removed.
742
+ * @remarks Time O(log n), Space O(1)
743
+
744
+
745
+
746
+
747
+
748
+
749
+
750
+
751
+
752
+
753
+
754
+
755
+
756
+
757
+
758
+
759
+
760
+
761
+
762
+
763
+
764
+
765
+
766
+
767
+
768
+
769
+
770
+
771
+
772
+
773
+
774
+
775
+
776
+
777
+
778
+
779
+
780
+
781
+
782
+
783
+
784
+
785
+
786
+
787
+
788
+
789
+
790
+
791
+
792
+
793
+
794
+
795
+
796
+
797
+
798
+
799
+
800
+
801
+
802
+
803
+
804
+
805
+
806
+
807
+
808
+
809
+
810
+
811
+
812
+
813
+
814
+
815
+
816
+
817
+
818
+
819
+
820
+
821
+
822
+
823
+
824
+
825
+
826
+
827
+
828
+
829
+
830
+
831
+
832
+
833
+
834
+
835
+
836
+
837
+
838
+
839
+
840
+
841
+
842
+
843
+
844
+
845
+
846
+
847
+
848
+
849
+
850
+
851
+
852
+
853
+
854
+
855
+
856
+
857
+
858
+
859
+
860
+
861
+
862
+
863
+
864
+
865
+
866
+
867
+
868
+
869
+
870
+
871
+
872
+
873
+
874
+
875
+
876
+
877
+
878
+
879
+
880
+
881
+
882
+
883
+
884
+
885
+
886
+
887
+
888
+
889
+
890
+
891
+
892
+
893
+
894
+
895
+
896
+
897
+
898
+
899
+
900
+
901
+
902
+
903
+
904
+ * @example
905
+ * // Remove one occurrence
906
+ * const ms = new TreeMultiSet<number>();
907
+ * ms.add(1, 3);
908
+ * ms.delete(1);
909
+ * console.log(ms.count(1)); // 2;
910
+ */
911
+ delete(key: K, n = 1): boolean {
912
+ this._validateKey(key);
913
+ this._validateCount(n);
914
+ if (n === 0) return false;
915
+
916
+ const old = this.#core.get(key) ?? 0;
917
+ if (old === 0) return false;
918
+
919
+ const removed = Math.min(old, n);
920
+ const next = old - removed;
921
+
922
+ if (next === 0) this.#core.delete(key);
923
+ else this.#core.set(key, next);
924
+
925
+ this._size -= removed;
926
+ return true;
927
+ }
928
+
929
+ /**
930
+ * Delete all occurrences of the given key.
931
+ * @returns True if any occurrence was removed.
932
+ * @remarks Time O(log n), Space O(1)
933
+
934
+
935
+
936
+
937
+
938
+
939
+
940
+
941
+
942
+
943
+
944
+
945
+
946
+
947
+
948
+
949
+
950
+
951
+
952
+
953
+
954
+
955
+
956
+
957
+
958
+
959
+ * @example
960
+ * // Remove all occurrences
961
+ * const ms = new TreeMultiSet<number>();
962
+ * ms.add(1, 3);
963
+ * ms.deleteAll(1);
964
+ * console.log(ms.has(1)); // false;
965
+ */
966
+ deleteAll(key: K): boolean {
967
+ this._validateKey(key);
968
+ const old = this.#core.get(key) ?? 0;
969
+ if (old === 0) return false;
970
+ this.#core.delete(key);
971
+ this._size -= old;
972
+ return true;
973
+ }
974
+
975
+ /**
976
+ * Iterates over distinct keys (each key yielded once).
977
+ * @remarks Time O(n), Space O(1)
978
+
979
+
980
+
981
+
982
+
983
+
984
+
985
+
986
+
987
+
988
+
989
+
990
+
991
+
992
+
993
+
994
+
995
+
996
+
997
+
998
+
999
+
1000
+
1001
+
1002
+
1003
+
1004
+ * @example
1005
+ * // Iterate unique keys
1006
+ * const ms = new TreeMultiSet<number>();
1007
+ * ms.add(1, 2);
1008
+ * ms.add(2);
1009
+ * console.log([...ms.keysDistinct()]); // [1, 2];
1010
+ */
1011
+ *keysDistinct(): IterableIterator<K> {
1012
+ yield* this.#core.keys();
1013
+ }
1014
+
1015
+ /**
1016
+ * Iterates over entries as [key, count] pairs.
1017
+ * @remarks Time O(n), Space O(1)
1018
+
1019
+
1020
+
1021
+
1022
+
1023
+
1024
+
1025
+
1026
+
1027
+
1028
+
1029
+
1030
+
1031
+
1032
+
1033
+
1034
+
1035
+
1036
+
1037
+
1038
+
1039
+
1040
+
1041
+
1042
+
1043
+
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+
1052
+
1053
+
1054
+
1055
+
1056
+
1057
+
1058
+
1059
+
1060
+
1061
+
1062
+
1063
+
1064
+
1065
+
1066
+
1067
+
1068
+
1069
+
1070
+
1071
+
1072
+
1073
+
1074
+
1075
+
1076
+
1077
+
1078
+
1079
+
1080
+
1081
+
1082
+
1083
+
1084
+
1085
+
1086
+
1087
+
1088
+
1089
+
1090
+
1091
+
1092
+
1093
+
1094
+
1095
+
1096
+
1097
+
1098
+
1099
+
1100
+
1101
+
1102
+
1103
+
1104
+
1105
+
1106
+
1107
+
1108
+
1109
+
1110
+
1111
+
1112
+
1113
+
1114
+
1115
+
1116
+
1117
+
1118
+
1119
+
1120
+
1121
+
1122
+
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+
1131
+
1132
+
1133
+
1134
+
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+
1144
+
1145
+
1146
+
1147
+
1148
+
1149
+
1150
+
1151
+
1152
+
1153
+
1154
+
1155
+
1156
+
1157
+
1158
+
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+
1168
+
1169
+
1170
+
1171
+
1172
+
1173
+
1174
+
1175
+
1176
+ * @example
1177
+ * // Iterate entries
1178
+ * const ms = new TreeMultiSet<number>();
1179
+ * ms.add(1, 2);
1180
+ * console.log([...ms.entries()].length); // > 0;
1181
+ */
1182
+ *entries(): IterableIterator<[K, number]> {
1183
+ for (const [k, v] of this.#core) {
1184
+ yield [k, v ?? 0];
1185
+ }
1186
+ }
1187
+
1188
+ /**
1189
+ * Expanded iteration (default). Each key is yielded `count(key)` times.
1190
+ * @remarks Time O(size), Space O(1) where size is total occurrences
1191
+ */
1192
+ *[Symbol.iterator](): Iterator<K> {
1193
+ for (const [k, c] of this.entries()) {
1194
+ for (let i = 0; i < c; i++) yield k;
1195
+ }
1196
+ }
1197
+
1198
+ /**
1199
+ * Returns an array with all elements (expanded).
1200
+ * @remarks Time O(size), Space O(size)
1201
+
1202
+
1203
+
1204
+
1205
+
1206
+
1207
+
1208
+
1209
+
1210
+
1211
+
1212
+
1213
+
1214
+
1215
+
1216
+
1217
+
1218
+
1219
+
1220
+
1221
+
1222
+
1223
+
1224
+
1225
+
1226
+
1227
+
1228
+
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+
1237
+
1238
+
1239
+
1240
+
1241
+
1242
+
1243
+
1244
+
1245
+
1246
+
1247
+
1248
+
1249
+
1250
+
1251
+
1252
+
1253
+
1254
+
1255
+
1256
+
1257
+
1258
+
1259
+
1260
+
1261
+
1262
+
1263
+
1264
+
1265
+
1266
+
1267
+
1268
+
1269
+
1270
+
1271
+
1272
+
1273
+
1274
+
1275
+
1276
+
1277
+
1278
+
1279
+
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+
1287
+
1288
+
1289
+
1290
+
1291
+
1292
+
1293
+
1294
+
1295
+
1296
+
1297
+
1298
+
1299
+
1300
+
1301
+
1302
+
1303
+
1304
+
1305
+
1306
+
1307
+
1308
+
1309
+
1310
+
1311
+
1312
+
1313
+
1314
+
1315
+
1316
+
1317
+
1318
+
1319
+
1320
+
1321
+
1322
+
1323
+
1324
+
1325
+
1326
+
1327
+
1328
+
1329
+
1330
+
1331
+
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+
1339
+
1340
+
1341
+
1342
+
1343
+
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1357
+
1358
+
1359
+ * @example
1360
+ * // All elements (with duplicates)
1361
+ * const ms = new TreeMultiSet<number>();
1362
+ * ms.add(1, 2);
1363
+ * ms.add(2);
1364
+ * console.log(ms.toArray()); // [1, 1, 2];
1365
+ */
1366
+ toArray(): K[] {
1367
+ return [...this];
1368
+ }
1369
+
1370
+ /**
1371
+ * Returns an array with distinct keys only.
1372
+ * @remarks Time O(n), Space O(n)
1373
+
1374
+
1375
+
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+
1389
+
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+
1397
+
1398
+
1399
+ * @example
1400
+ * // Unique keys only
1401
+ * const ms = new TreeMultiSet<number>();
1402
+ * ms.add(1, 3);
1403
+ * ms.add(2);
1404
+ * console.log(ms.toDistinctArray()); // [1, 2];
1405
+ */
1406
+ toDistinctArray(): K[] {
1407
+ return [...this.keysDistinct()];
1408
+ }
1409
+
1410
+ /**
1411
+ * Returns an array of [key, count] entries.
1412
+ * @remarks Time O(n), Space O(n)
1413
+
1414
+
1415
+
1416
+
1417
+
1418
+
1419
+
1420
+
1421
+
1422
+
1423
+
1424
+
1425
+
1426
+
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+
1433
+
1434
+
1435
+
1436
+
1437
+
1438
+
1439
+ * @example
1440
+ * // Key-count pairs
1441
+ * const ms = new TreeMultiSet<number>();
1442
+ * ms.add(1, 2);
1443
+ * ms.add(3);
1444
+ * console.log(ms.toEntries()); // [[1, 2], [3, 1]];
1445
+ */
1446
+ toEntries(): Array<[K, number]> {
1447
+ return [...this.entries()];
1448
+ }
1449
+
1450
+ /**
1451
+ * Expose comparator for advanced usage/testing (read-only).
1452
+ * @remarks Time O(1), Space O(1)
1453
+ */
1454
+ get comparator(): Comparator<K> {
1455
+ return this.#core.comparator;
1456
+ }
1457
+
1458
+ // ━━━ clear ━━━
1459
+
1460
+ /**
1461
+ * Remove all elements from the multiset.
1462
+ * @remarks Time O(1), Space O(1)
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+
1482
+
1483
+
1484
+
1485
+
1486
+
1487
+
1488
+
1489
+
1490
+
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+
1511
+
1512
+
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+
1520
+
1521
+
1522
+
1523
+
1524
+
1525
+
1526
+
1527
+
1528
+
1529
+
1530
+
1531
+
1532
+
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+
1539
+
1540
+
1541
+
1542
+
1543
+
1544
+
1545
+
1546
+
1547
+
1548
+
1549
+
1550
+
1551
+
1552
+
1553
+
1554
+
1555
+
1556
+
1557
+
1558
+
1559
+
1560
+
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+
1567
+
1568
+
1569
+
1570
+
1571
+
1572
+
1573
+
1574
+
1575
+
1576
+
1577
+
1578
+
1579
+
1580
+
1581
+
1582
+
1583
+
1584
+
1585
+
1586
+
1587
+
1588
+
1589
+
1590
+
1591
+
1592
+
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+
1602
+
1603
+
1604
+
1605
+
1606
+
1607
+
1608
+
1609
+
1610
+
1611
+
1612
+
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+
1621
+
1622
+ * @example
1623
+ * // Remove all
1624
+ * const ms = new TreeMultiSet<number>();
1625
+ * ms.add(1);
1626
+ * ms.clear();
1627
+ * console.log(ms.isEmpty()); // true;
1628
+ */
1629
+ clear(): void {
1630
+ this.#core.clear();
1631
+ this._size = 0;
1632
+ }
1633
+
1634
+ // ━━━ Navigable methods ━━━
1635
+
1636
+ /**
1637
+ * Returns the smallest key, or undefined if empty.
1638
+ * @remarks Time O(log n), Space O(1)
1639
+
1640
+
1641
+
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+
1651
+
1652
+
1653
+
1654
+
1655
+
1656
+
1657
+
1658
+
1659
+
1660
+
1661
+
1662
+
1663
+
1664
+
1665
+
1666
+ * @example
1667
+ * // Smallest element
1668
+ * const ms = new TreeMultiSet<number>();
1669
+ * ms.add(3);
1670
+ * ms.add(1);
1671
+ * console.log(ms.first()); // 1;
1672
+ */
1673
+ first(): K | undefined {
1674
+ return this.#core.getLeftMost();
1675
+ }
1676
+
1677
+ /**
1678
+ * Returns the largest key, or undefined if empty.
1679
+ * @remarks Time O(log n), Space O(1)
1680
+
1681
+
1682
+
1683
+
1684
+
1685
+
1686
+
1687
+
1688
+
1689
+
1690
+
1691
+
1692
+
1693
+
1694
+
1695
+
1696
+
1697
+
1698
+
1699
+
1700
+
1701
+
1702
+
1703
+
1704
+
1705
+
1706
+
1707
+ * @example
1708
+ * // Largest element
1709
+ * const ms = new TreeMultiSet<number>();
1710
+ * ms.add(1);
1711
+ * ms.add(3);
1712
+ * console.log(ms.last()); // 3;
1713
+ */
1714
+ last(): K | undefined {
1715
+ return this.#core.getRightMost();
1716
+ }
1717
+
1718
+ /**
1719
+ * Removes all occurrences of the smallest key and returns it.
1720
+ * @remarks Time O(log n), Space O(1)
1721
+
1722
+
1723
+
1724
+
1725
+
1726
+
1727
+
1728
+
1729
+
1730
+
1731
+
1732
+
1733
+
1734
+
1735
+
1736
+
1737
+
1738
+
1739
+
1740
+
1741
+
1742
+
1743
+
1744
+
1745
+
1746
+
1747
+
1748
+ * @example
1749
+ * // Remove and return smallest
1750
+ * const ms = new TreeMultiSet<number>();
1751
+ * ms.add(2);
1752
+ * ms.add(1);
1753
+ * console.log(ms.pollFirst()); // 1;
1754
+ * console.log(ms.has(1)); // false;
1755
+ */
1756
+ pollFirst(): K | undefined {
1757
+ const key = this.first();
1758
+ if (key === undefined) return undefined;
1759
+ this.deleteAll(key);
1760
+ return key;
1761
+ }
1762
+
1763
+ /**
1764
+ * Removes all occurrences of the largest key and returns it.
1765
+ * @remarks Time O(log n), Space O(1)
1766
+
1767
+
1768
+
1769
+
1770
+
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+
1778
+
1779
+
1780
+
1781
+
1782
+
1783
+
1784
+
1785
+
1786
+
1787
+
1788
+
1789
+
1790
+
1791
+
1792
+
1793
+ * @example
1794
+ * // Remove and return largest
1795
+ * const ms = new TreeMultiSet<number>();
1796
+ * ms.add(1);
1797
+ * ms.add(3);
1798
+ * console.log(ms.pollLast()); // 3;
1799
+ */
1800
+ pollLast(): K | undefined {
1801
+ const key = this.last();
1802
+ if (key === undefined) return undefined;
1803
+ this.deleteAll(key);
1804
+ return key;
1805
+ }
1806
+
1807
+ /**
1808
+ * Returns the smallest key >= given key, or undefined.
1809
+ * @remarks Time O(log n), Space O(1)
1810
+
1811
+
1812
+
1813
+
1814
+
1815
+
1816
+
1817
+
1818
+
1819
+
1820
+
1821
+
1822
+
1823
+
1824
+
1825
+
1826
+
1827
+
1828
+
1829
+
1830
+
1831
+
1832
+
1833
+
1834
+
1835
+
1836
+
1837
+
1838
+
1839
+
1840
+
1841
+
1842
+
1843
+
1844
+
1845
+
1846
+
1847
+
1848
+
1849
+
1850
+
1851
+
1852
+
1853
+
1854
+
1855
+
1856
+
1857
+
1858
+
1859
+
1860
+
1861
+
1862
+
1863
+
1864
+
1865
+
1866
+
1867
+
1868
+
1869
+
1870
+
1871
+
1872
+
1873
+
1874
+
1875
+
1876
+
1877
+
1878
+
1879
+
1880
+
1881
+
1882
+
1883
+
1884
+
1885
+
1886
+
1887
+
1888
+
1889
+
1890
+
1891
+
1892
+
1893
+
1894
+
1895
+
1896
+
1897
+
1898
+
1899
+
1900
+
1901
+
1902
+
1903
+
1904
+
1905
+
1906
+
1907
+
1908
+
1909
+
1910
+
1911
+
1912
+
1913
+
1914
+
1915
+
1916
+
1917
+
1918
+
1919
+
1920
+
1921
+
1922
+
1923
+
1924
+
1925
+
1926
+
1927
+
1928
+
1929
+
1930
+
1931
+
1932
+
1933
+
1934
+
1935
+
1936
+ * @example
1937
+ * // Least key ≥ target
1938
+ * const ms = new TreeMultiSet<number>();
1939
+ * ms.add(10);
1940
+ * ms.add(20);
1941
+ * ms.add(30);
1942
+ * console.log(ms.ceiling(15)); // 20;
1943
+ */
1944
+ ceiling(key: K): K | undefined {
1945
+ this._validateKey(key);
1946
+ return this.#core.ceiling(key);
1947
+ }
1948
+
1949
+ /**
1950
+ * Returns the largest key <= given key, or undefined.
1951
+ * @remarks Time O(log n), Space O(1)
1952
+
1953
+
1954
+
1955
+
1956
+
1957
+
1958
+
1959
+
1960
+
1961
+
1962
+
1963
+
1964
+
1965
+
1966
+
1967
+
1968
+
1969
+
1970
+
1971
+
1972
+
1973
+
1974
+
1975
+
1976
+
1977
+
1978
+
1979
+
1980
+
1981
+
1982
+
1983
+
1984
+
1985
+
1986
+
1987
+
1988
+
1989
+
1990
+
1991
+
1992
+
1993
+
1994
+
1995
+
1996
+
1997
+
1998
+
1999
+
2000
+
2001
+
2002
+
2003
+
2004
+
2005
+
2006
+
2007
+
2008
+
2009
+
2010
+
2011
+
2012
+
2013
+
2014
+
2015
+
2016
+
2017
+
2018
+
2019
+
2020
+
2021
+
2022
+
2023
+
2024
+
2025
+
2026
+
2027
+
2028
+
2029
+
2030
+
2031
+
2032
+
2033
+
2034
+
2035
+
2036
+
2037
+
2038
+
2039
+
2040
+
2041
+
2042
+
2043
+
2044
+
2045
+
2046
+
2047
+
2048
+
2049
+
2050
+
2051
+
2052
+
2053
+
2054
+
2055
+
2056
+
2057
+
2058
+
2059
+
2060
+
2061
+
2062
+
2063
+
2064
+
2065
+
2066
+
2067
+
2068
+
2069
+
2070
+
2071
+
2072
+
2073
+
2074
+
2075
+
2076
+
2077
+
2078
+ * @example
2079
+ * // Greatest key ≤ target
2080
+ * const ms = new TreeMultiSet<number>();
2081
+ * ms.add(10);
2082
+ * ms.add(20);
2083
+ * ms.add(30);
2084
+ * console.log(ms.floor(25)); // 20;
2085
+ */
2086
+ floor(key: K): K | undefined {
2087
+ this._validateKey(key);
2088
+ return this.#core.floor(key);
2089
+ }
2090
+
2091
+ /**
2092
+ * Returns the smallest key > given key, or undefined.
2093
+ * @remarks Time O(log n), Space O(1)
2094
+
2095
+
2096
+
2097
+
2098
+
2099
+
2100
+
2101
+
2102
+
2103
+
2104
+
2105
+
2106
+
2107
+
2108
+
2109
+
2110
+
2111
+
2112
+
2113
+
2114
+
2115
+
2116
+
2117
+
2118
+
2119
+
2120
+
2121
+
2122
+
2123
+
2124
+
2125
+
2126
+
2127
+
2128
+
2129
+
2130
+
2131
+
2132
+
2133
+
2134
+
2135
+
2136
+
2137
+
2138
+
2139
+
2140
+
2141
+
2142
+
2143
+
2144
+
2145
+
2146
+
2147
+
2148
+
2149
+
2150
+
2151
+
2152
+
2153
+
2154
+
2155
+
2156
+
2157
+
2158
+
2159
+
2160
+
2161
+
2162
+
2163
+
2164
+
2165
+
2166
+
2167
+
2168
+
2169
+
2170
+
2171
+
2172
+
2173
+
2174
+
2175
+
2176
+
2177
+
2178
+
2179
+
2180
+
2181
+
2182
+
2183
+
2184
+
2185
+
2186
+
2187
+
2188
+
2189
+
2190
+
2191
+
2192
+
2193
+
2194
+
2195
+
2196
+
2197
+
2198
+
2199
+
2200
+
2201
+
2202
+
2203
+
2204
+
2205
+
2206
+
2207
+
2208
+
2209
+
2210
+
2211
+
2212
+
2213
+
2214
+
2215
+
2216
+
2217
+
2218
+
2219
+
2220
+ * @example
2221
+ * // Least key > target
2222
+ * const ms = new TreeMultiSet<number>();
2223
+ * ms.add(10);
2224
+ * ms.add(20);
2225
+ * console.log(ms.higher(10)); // 20;
2226
+ */
2227
+ higher(key: K): K | undefined {
2228
+ this._validateKey(key);
2229
+ return this.#core.higher(key);
2230
+ }
2231
+
2232
+ /**
2233
+ * Returns the largest key < given key, or undefined.
2234
+ * @remarks Time O(log n), Space O(1)
2235
+
2236
+
2237
+
2238
+
2239
+
2240
+
2241
+
2242
+
2243
+
2244
+
2245
+
2246
+
2247
+
2248
+
2249
+
2250
+
2251
+
2252
+
2253
+
2254
+
2255
+
2256
+
2257
+
2258
+
2259
+
2260
+
2261
+
2262
+
2263
+
2264
+
2265
+
2266
+
2267
+
2268
+
2269
+
2270
+
2271
+
2272
+
2273
+
2274
+
2275
+
2276
+
2277
+
2278
+
2279
+
2280
+
2281
+
2282
+
2283
+
2284
+
2285
+
2286
+
2287
+
2288
+
2289
+
2290
+
2291
+
2292
+
2293
+
2294
+
2295
+
2296
+
2297
+
2298
+
2299
+
2300
+
2301
+
2302
+
2303
+
2304
+
2305
+
2306
+
2307
+
2308
+
2309
+
2310
+
2311
+
2312
+
2313
+
2314
+
2315
+
2316
+
2317
+
2318
+
2319
+
2320
+
2321
+
2322
+
2323
+
2324
+
2325
+
2326
+
2327
+
2328
+
2329
+
2330
+
2331
+
2332
+
2333
+
2334
+
2335
+
2336
+
2337
+
2338
+
2339
+
2340
+
2341
+
2342
+
2343
+
2344
+
2345
+
2346
+
2347
+
2348
+
2349
+
2350
+
2351
+
2352
+
2353
+
2354
+
2355
+
2356
+
2357
+
2358
+
2359
+
2360
+
2361
+ * @example
2362
+ * // Greatest key < target
2363
+ * const ms = new TreeMultiSet<number>();
2364
+ * ms.add(10);
2365
+ * ms.add(20);
2366
+ * console.log(ms.lower(20)); // 10;
2367
+ */
2368
+ lower(key: K): K | undefined {
2369
+ this._validateKey(key);
2370
+ return this.#core.lower(key);
2371
+ }
2372
+
2373
+ // ━━━ Functional methods ━━━
2374
+
2375
+ /**
2376
+ * Iterates over distinct keys with their counts.
2377
+ * @remarks Time O(n), Space O(1)
2378
+
2379
+
2380
+
2381
+
2382
+
2383
+
2384
+
2385
+
2386
+
2387
+
2388
+
2389
+
2390
+
2391
+
2392
+
2393
+
2394
+
2395
+
2396
+
2397
+
2398
+
2399
+
2400
+
2401
+
2402
+
2403
+
2404
+
2405
+
2406
+
2407
+
2408
+
2409
+
2410
+
2411
+
2412
+
2413
+
2414
+
2415
+
2416
+
2417
+
2418
+
2419
+
2420
+
2421
+
2422
+
2423
+
2424
+
2425
+
2426
+
2427
+
2428
+
2429
+
2430
+
2431
+
2432
+
2433
+
2434
+
2435
+
2436
+
2437
+
2438
+
2439
+
2440
+
2441
+
2442
+
2443
+
2444
+
2445
+
2446
+
2447
+
2448
+
2449
+
2450
+
2451
+
2452
+
2453
+
2454
+
2455
+
2456
+
2457
+
2458
+
2459
+
2460
+
2461
+
2462
+
2463
+
2464
+
2465
+
2466
+
2467
+
2468
+
2469
+
2470
+
2471
+
2472
+
2473
+
2474
+
2475
+
2476
+
2477
+
2478
+
2479
+
2480
+
2481
+
2482
+
2483
+
2484
+
2485
+
2486
+
2487
+
2488
+
2489
+
2490
+
2491
+
2492
+
2493
+
2494
+
2495
+
2496
+
2497
+
2498
+
2499
+
2500
+
2501
+
2502
+
2503
+
2504
+
2505
+
2506
+
2507
+
2508
+
2509
+
2510
+
2511
+
2512
+
2513
+
2514
+
2515
+
2516
+
2517
+
2518
+
2519
+
2520
+
2521
+
2522
+
2523
+
2524
+
2525
+
2526
+
2527
+
2528
+
2529
+
2530
+
2531
+
2532
+
2533
+
2534
+
2535
+
2536
+
2537
+ * @example
2538
+ * // Iterate
2539
+ * const ms = new TreeMultiSet<number>();
2540
+ * ms.add(1, 2);
2541
+ * ms.add(2);
2542
+ * const pairs: [number, number][] = [];
2543
+ * ms.forEach((k, c) => pairs.push([k, c]));
2544
+ * console.log(pairs); // [[1, 2], [2, 1]];
2545
+ */
2546
+ forEach(callback: (key: K, count: number) => void): void {
2547
+ for (const [k, c] of this.entries()) {
2548
+ callback(k, c);
2549
+ }
2550
+ }
2551
+
2552
+ /**
2553
+ * Creates a new TreeMultiSet with entries that match the predicate.
2554
+ * @remarks Time O(n log n), Space O(n)
2555
+
2556
+
2557
+
2558
+
2559
+
2560
+
2561
+
2562
+
2563
+
2564
+
2565
+
2566
+
2567
+
2568
+
2569
+
2570
+
2571
+
2572
+
2573
+
2574
+
2575
+
2576
+
2577
+
2578
+
2579
+
2580
+
2581
+
2582
+
2583
+
2584
+
2585
+
2586
+
2587
+
2588
+
2589
+
2590
+
2591
+
2592
+
2593
+
2594
+
2595
+
2596
+
2597
+
2598
+
2599
+
2600
+
2601
+
2602
+
2603
+
2604
+
2605
+
2606
+
2607
+
2608
+
2609
+
2610
+
2611
+
2612
+
2613
+
2614
+
2615
+
2616
+
2617
+
2618
+
2619
+
2620
+
2621
+
2622
+
2623
+
2624
+
2625
+
2626
+
2627
+
2628
+
2629
+
2630
+
2631
+
2632
+
2633
+
2634
+
2635
+
2636
+
2637
+
2638
+
2639
+
2640
+
2641
+
2642
+
2643
+
2644
+
2645
+
2646
+
2647
+
2648
+
2649
+
2650
+
2651
+
2652
+
2653
+
2654
+
2655
+
2656
+
2657
+
2658
+
2659
+
2660
+
2661
+
2662
+
2663
+
2664
+
2665
+
2666
+
2667
+
2668
+
2669
+
2670
+
2671
+
2672
+
2673
+
2674
+
2675
+
2676
+
2677
+
2678
+
2679
+
2680
+
2681
+
2682
+
2683
+
2684
+
2685
+
2686
+
2687
+
2688
+
2689
+
2690
+
2691
+
2692
+
2693
+
2694
+
2695
+
2696
+
2697
+
2698
+
2699
+
2700
+
2701
+
2702
+
2703
+
2704
+
2705
+
2706
+
2707
+
2708
+
2709
+
2710
+
2711
+
2712
+
2713
+
2714
+ * @example
2715
+ * // Filter
2716
+ * const ms = new TreeMultiSet<number>();
2717
+ * ms.add(1, 3);
2718
+ * ms.add(2, 1);
2719
+ * ms.add(3, 2);
2720
+ * const filtered = ms.filter((k, c) => c > 1);
2721
+ * console.log([...filtered.keysDistinct()]); // [1, 3];
2722
+ */
2723
+ filter(predicate: (key: K, count: number) => boolean): TreeMultiSet<K> {
2724
+ const result = new TreeMultiSet<K>([], {
2725
+ comparator: this.#isDefaultComparator ? undefined : this.comparator,
2726
+ isMapMode: this.#core.isMapMode
2727
+ });
2728
+ for (const [k, c] of this.entries()) {
2729
+ if (predicate(k, c)) {
2730
+ result.add(k, c);
2731
+ }
2732
+ }
2733
+ return result;
2734
+ }
2735
+
2736
+ /**
2737
+ * Reduces the multiset to a single value.
2738
+ * @remarks Time O(n), Space O(1)
2739
+
2740
+
2741
+
2742
+
2743
+
2744
+
2745
+
2746
+
2747
+
2748
+
2749
+
2750
+
2751
+
2752
+
2753
+
2754
+
2755
+
2756
+
2757
+
2758
+
2759
+
2760
+
2761
+
2762
+
2763
+
2764
+
2765
+
2766
+
2767
+
2768
+
2769
+
2770
+
2771
+
2772
+
2773
+
2774
+
2775
+
2776
+
2777
+
2778
+
2779
+
2780
+
2781
+
2782
+
2783
+
2784
+
2785
+
2786
+
2787
+
2788
+
2789
+
2790
+
2791
+
2792
+
2793
+
2794
+
2795
+
2796
+
2797
+
2798
+
2799
+
2800
+
2801
+
2802
+
2803
+
2804
+
2805
+
2806
+
2807
+
2808
+
2809
+
2810
+
2811
+
2812
+
2813
+
2814
+
2815
+
2816
+
2817
+
2818
+
2819
+
2820
+
2821
+
2822
+
2823
+
2824
+
2825
+
2826
+
2827
+
2828
+
2829
+
2830
+
2831
+
2832
+
2833
+
2834
+
2835
+
2836
+
2837
+
2838
+
2839
+
2840
+
2841
+
2842
+
2843
+
2844
+
2845
+
2846
+
2847
+
2848
+
2849
+
2850
+
2851
+
2852
+
2853
+
2854
+
2855
+
2856
+
2857
+
2858
+
2859
+
2860
+
2861
+
2862
+
2863
+
2864
+
2865
+
2866
+
2867
+
2868
+
2869
+
2870
+
2871
+
2872
+
2873
+
2874
+
2875
+
2876
+
2877
+
2878
+
2879
+
2880
+
2881
+
2882
+
2883
+
2884
+
2885
+
2886
+
2887
+
2888
+
2889
+
2890
+
2891
+
2892
+
2893
+
2894
+
2895
+
2896
+
2897
+
2898
+ * @example
2899
+ * // Aggregate
737
2900
  * const ms = new TreeMultiSet<number>();
738
- * ms.add(1);
739
- * ms.add(3);
740
- * console.log(ms.pollLast()); // 3;
2901
+ * ms.add(1, 2);
2902
+ * ms.add(2, 3);
2903
+ * const sum = ms.reduce((acc, k, c) => acc + k * c, 0);
2904
+ * console.log(sum); // 8;
741
2905
  */
742
- pollLast(): K | undefined {
743
- const key = this.last();
744
- if (key === undefined) return undefined;
745
- this.deleteAll(key);
746
- return key;
2906
+ reduce<U>(callback: (accumulator: U, key: K, count: number) => U, initialValue: U): U {
2907
+ let acc = initialValue;
2908
+ for (const [k, c] of this.entries()) {
2909
+ acc = callback(acc, k, c);
2910
+ }
2911
+ return acc;
747
2912
  }
748
2913
 
749
2914
  /**
750
- * Returns the smallest key >= given key, or undefined.
751
- * @remarks Time O(log n), Space O(1)
2915
+ * Maps keys and counts to a new TreeMultiSet.
2916
+ * When multiple keys map to the same new key, counts are merged (added).
2917
+ * @remarks Time O(n log n), Space O(n)
2918
+
2919
+
2920
+
2921
+
2922
+
2923
+
2924
+
2925
+
2926
+
2927
+
2928
+
2929
+
2930
+
2931
+
2932
+
2933
+
2934
+
2935
+
2936
+
2937
+
2938
+
2939
+
2940
+
2941
+
2942
+
2943
+
2944
+
2945
+
2946
+
2947
+
2948
+
2949
+
2950
+
2951
+
2952
+
2953
+
2954
+
2955
+
2956
+
2957
+
2958
+
2959
+
2960
+
2961
+
2962
+
2963
+
2964
+
2965
+
2966
+
2967
+
2968
+
2969
+
2970
+
2971
+
2972
+
2973
+
2974
+
2975
+
2976
+
2977
+
2978
+
2979
+
2980
+
2981
+
2982
+
2983
+
2984
+
2985
+
2986
+
2987
+
2988
+
2989
+
2990
+
2991
+
2992
+
2993
+
2994
+
2995
+
2996
+
2997
+
2998
+
2999
+
3000
+
3001
+
3002
+
3003
+
3004
+
3005
+
3006
+
3007
+
3008
+
3009
+
3010
+
3011
+
3012
+
3013
+
3014
+
3015
+
3016
+
3017
+
3018
+
3019
+
3020
+
3021
+
3022
+
3023
+
3024
+
3025
+
3026
+
3027
+
3028
+
3029
+
3030
+
3031
+
3032
+
3033
+
3034
+
3035
+
3036
+
3037
+
3038
+
3039
+
3040
+
3041
+
3042
+
3043
+
3044
+
3045
+
3046
+
3047
+
3048
+
3049
+
3050
+
3051
+
3052
+
3053
+
3054
+
3055
+
3056
+
3057
+
3058
+
3059
+
3060
+
3061
+
3062
+
3063
+
3064
+
3065
+
3066
+
3067
+
3068
+
3069
+
3070
+
3071
+
3072
+
3073
+
3074
+
3075
+
3076
+
3077
+ * @example
3078
+ * // Transform
3079
+ * const ms = new TreeMultiSet<number>();
3080
+ * ms.add(1, 2);
3081
+ * ms.add(2, 3);
3082
+ * const doubled = ms.map((k, c) => [k * 10, c] as [number, number]);
3083
+ * console.log([...doubled.keysDistinct()]); // [10, 20];
3084
+ */
3085
+ map<K2>(
3086
+ mapper: (key: K, count: number) => [K2, number],
3087
+ options?: { comparator?: Comparator<K2> }
3088
+ ): TreeMultiSet<K2> {
3089
+ const result = new TreeMultiSet<K2>([], {
3090
+ comparator: options?.comparator,
3091
+ isMapMode: this.#core.isMapMode
3092
+ });
3093
+ for (const [k, c] of this.entries()) {
3094
+ const [newKey, newCount] = mapper(k, c);
3095
+ result.add(newKey, newCount);
3096
+ }
3097
+ return result;
3098
+ }
3099
+
3100
+ /**
3101
+ * Creates an independent copy of this multiset.
3102
+ * @remarks Time O(n log n), Space O(n)
752
3103
 
753
3104
 
754
3105
 
@@ -783,23 +3134,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
783
3134
 
784
3135
 
785
3136
 
786
- * @example
787
- * // Least key ≥ target
788
- * const ms = new TreeMultiSet<number>();
789
- * ms.add(10);
790
- * ms.add(20);
791
- * ms.add(30);
792
- * console.log(ms.ceiling(15)); // 20;
793
- */
794
- ceiling(key: K): K | undefined {
795
- this._validateKey(key);
796
- return this.#core.ceiling(key);
797
- }
798
-
799
- /**
800
- * Returns the largest key <= given key, or undefined.
801
- * @remarks Time O(log n), Space O(1)
802
-
803
3137
 
804
3138
 
805
3139
 
@@ -833,23 +3167,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
833
3167
 
834
3168
 
835
3169
 
836
- * @example
837
- * // Greatest key ≤ target
838
- * const ms = new TreeMultiSet<number>();
839
- * ms.add(10);
840
- * ms.add(20);
841
- * ms.add(30);
842
- * console.log(ms.floor(25)); // 20;
843
- */
844
- floor(key: K): K | undefined {
845
- this._validateKey(key);
846
- return this.#core.floor(key);
847
- }
848
-
849
- /**
850
- * Returns the smallest key > given key, or undefined.
851
- * @remarks Time O(log n), Space O(1)
852
-
853
3170
 
854
3171
 
855
3172
 
@@ -883,22 +3200,30 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
883
3200
 
884
3201
 
885
3202
 
886
- * @example
887
- * // Least key > target
888
- * const ms = new TreeMultiSet<number>();
889
- * ms.add(10);
890
- * ms.add(20);
891
- * console.log(ms.higher(10)); // 20;
892
- */
893
- higher(key: K): K | undefined {
894
- this._validateKey(key);
895
- return this.#core.higher(key);
896
- }
897
-
898
- /**
899
- * Returns the largest key < given key, or undefined.
900
- * @remarks Time O(log n), Space O(1)
901
-
3203
+
3204
+
3205
+
3206
+
3207
+
3208
+
3209
+
3210
+
3211
+
3212
+
3213
+
3214
+
3215
+
3216
+
3217
+
3218
+
3219
+
3220
+
3221
+
3222
+
3223
+
3224
+
3225
+
3226
+
902
3227
 
903
3228
 
904
3229
 
@@ -933,26 +3258,88 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
933
3258
 
934
3259
 
935
3260
  * @example
936
- * // Greatest key < target
937
- * const ms = new TreeMultiSet<number>();
938
- * ms.add(10);
939
- * ms.add(20);
940
- * console.log(ms.lower(20)); // 10;
3261
+ * // Order-statistic on BST
3262
+ * const tree = new TreeMultiSet<number>([30, 10, 50, 20, 40], { enableOrderStatistic: true });
3263
+ * console.log(tree.getByRank(0)); // 10;
3264
+ * console.log(tree.getByRank(4)); // 50;
3265
+ * console.log(tree.getRank(30)); // 2;
941
3266
  */
942
- lower(key: K): K | undefined {
943
- this._validateKey(key);
944
- return this.#core.lower(key);
3267
+ // ─── Order-Statistic Methods ───────────────────────────
3268
+
3269
+ getByRank(k: number): K | undefined {
3270
+ return this.#core.getByRank(k);
945
3271
  }
946
3272
 
947
- // ━━━ Functional methods ━━━
3273
+ /**
3274
+ * Get the rank of a key in sorted order
3275
+ * @example
3276
+ * // Get the rank of a key in sorted order
3277
+ * const tree = new TreeMultiSet<number>(
3278
+ * [10, 20, 30, 40, 50],
3279
+ * { enableOrderStatistic: true }
3280
+ * );
3281
+ * console.log(tree.getRank(10)); // 0; // smallest → rank 0
3282
+ * console.log(tree.getRank(30)); // 2; // 2 elements before 30 in tree order
3283
+ * console.log(tree.getRank(50)); // 4; // largest → rank 4
3284
+ * console.log(tree.getRank(25)); // 2;
3285
+ */
3286
+ getRank(key: K): number {
3287
+ return this.#core.getRank(key);
3288
+ }
948
3289
 
949
- /**
950
- * Iterates over distinct keys with their counts.
951
- * @remarks Time O(n), Space O(1)
3290
+ /**
3291
+ * Get elements by rank range
3292
+
3293
+ * @example
3294
+ * // Pagination with rangeByRank
3295
+ * const tree = new TreeMultiSet<number>(
3296
+ * [10, 20, 30, 40, 50, 60, 70, 80, 90],
3297
+ * { enableOrderStatistic: true }
3298
+ * );
3299
+ * const pageSize = 3;
3300
+ *
3301
+ * // Page 1
3302
+ * console.log(tree.rangeByRank(0, pageSize - 1)); // [10, 20, 30];
3303
+ * // Page 2
3304
+ * console.log(tree.rangeByRank(pageSize, 2 * pageSize - 1)); // [40, 50, 60];
3305
+ * // Page 3
3306
+ * console.log(tree.rangeByRank(2 * pageSize, 3 * pageSize - 1)); // [70, 80, 90];
3307
+ */
3308
+ rangeByRank(start: number, end: number): K[] {
3309
+ return this.#core.rangeByRank(start, end).filter((k): k is K => k !== undefined);
3310
+ }
3311
+
3312
+ /**
3313
+ * Deep copy
952
3314
 
953
3315
 
954
3316
 
955
3317
 
3318
+ * @example
3319
+ * // Deep clone
3320
+ * const ms = new TreeMultiSet<number>();
3321
+ * ms.add(1, 3);
3322
+ * const copy = ms.clone();
3323
+ * copy.deleteAll(1);
3324
+ * console.log(ms.has(1)); // true;
3325
+ */
3326
+ clone(): TreeMultiSet<K> {
3327
+ const result = new TreeMultiSet<K>([], {
3328
+ comparator: this.#isDefaultComparator ? undefined : this.comparator,
3329
+ isMapMode: this.#core.isMapMode
3330
+ });
3331
+ for (const [k, c] of this.entries()) {
3332
+ result.add(k, c);
3333
+ }
3334
+ return result;
3335
+ }
3336
+
3337
+ // ━━━ Tree utilities ━━━
3338
+
3339
+ /**
3340
+ * Returns keys within the given range.
3341
+ * @remarks Time O(log n + k), Space O(k) where k is result size
3342
+
956
3343
 
957
3344
 
958
3345
 
@@ -993,26 +3380,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
993
3380
 
994
3381
 
995
3382
 
996
- * @example
997
- * // Iterate
998
- * const ms = new TreeMultiSet<number>();
999
- * ms.add(1, 2);
1000
- * ms.add(2);
1001
- * const pairs: [number, number][] = [];
1002
- * ms.forEach((k, c) => pairs.push([k, c]));
1003
- * console.log(pairs); // [[1, 2], [2, 1]];
1004
- */
1005
- forEach(callback: (key: K, count: number) => void): void {
1006
- for (const [k, c] of this.entries()) {
1007
- callback(k, c);
1008
- }
1009
- }
1010
-
1011
- /**
1012
- * Creates a new TreeMultiSet with entries that match the predicate.
1013
- * @remarks Time O(n log n), Space O(n)
1014
-
1015
-
1016
3383
 
1017
3384
 
1018
3385
 
@@ -1055,32 +3422,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1055
3422
 
1056
3423
 
1057
3424
 
1058
- * @example
1059
- * // Filter
1060
- * const ms = new TreeMultiSet<number>();
1061
- * ms.add(1, 3);
1062
- * ms.add(2, 1);
1063
- * ms.add(3, 2);
1064
- * const filtered = ms.filter((k, c) => c > 1);
1065
- * console.log([...filtered.keysDistinct()]); // [1, 3];
1066
- */
1067
- filter(predicate: (key: K, count: number) => boolean): TreeMultiSet<K> {
1068
- const result = new TreeMultiSet<K>([], {
1069
- comparator: this.#isDefaultComparator ? undefined : this.comparator,
1070
- isMapMode: this.#core.isMapMode
1071
- });
1072
- for (const [k, c] of this.entries()) {
1073
- if (predicate(k, c)) {
1074
- result.add(k, c);
1075
- }
1076
- }
1077
- return result;
1078
- }
1079
-
1080
- /**
1081
- * Reduces the multiset to a single value.
1082
- * @remarks Time O(n), Space O(1)
1083
-
1084
3425
 
1085
3426
 
1086
3427
 
@@ -1125,25 +3466,25 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1125
3466
 
1126
3467
 
1127
3468
  * @example
1128
- * // Aggregate
3469
+ * // Find in range
1129
3470
  * const ms = new TreeMultiSet<number>();
1130
- * ms.add(1, 2);
1131
- * ms.add(2, 3);
1132
- * const sum = ms.reduce((acc, k, c) => acc + k * c, 0);
1133
- * console.log(sum); // 8;
3471
+ * ms.add(10);
3472
+ * ms.add(20);
3473
+ * ms.add(30);
3474
+ * const result = ms.rangeSearch([15, 25]);
3475
+ * console.log(result.length); // 1;
1134
3476
  */
1135
- reduce<U>(callback: (accumulator: U, key: K, count: number) => U, initialValue: U): U {
1136
- let acc = initialValue;
1137
- for (const [k, c] of this.entries()) {
1138
- acc = callback(acc, k, c);
1139
- }
1140
- return acc;
3477
+ rangeSearch<C extends (key: K) => any>(
3478
+ range: [K, K],
3479
+ callback?: C
3480
+ ): (C extends undefined ? K : ReturnType<C>)[] {
3481
+ const cb = callback ?? ((k: K) => k);
3482
+ return this.#core.rangeSearch(range, node => cb(node.key));
1141
3483
  }
1142
3484
 
1143
3485
  /**
1144
- * Maps keys and counts to a new TreeMultiSet.
1145
- * When multiple keys map to the same new key, counts are merged (added).
1146
- * @remarks Time O(n log n), Space O(n)
3486
+ * Prints the internal tree structure (for debugging).
3487
+ * @remarks Time O(n), Space O(n)
1147
3488
 
1148
3489
 
1149
3490
 
@@ -1188,37 +3529,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1188
3529
 
1189
3530
 
1190
3531
 
1191
- * @example
1192
- * // Transform
1193
- * const ms = new TreeMultiSet<number>();
1194
- * ms.add(1, 2);
1195
- * ms.add(2, 3);
1196
- * const doubled = ms.map((k, c) => [k * 10, c] as [number, number]);
1197
- * console.log([...doubled.keysDistinct()]); // [10, 20];
1198
- */
1199
- map<K2>(
1200
- mapper: (key: K, count: number) => [K2, number],
1201
- options?: { comparator?: Comparator<K2> }
1202
- ): TreeMultiSet<K2> {
1203
- const result = new TreeMultiSet<K2>([], {
1204
- comparator: options?.comparator,
1205
- isMapMode: this.#core.isMapMode
1206
- });
1207
- for (const [k, c] of this.entries()) {
1208
- const [newKey, newCount] = mapper(k, c);
1209
- result.add(newKey, newCount);
1210
- }
1211
- return result;
1212
- }
1213
-
1214
- /**
1215
- * Creates an independent copy of this multiset.
1216
- * @remarks Time O(n log n), Space O(n)
1217
-
1218
-
1219
-
1220
-
1221
-
1222
3532
 
1223
3533
 
1224
3534
 
@@ -1258,31 +3568,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1258
3568
 
1259
3569
 
1260
3570
 
1261
- * @example
1262
- * // Deep clone
1263
- * const ms = new TreeMultiSet<number>();
1264
- * ms.add(1, 3);
1265
- * const copy = ms.clone();
1266
- * copy.deleteAll(1);
1267
- * console.log(ms.has(1)); // true;
1268
- */
1269
- clone(): TreeMultiSet<K> {
1270
- const result = new TreeMultiSet<K>([], {
1271
- comparator: this.#isDefaultComparator ? undefined : this.comparator,
1272
- isMapMode: this.#core.isMapMode
1273
- });
1274
- for (const [k, c] of this.entries()) {
1275
- result.add(k, c);
1276
- }
1277
- return result;
1278
- }
1279
-
1280
- // ━━━ Tree utilities ━━━
1281
-
1282
- /**
1283
- * Returns keys within the given range.
1284
- * @remarks Time O(log n + k), Space O(k) where k is result size
1285
-
1286
3571
 
1287
3572
 
1288
3573
 
@@ -1316,27 +3601,6 @@ export class TreeMultiSet<K = any, R = K> implements Iterable<K> {
1316
3601
 
1317
3602
 
1318
3603
 
1319
- * @example
1320
- * // Find in range
1321
- * const ms = new TreeMultiSet<number>();
1322
- * ms.add(10);
1323
- * ms.add(20);
1324
- * ms.add(30);
1325
- * const result = ms.rangeSearch([15, 25]);
1326
- * console.log(result.length); // 1;
1327
- */
1328
- rangeSearch<C extends (key: K) => any>(
1329
- range: [K, K],
1330
- callback?: C
1331
- ): (C extends undefined ? K : ReturnType<C>)[] {
1332
- const cb = callback ?? ((k: K) => k);
1333
- return this.#core.rangeSearch(range, node => cb(node.key));
1334
- }
1335
-
1336
- /**
1337
- * Prints the internal tree structure (for debugging).
1338
- * @remarks Time O(n), Space O(n)
1339
-
1340
3604
 
1341
3605
 
1342
3606