data-structure-typed 2.0.5 → 2.1.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 (260) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/COMMANDS.md +17 -0
  3. package/benchmark/report.html +13 -77
  4. package/benchmark/report.json +145 -177
  5. package/dist/cjs/data-structures/base/iterable-element-base.d.ts +186 -83
  6. package/dist/cjs/data-structures/base/iterable-element-base.js +149 -107
  7. package/dist/cjs/data-structures/base/iterable-element-base.js.map +1 -1
  8. package/dist/cjs/data-structures/base/iterable-entry-base.d.ts +95 -119
  9. package/dist/cjs/data-structures/base/iterable-entry-base.js +59 -116
  10. package/dist/cjs/data-structures/base/iterable-entry-base.js.map +1 -1
  11. package/dist/cjs/data-structures/base/linear-base.d.ts +250 -192
  12. package/dist/cjs/data-structures/base/linear-base.js +137 -274
  13. package/dist/cjs/data-structures/base/linear-base.js.map +1 -1
  14. package/dist/cjs/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
  15. package/dist/cjs/data-structures/binary-tree/avl-tree-counter.js +171 -205
  16. package/dist/cjs/data-structures/binary-tree/avl-tree-counter.js.map +1 -1
  17. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
  18. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
  19. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  20. package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +138 -149
  21. package/dist/cjs/data-structures/binary-tree/avl-tree.js +208 -195
  22. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  23. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +476 -632
  24. package/dist/cjs/data-structures/binary-tree/binary-tree.js +594 -865
  25. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  26. package/dist/cjs/data-structures/binary-tree/bst.d.ts +258 -306
  27. package/dist/cjs/data-structures/binary-tree/bst.js +505 -481
  28. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  29. package/dist/cjs/data-structures/binary-tree/red-black-tree.d.ts +107 -179
  30. package/dist/cjs/data-structures/binary-tree/red-black-tree.js +114 -209
  31. package/dist/cjs/data-structures/binary-tree/red-black-tree.js.map +1 -1
  32. package/dist/cjs/data-structures/binary-tree/tree-counter.d.ts +132 -154
  33. package/dist/cjs/data-structures/binary-tree/tree-counter.js +172 -203
  34. package/dist/cjs/data-structures/binary-tree/tree-counter.js.map +1 -1
  35. package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
  36. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +105 -85
  37. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  38. package/dist/cjs/data-structures/graph/abstract-graph.d.ts +238 -233
  39. package/dist/cjs/data-structures/graph/abstract-graph.js +267 -237
  40. package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
  41. package/dist/cjs/data-structures/graph/directed-graph.d.ts +108 -224
  42. package/dist/cjs/data-structures/graph/directed-graph.js +146 -233
  43. package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
  44. package/dist/cjs/data-structures/graph/map-graph.d.ts +49 -55
  45. package/dist/cjs/data-structures/graph/map-graph.js +56 -59
  46. package/dist/cjs/data-structures/graph/map-graph.js.map +1 -1
  47. package/dist/cjs/data-structures/graph/undirected-graph.d.ts +103 -146
  48. package/dist/cjs/data-structures/graph/undirected-graph.js +129 -149
  49. package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
  50. package/dist/cjs/data-structures/hash/hash-map.d.ts +164 -338
  51. package/dist/cjs/data-structures/hash/hash-map.js +270 -457
  52. package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
  53. package/dist/cjs/data-structures/heap/heap.d.ts +214 -289
  54. package/dist/cjs/data-structures/heap/heap.js +340 -349
  55. package/dist/cjs/data-structures/heap/heap.js.map +1 -1
  56. package/dist/cjs/data-structures/heap/max-heap.d.ts +11 -47
  57. package/dist/cjs/data-structures/heap/max-heap.js +11 -66
  58. package/dist/cjs/data-structures/heap/max-heap.js.map +1 -1
  59. package/dist/cjs/data-structures/heap/min-heap.d.ts +12 -47
  60. package/dist/cjs/data-structures/heap/min-heap.js +11 -66
  61. package/dist/cjs/data-structures/heap/min-heap.js.map +1 -1
  62. package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
  63. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +368 -494
  64. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  65. package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +261 -310
  66. package/dist/cjs/data-structures/linked-list/singly-linked-list.js +447 -466
  67. package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
  68. package/dist/cjs/data-structures/linked-list/skip-linked-list.d.ts +0 -107
  69. package/dist/cjs/data-structures/linked-list/skip-linked-list.js +0 -100
  70. package/dist/cjs/data-structures/linked-list/skip-linked-list.js.map +1 -1
  71. package/dist/cjs/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
  72. package/dist/cjs/data-structures/priority-queue/max-priority-queue.js +11 -78
  73. package/dist/cjs/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  74. package/dist/cjs/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
  75. package/dist/cjs/data-structures/priority-queue/min-priority-queue.js +10 -79
  76. package/dist/cjs/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  77. package/dist/cjs/data-structures/priority-queue/priority-queue.d.ts +2 -61
  78. package/dist/cjs/data-structures/priority-queue/priority-queue.js +8 -83
  79. package/dist/cjs/data-structures/priority-queue/priority-queue.js.map +1 -1
  80. package/dist/cjs/data-structures/queue/deque.d.ts +227 -254
  81. package/dist/cjs/data-structures/queue/deque.js +309 -348
  82. package/dist/cjs/data-structures/queue/deque.js.map +1 -1
  83. package/dist/cjs/data-structures/queue/queue.d.ts +180 -201
  84. package/dist/cjs/data-structures/queue/queue.js +265 -248
  85. package/dist/cjs/data-structures/queue/queue.js.map +1 -1
  86. package/dist/cjs/data-structures/stack/stack.d.ts +124 -102
  87. package/dist/cjs/data-structures/stack/stack.js +181 -125
  88. package/dist/cjs/data-structures/stack/stack.js.map +1 -1
  89. package/dist/cjs/data-structures/trie/trie.d.ts +164 -165
  90. package/dist/cjs/data-structures/trie/trie.js +189 -172
  91. package/dist/cjs/data-structures/trie/trie.js.map +1 -1
  92. package/dist/cjs/interfaces/binary-tree.d.ts +56 -6
  93. package/dist/cjs/interfaces/graph.d.ts +16 -0
  94. package/dist/cjs/types/data-structures/base/base.d.ts +1 -1
  95. package/dist/cjs/types/data-structures/graph/abstract-graph.d.ts +4 -0
  96. package/dist/cjs/types/utils/utils.d.ts +1 -0
  97. package/dist/cjs/utils/utils.d.ts +1 -1
  98. package/dist/cjs/utils/utils.js +2 -1
  99. package/dist/cjs/utils/utils.js.map +1 -1
  100. package/dist/esm/data-structures/base/iterable-element-base.d.ts +186 -83
  101. package/dist/esm/data-structures/base/iterable-element-base.js +155 -107
  102. package/dist/esm/data-structures/base/iterable-element-base.js.map +1 -1
  103. package/dist/esm/data-structures/base/iterable-entry-base.d.ts +95 -119
  104. package/dist/esm/data-structures/base/iterable-entry-base.js +59 -116
  105. package/dist/esm/data-structures/base/iterable-entry-base.js.map +1 -1
  106. package/dist/esm/data-structures/base/linear-base.d.ts +250 -192
  107. package/dist/esm/data-structures/base/linear-base.js +137 -274
  108. package/dist/esm/data-structures/base/linear-base.js.map +1 -1
  109. package/dist/esm/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
  110. package/dist/esm/data-structures/binary-tree/avl-tree-counter.js +171 -212
  111. package/dist/esm/data-structures/binary-tree/avl-tree-counter.js.map +1 -1
  112. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
  113. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js +133 -94
  114. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  115. package/dist/esm/data-structures/binary-tree/avl-tree.d.ts +138 -149
  116. package/dist/esm/data-structures/binary-tree/avl-tree.js +206 -200
  117. package/dist/esm/data-structures/binary-tree/avl-tree.js.map +1 -1
  118. package/dist/esm/data-structures/binary-tree/binary-tree.d.ts +476 -632
  119. package/dist/esm/data-structures/binary-tree/binary-tree.js +598 -874
  120. package/dist/esm/data-structures/binary-tree/binary-tree.js.map +1 -1
  121. package/dist/esm/data-structures/binary-tree/bst.d.ts +258 -306
  122. package/dist/esm/data-structures/binary-tree/bst.js +507 -487
  123. package/dist/esm/data-structures/binary-tree/bst.js.map +1 -1
  124. package/dist/esm/data-structures/binary-tree/red-black-tree.d.ts +107 -179
  125. package/dist/esm/data-structures/binary-tree/red-black-tree.js +114 -215
  126. package/dist/esm/data-structures/binary-tree/red-black-tree.js.map +1 -1
  127. package/dist/esm/data-structures/binary-tree/tree-counter.d.ts +132 -154
  128. package/dist/esm/data-structures/binary-tree/tree-counter.js +175 -209
  129. package/dist/esm/data-structures/binary-tree/tree-counter.js.map +1 -1
  130. package/dist/esm/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
  131. package/dist/esm/data-structures/binary-tree/tree-multi-map.js +103 -92
  132. package/dist/esm/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  133. package/dist/esm/data-structures/graph/abstract-graph.d.ts +238 -233
  134. package/dist/esm/data-structures/graph/abstract-graph.js +267 -237
  135. package/dist/esm/data-structures/graph/abstract-graph.js.map +1 -1
  136. package/dist/esm/data-structures/graph/directed-graph.d.ts +108 -224
  137. package/dist/esm/data-structures/graph/directed-graph.js +145 -233
  138. package/dist/esm/data-structures/graph/directed-graph.js.map +1 -1
  139. package/dist/esm/data-structures/graph/map-graph.d.ts +49 -55
  140. package/dist/esm/data-structures/graph/map-graph.js +56 -59
  141. package/dist/esm/data-structures/graph/map-graph.js.map +1 -1
  142. package/dist/esm/data-structures/graph/undirected-graph.d.ts +103 -146
  143. package/dist/esm/data-structures/graph/undirected-graph.js +128 -149
  144. package/dist/esm/data-structures/graph/undirected-graph.js.map +1 -1
  145. package/dist/esm/data-structures/hash/hash-map.d.ts +164 -338
  146. package/dist/esm/data-structures/hash/hash-map.js +270 -457
  147. package/dist/esm/data-structures/hash/hash-map.js.map +1 -1
  148. package/dist/esm/data-structures/heap/heap.d.ts +214 -289
  149. package/dist/esm/data-structures/heap/heap.js +329 -349
  150. package/dist/esm/data-structures/heap/heap.js.map +1 -1
  151. package/dist/esm/data-structures/heap/max-heap.d.ts +11 -47
  152. package/dist/esm/data-structures/heap/max-heap.js +11 -66
  153. package/dist/esm/data-structures/heap/max-heap.js.map +1 -1
  154. package/dist/esm/data-structures/heap/min-heap.d.ts +12 -47
  155. package/dist/esm/data-structures/heap/min-heap.js +11 -66
  156. package/dist/esm/data-structures/heap/min-heap.js.map +1 -1
  157. package/dist/esm/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
  158. package/dist/esm/data-structures/linked-list/doubly-linked-list.js +368 -495
  159. package/dist/esm/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  160. package/dist/esm/data-structures/linked-list/singly-linked-list.d.ts +261 -310
  161. package/dist/esm/data-structures/linked-list/singly-linked-list.js +448 -467
  162. package/dist/esm/data-structures/linked-list/singly-linked-list.js.map +1 -1
  163. package/dist/esm/data-structures/linked-list/skip-linked-list.d.ts +0 -107
  164. package/dist/esm/data-structures/linked-list/skip-linked-list.js +0 -100
  165. package/dist/esm/data-structures/linked-list/skip-linked-list.js.map +1 -1
  166. package/dist/esm/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
  167. package/dist/esm/data-structures/priority-queue/max-priority-queue.js +11 -78
  168. package/dist/esm/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  169. package/dist/esm/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
  170. package/dist/esm/data-structures/priority-queue/min-priority-queue.js +10 -79
  171. package/dist/esm/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  172. package/dist/esm/data-structures/priority-queue/priority-queue.d.ts +2 -61
  173. package/dist/esm/data-structures/priority-queue/priority-queue.js +8 -83
  174. package/dist/esm/data-structures/priority-queue/priority-queue.js.map +1 -1
  175. package/dist/esm/data-structures/queue/deque.d.ts +227 -254
  176. package/dist/esm/data-structures/queue/deque.js +313 -348
  177. package/dist/esm/data-structures/queue/deque.js.map +1 -1
  178. package/dist/esm/data-structures/queue/queue.d.ts +180 -201
  179. package/dist/esm/data-structures/queue/queue.js +263 -248
  180. package/dist/esm/data-structures/queue/queue.js.map +1 -1
  181. package/dist/esm/data-structures/stack/stack.d.ts +124 -102
  182. package/dist/esm/data-structures/stack/stack.js +181 -125
  183. package/dist/esm/data-structures/stack/stack.js.map +1 -1
  184. package/dist/esm/data-structures/trie/trie.d.ts +164 -165
  185. package/dist/esm/data-structures/trie/trie.js +193 -172
  186. package/dist/esm/data-structures/trie/trie.js.map +1 -1
  187. package/dist/esm/interfaces/binary-tree.d.ts +56 -6
  188. package/dist/esm/interfaces/graph.d.ts +16 -0
  189. package/dist/esm/types/data-structures/base/base.d.ts +1 -1
  190. package/dist/esm/types/data-structures/graph/abstract-graph.d.ts +4 -0
  191. package/dist/esm/types/utils/utils.d.ts +1 -0
  192. package/dist/esm/utils/utils.d.ts +1 -1
  193. package/dist/esm/utils/utils.js +2 -1
  194. package/dist/esm/utils/utils.js.map +1 -1
  195. package/dist/umd/data-structure-typed.js +4685 -6477
  196. package/dist/umd/data-structure-typed.min.js +8 -6
  197. package/dist/umd/data-structure-typed.min.js.map +1 -1
  198. package/package.json +3 -4
  199. package/src/data-structures/base/iterable-element-base.ts +238 -115
  200. package/src/data-structures/base/iterable-entry-base.ts +96 -120
  201. package/src/data-structures/base/linear-base.ts +271 -277
  202. package/src/data-structures/binary-tree/avl-tree-counter.ts +198 -216
  203. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +192 -101
  204. package/src/data-structures/binary-tree/avl-tree.ts +239 -206
  205. package/src/data-structures/binary-tree/binary-tree.ts +660 -889
  206. package/src/data-structures/binary-tree/bst.ts +568 -570
  207. package/src/data-structures/binary-tree/red-black-tree.ts +161 -222
  208. package/src/data-structures/binary-tree/tree-counter.ts +199 -218
  209. package/src/data-structures/binary-tree/tree-multi-map.ts +131 -97
  210. package/src/data-structures/graph/abstract-graph.ts +339 -264
  211. package/src/data-structures/graph/directed-graph.ts +146 -236
  212. package/src/data-structures/graph/map-graph.ts +63 -60
  213. package/src/data-structures/graph/undirected-graph.ts +129 -152
  214. package/src/data-structures/hash/hash-map.ts +274 -496
  215. package/src/data-structures/heap/heap.ts +389 -402
  216. package/src/data-structures/heap/max-heap.ts +12 -76
  217. package/src/data-structures/heap/min-heap.ts +13 -76
  218. package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
  219. package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
  220. package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
  221. package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
  222. package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
  223. package/src/data-structures/priority-queue/priority-queue.ts +3 -92
  224. package/src/data-structures/queue/deque.ts +381 -357
  225. package/src/data-structures/queue/queue.ts +310 -264
  226. package/src/data-structures/stack/stack.ts +217 -131
  227. package/src/data-structures/trie/trie.ts +240 -175
  228. package/src/interfaces/binary-tree.ts +240 -6
  229. package/src/interfaces/graph.ts +37 -0
  230. package/src/types/data-structures/base/base.ts +5 -5
  231. package/src/types/data-structures/graph/abstract-graph.ts +5 -0
  232. package/src/types/utils/utils.ts +2 -0
  233. package/src/utils/utils.ts +9 -14
  234. package/test/integration/index.html +1 -1
  235. package/test/performance/benchmark-runner.ts +528 -0
  236. package/test/performance/reportor.mjs +43 -43
  237. package/test/performance/runner-config.json +39 -0
  238. package/test/performance/single-suite-runner.ts +69 -0
  239. package/test/unit/data-structures/binary-tree/avl-tree-counter.test.ts +3 -3
  240. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +5 -5
  241. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +4 -4
  242. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +350 -90
  243. package/test/unit/data-structures/binary-tree/bst.test.ts +12 -9
  244. package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +2 -2
  245. package/test/unit/data-structures/binary-tree/tree-counter.test.ts +25 -24
  246. package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +3 -3
  247. package/test/unit/data-structures/graph/abstract-graph.test.ts +0 -4
  248. package/test/unit/data-structures/graph/directed-graph.test.ts +1 -1
  249. package/test/unit/data-structures/heap/heap.test.ts +14 -21
  250. package/test/unit/data-structures/heap/max-heap.test.ts +5 -9
  251. package/test/unit/data-structures/heap/min-heap.test.ts +1 -4
  252. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +14 -14
  253. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +0 -7
  254. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +8 -11
  255. package/test/unit/data-structures/priority-queue/min-priority-queue.test.ts +1 -4
  256. package/test/unit/data-structures/priority-queue/priority-queue.test.ts +1 -4
  257. package/test/unit/data-structures/queue/queue.test.ts +4 -5
  258. package/test/unit/utils/utils.test.ts +0 -1
  259. package/test/performance/data-structures/binary-tree/avl-tree.test.mjs +0 -71
  260. package/test/performance/data-structures/binary-tree/red-black-tree.test.mjs +0 -81
@@ -1,11 +1,16 @@
1
1
  /**
2
2
  * data-structure-typed
3
- * @author Kirk Qi
4
- * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>
3
+ *
4
+ * @author Pablo Zeng
5
+ * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
5
6
  * @license MIT License
6
7
  */
7
8
  import { IterableElementBase } from '../base';
8
9
  /**
10
+ * Binary heap with pluggable comparator; supports fast insertion and removal of the top element.
11
+ * @remarks Time O(1), Space O(1)
12
+ * @template E
13
+ * @template R
9
14
  * 1. Complete Binary Tree: Heaps are typically complete binary trees, meaning every level is fully filled except possibly for the last level, which has nodes as far left as possible.
10
15
  * 2. Heap Properties: Each node in a heap follows a specific order property, which varies depending on the type of heap:
11
16
  * Max Heap: The value of each parent node is greater than or equal to the value of its children.
@@ -183,18 +188,13 @@ import { IterableElementBase } from '../base';
183
188
  * console.log(scheduleTasks(tasks, 2)); // expectedMap
184
189
  */
185
190
  export class Heap extends IterableElementBase {
191
+ _equals = Object.is;
186
192
  /**
187
- * The constructor initializes a heap data structure with optional elements and options.
188
- * @param elements - The `elements` parameter is an iterable object that contains the initial
189
- * elements to be added to the heap.
190
- * It is an optional parameter, and if not provided, the heap will
191
- * be initialized as empty.
192
- * @param [options] - The `options` parameter is an optional object that can contain additional
193
- * configuration options for the heap.
194
- * In this case, it is used to specify a custom comparator
195
- * function for comparing elements in the heap.
196
- * The comparator function is used to determine the
197
- * order of elements in the heap.
193
+ * Create a Heap and optionally bulk-insert elements.
194
+ * @remarks Time O(N), Space O(N)
195
+ * @param [elements] - Iterable of elements (or raw values if toElementFn is set).
196
+ * @param [options] - Options such as comparator and toElementFn.
197
+ * @returns New Heap instance.
198
198
  */
199
199
  constructor(elements = [], options) {
200
200
  super(options);
@@ -207,78 +207,88 @@ export class Heap extends IterableElementBase {
207
207
  }
208
208
  _elements = [];
209
209
  /**
210
- * The function returns an array of elements.
211
- * @returns The element array is being returned.
210
+ * Get the backing array of the heap.
211
+ * @remarks Time O(1), Space O(1)
212
+ * @returns Internal elements array.
212
213
  */
213
214
  get elements() {
214
215
  return this._elements;
215
216
  }
216
217
  /**
217
- * Get the size (number of elements) of the heap.
218
+ * Get the number of elements.
219
+ * @remarks Time O(1), Space O(1)
220
+ * @returns Heap size.
218
221
  */
219
222
  get size() {
220
223
  return this.elements.length;
221
224
  }
222
225
  /**
223
- * Get the last element in the heap, which is not necessarily a leaf node.
224
- * @returns The last element or undefined if the heap is empty.
226
+ * Get the last leaf element.
227
+ * @remarks Time O(1), Space O(1)
228
+ * @returns Last element or undefined.
225
229
  */
226
230
  get leaf() {
227
231
  return this.elements[this.size - 1] ?? undefined;
228
232
  }
229
233
  /**
230
- * Static method that creates a binary heap from an array of elements and a comparison function.
231
- * @returns A new Heap instance.
232
- * @param elements
233
- * @param options
234
+ * Create a heap of the same class from an iterable.
235
+ * @remarks Time O(N), Space O(N)
236
+ * @template T
237
+ * @template R
238
+ * @template S
239
+ * @param [elements] - Iterable of elements or raw records.
240
+ * @param [options] - Heap options including comparator.
241
+ * @returns A new heap instance of this class.
242
+ */
243
+ static from(elements, options) {
244
+ return new this(elements, options);
245
+ }
246
+ /**
247
+ * Build a Heap from an iterable in linear time given a comparator.
248
+ * @remarks Time O(N), Space O(N)
249
+ * @template EE
250
+ * @template RR
251
+ * @param elements - Iterable of elements.
252
+ * @param options - Heap options including comparator.
253
+ * @returns A new Heap built from elements.
234
254
  */
235
255
  static heapify(elements, options) {
236
256
  return new Heap(elements, options);
237
257
  }
238
258
  /**
239
- * Time Complexity: O(log n)
240
- * Space Complexity: O(1)
241
- *
242
- * The add function pushes an element into an array and then triggers a bubble-up operation.
243
- * @param {E} element - The `element` parameter represents the element that you want to add to the
244
- * data structure.
245
- * @returns The `add` method is returning a boolean value, which is the result of calling the
246
- * `_bubbleUp` method with the index `this.elements.length - 1` as an argument.
259
+ * Insert an element.
260
+ * @remarks Time O(1) amortized, Space O(1)
261
+ * @param element - Element to insert.
262
+ * @returns True.
247
263
  */
248
264
  add(element) {
249
265
  this._elements.push(element);
250
266
  return this._bubbleUp(this.elements.length - 1);
251
267
  }
252
268
  /**
253
- * Time Complexity: O(k log n)
254
- * Space Complexity: O(1)
255
- *
256
- * The `addMany` function iterates over elements and adds them to a collection, returning an array of
257
- * boolean values indicating success or failure.
258
- * @param {Iterable<E> | Iterable<R>} elements - The `elements` parameter in the `addMany` method is
259
- * an iterable containing elements of type `E` or `R`. The method iterates over each element in the
260
- * iterable and adds them to the data structure. If a transformation function `_toElementFn` is
261
- * provided, it transforms the element
262
- * @returns The `addMany` method returns an array of boolean values indicating whether each element
263
- * in the input iterable was successfully added to the data structure.
269
+ * Insert many elements from an iterable.
270
+ * @remarks Time O(N log N), Space O(1)
271
+ * @param elements - Iterable of elements or raw values.
272
+ * @returns Array of per-element success flags.
264
273
  */
265
274
  addMany(elements) {
266
- const ans = [];
275
+ const flags = [];
267
276
  for (const el of elements) {
268
- if (this._toElementFn) {
269
- ans.push(this.add(this._toElementFn(el)));
270
- continue;
277
+ if (this.toElementFn) {
278
+ const ok = this.add(this.toElementFn(el));
279
+ flags.push(ok);
280
+ }
281
+ else {
282
+ const ok = this.add(el);
283
+ flags.push(ok);
271
284
  }
272
- ans.push(this.add(el));
273
285
  }
274
- return ans;
286
+ return flags;
275
287
  }
276
288
  /**
277
- * Time Complexity: O(log n)
278
- * Space Complexity: O(1)
279
- *
280
- * Remove and return the top element (the smallest or largest element) from the heap.
281
- * @returns The top element or undefined if the heap is empty.
289
+ * Remove and return the top element.
290
+ * @remarks Time O(log N), Space O(1)
291
+ * @returns Top element or undefined.
282
292
  */
283
293
  poll() {
284
294
  if (this.elements.length === 0)
@@ -292,63 +302,65 @@ export class Heap extends IterableElementBase {
292
302
  return value;
293
303
  }
294
304
  /**
295
- * Time Complexity: O(1)
296
- * Space Complexity: O(1)
297
- *
298
- * Peek at the top element of the heap without removing it.
299
- * @returns The top element or undefined if the heap is empty.
305
+ * Get the current top element without removing it.
306
+ * @remarks Time O(1), Space O(1)
307
+ * @returns Top element or undefined.
300
308
  */
301
309
  peek() {
302
310
  return this.elements[0];
303
311
  }
304
312
  /**
305
- * Check if the heap is empty.
306
- * @returns True if the heap is empty, otherwise false.
313
+ * Check whether the heap is empty.
314
+ * @remarks Time O(1), Space O(1)
315
+ * @returns True if size is 0.
307
316
  */
308
317
  isEmpty() {
309
318
  return this.size === 0;
310
319
  }
311
320
  /**
312
- * Reset the elements of the heap. Make the elements empty.
321
+ * Remove all elements.
322
+ * @remarks Time O(1), Space O(1)
323
+ * @returns void
313
324
  */
314
325
  clear() {
315
326
  this._elements = [];
316
327
  }
317
328
  /**
318
- * Time Complexity: O(n)
319
- * Space Complexity: O(n)
320
- *
321
- * Clear and add elements of the heap
322
- * @param elements
329
+ * Replace the backing array and rebuild the heap.
330
+ * @remarks Time O(N), Space O(N)
331
+ * @param elements - Iterable used to refill the heap.
332
+ * @returns Array of per-node results from fixing steps.
323
333
  */
324
334
  refill(elements) {
325
- this._elements = elements;
335
+ this._elements = Array.from(elements);
326
336
  return this.fix();
327
337
  }
328
338
  /**
329
- * Time Complexity: O(n)
330
- * Space Complexity: O(1)
331
- *
332
- * Use a comparison function to check whether a binary heap contains a specific element.
333
- * @param element - the element to check.
334
- * @returns Returns true if the specified element is contained; otherwise, returns false.
339
+ * Check if an equal element exists in the heap.
340
+ * @remarks Time O(N), Space O(1)
341
+ * @param element - Element to search for.
342
+ * @returns True if found.
335
343
  */
336
344
  has(element) {
337
- return this.elements.includes(element);
345
+ for (const el of this.elements)
346
+ if (this._equals(el, element))
347
+ return true;
348
+ return false;
338
349
  }
339
350
  /**
340
- * Time Complexity: O(n)
341
- * Space Complexity: O(1)
342
- *
343
- * The `delete` function removes an element from an array-like data structure, maintaining the order
344
- * and structure of the remaining elements.
345
- * @param {E} element - The `element` parameter represents the element that you want to delete from
346
- * the array `this.elements`.
347
- * @returns The `delete` function is returning a boolean value. It returns `true` if the element was
348
- * successfully deleted from the array, and `false` if the element was not found in the array.
351
+ * Delete one occurrence of an element.
352
+ * @remarks Time O(N), Space O(1)
353
+ * @param element - Element to delete.
354
+ * @returns True if an element was removed.
349
355
  */
350
356
  delete(element) {
351
- const index = this.elements.indexOf(element);
357
+ let index = -1;
358
+ for (let i = 0; i < this.elements.length; i++) {
359
+ if (this._equals(this.elements[i], element)) {
360
+ index = i;
361
+ break;
362
+ }
363
+ }
352
364
  if (index < 0)
353
365
  return false;
354
366
  if (index === 0) {
@@ -365,16 +377,52 @@ export class Heap extends IterableElementBase {
365
377
  return true;
366
378
  }
367
379
  /**
368
- * Time Complexity: O(n)
369
- * Space Complexity: O(log n)
370
- *
371
- * Depth-first search (DFS) method, different traversal orders can be selected。
372
- * @param order - Traverse order parameter: 'IN' (in-order), 'PRE' (pre-order) or 'POST' (post-order).
373
- * @returns An array containing elements traversed in the specified order.
380
+ * Delete the first element that matches a predicate.
381
+ * @remarks Time O(N), Space O(1)
382
+ * @param predicate - Function (element, index, heap) → boolean.
383
+ * @returns True if an element was removed.
384
+ */
385
+ deleteBy(predicate) {
386
+ let idx = -1;
387
+ for (let i = 0; i < this.elements.length; i++) {
388
+ if (predicate(this.elements[i], i, this)) {
389
+ idx = i;
390
+ break;
391
+ }
392
+ }
393
+ if (idx < 0)
394
+ return false;
395
+ if (idx === 0) {
396
+ this.poll();
397
+ }
398
+ else if (idx === this.elements.length - 1) {
399
+ this.elements.pop();
400
+ }
401
+ else {
402
+ this.elements.splice(idx, 1, this.elements.pop());
403
+ this._bubbleUp(idx);
404
+ this._sinkDown(idx, this.elements.length >> 1);
405
+ }
406
+ return true;
407
+ }
408
+ /**
409
+ * Set the equality comparator used by has/delete operations.
410
+ * @remarks Time O(1), Space O(1)
411
+ * @param equals - Equality predicate (a, b) → boolean.
412
+ * @returns This heap.
413
+ */
414
+ setEquality(equals) {
415
+ this._equals = equals;
416
+ return this;
417
+ }
418
+ /**
419
+ * Traverse the binary heap as a complete binary tree and collect elements.
420
+ * @remarks Time O(N), Space O(H)
421
+ * @param [order] - Traversal order: 'PRE' | 'IN' | 'POST'.
422
+ * @returns Array of visited elements.
374
423
  */
375
424
  dfs(order = 'PRE') {
376
425
  const result = [];
377
- // Auxiliary recursive function, traverses the binary heap according to the traversal order
378
426
  const _dfs = (index) => {
379
427
  const left = 2 * index + 1, right = left + 1;
380
428
  if (index < this.size) {
@@ -395,108 +443,110 @@ export class Heap extends IterableElementBase {
395
443
  }
396
444
  }
397
445
  };
398
- _dfs(0); // Traverse starting from the root node
446
+ _dfs(0);
399
447
  return result;
400
448
  }
401
449
  /**
402
- * Time Complexity: O(n)
403
- * Space Complexity: O(n)
404
- *
405
- * Clone the heap, creating a new heap with the same elements.
406
- * @returns A new Heap instance containing the same elements.
450
+ * Restore heap order bottom-up (heapify in-place).
451
+ * @remarks Time O(N), Space O(1)
452
+ * @returns Array of per-node results from fixing steps.
407
453
  */
408
- clone() {
409
- return new Heap(this, { comparator: this.comparator, toElementFn: this.toElementFn });
454
+ fix() {
455
+ const results = [];
456
+ for (let i = Math.floor(this.size / 2) - 1; i >= 0; i--) {
457
+ results.push(this._sinkDown(i, this.elements.length >> 1));
458
+ }
459
+ return results;
410
460
  }
411
461
  /**
412
- * Time Complexity: O(n log n)
413
- * Space Complexity: O(n)
414
- *
415
- * Sort the elements in the heap and return them as an array.
416
- * @returns An array containing the elements sorted in ascending order.
462
+ * Return all elements in ascending order by repeatedly polling.
463
+ * @remarks Time O(N log N), Space O(N)
464
+ * @returns Sorted array of elements.
417
465
  */
418
466
  sort() {
419
- const visitedNode = [];
420
- const cloned = new Heap(this, { comparator: this.comparator });
421
- while (cloned.size !== 0) {
467
+ const visited = [];
468
+ const cloned = this._createInstance();
469
+ for (const x of this.elements)
470
+ cloned.add(x);
471
+ while (!cloned.isEmpty()) {
422
472
  const top = cloned.poll();
423
473
  if (top !== undefined)
424
- visitedNode.push(top);
474
+ visited.push(top);
425
475
  }
426
- return visitedNode;
476
+ return visited;
427
477
  }
428
478
  /**
429
- * Time Complexity: O(n log n)
430
- * Space Complexity: O(n)
431
- *
432
- * Fix the entire heap to maintain heap properties.
479
+ * Deep clone this heap.
480
+ * @remarks Time O(N), Space O(N)
481
+ * @returns A new heap with the same elements.
433
482
  */
434
- fix() {
435
- const results = [];
436
- for (let i = Math.floor(this.size / 2); i >= 0; i--)
437
- results.push(this._sinkDown(i, this.elements.length >> 1));
438
- return results;
483
+ clone() {
484
+ const next = this._createInstance();
485
+ for (const x of this.elements)
486
+ next.add(x);
487
+ return next;
439
488
  }
440
489
  /**
441
- * Time Complexity: O(n)
442
- * Space Complexity: O(n)
443
- *
444
- * The `filter` function creates a new Heap object containing elements that pass a given callback
445
- * function.
446
- * @param callback - The `callback` parameter is a function that will be called for each element in
447
- * the heap. It takes three arguments: the current element, the index of the current element, and the
448
- * heap itself. The callback function should return a boolean value indicating whether the current
449
- * element should be included in the filtered list
450
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value
451
- * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be
452
- * passed as the `this` value to the `callback` function. If `thisArg` is
453
- * @returns The `filter` method is returning a new `Heap` object that contains the elements that pass
454
- * the filter condition specified by the `callback` function.
490
+ * Filter elements into a new heap of the same class.
491
+ * @remarks Time O(N log N), Space O(N)
492
+ * @param callback - Predicate (element, index, heap) → boolean to keep element.
493
+ * @param [thisArg] - Value for `this` inside the callback.
494
+ * @returns A new heap with the kept elements.
455
495
  */
456
496
  filter(callback, thisArg) {
457
- const filteredList = new Heap([], { toElementFn: this.toElementFn, comparator: this.comparator });
458
- let index = 0;
459
- for (const current of this) {
460
- if (callback.call(thisArg, current, index, this)) {
461
- filteredList.add(current);
497
+ const out = this._createInstance();
498
+ let i = 0;
499
+ for (const x of this) {
500
+ if (thisArg === undefined ? callback(x, i++, this) : callback.call(thisArg, x, i++, this)) {
501
+ out.add(x);
502
+ }
503
+ else {
504
+ i++;
462
505
  }
463
- index++;
464
506
  }
465
- return filteredList;
466
- }
467
- /**
468
- * Time Complexity: O(n)
469
- * Space Complexity: O(n)
470
- *
471
- * The `map` function creates a new heap by applying a callback function to each element of the
472
- * original heap.
473
- * @param callback - The `callback` parameter is a function that will be called for each element in
474
- * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current
475
- * element), and `this` (the heap itself). The callback function should return a value of
476
- * @param comparator - The `comparator` parameter is a function that defines the order of the
477
- * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number
478
- * if `a` should be placed before `b`, a positive number if `a` should be placed after
479
- * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw
480
- * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and
481
- * returns a value of type `T`. This function is used to transform the elements of the original
482
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
483
- * specify the value of `this` within the callback function. It is used to set the context or scope
484
- * in which the callback function will be executed. If `thisArg` is provided, it will be used as the
485
- * value of
486
- * @returns a new instance of the `Heap` class with the mapped elements.
487
- */
488
- map(callback, comparator, toElementFn, thisArg) {
489
- const mappedHeap = new Heap([], { comparator, toElementFn });
490
- let index = 0;
491
- for (const el of this) {
492
- mappedHeap.add(callback.call(thisArg, el, index, this));
493
- index++;
507
+ return out;
508
+ }
509
+ /**
510
+ * Map elements into a new heap of possibly different element type.
511
+ * @remarks Time O(N log N), Space O(N)
512
+ * @template EM
513
+ * @template RM
514
+ * @param callback - Mapping function (element, index, heap) → newElement.
515
+ * @param options - Options for the output heap, including comparator for EM.
516
+ * @param [thisArg] - Value for `this` inside the callback.
517
+ * @returns A new heap with mapped elements.
518
+ */
519
+ map(callback, options, thisArg) {
520
+ const { comparator, toElementFn, ...rest } = options ?? {};
521
+ if (!comparator)
522
+ throw new TypeError('Heap.map requires options.comparator for EM');
523
+ const out = this._createLike([], { ...rest, comparator, toElementFn });
524
+ let i = 0;
525
+ for (const x of this) {
526
+ const v = thisArg === undefined ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
527
+ out.add(v);
494
528
  }
495
- return mappedHeap;
529
+ return out;
530
+ }
531
+ /**
532
+ * Map elements into a new heap of the same element type.
533
+ * @remarks Time O(N log N), Space O(N)
534
+ * @param callback - Mapping function (element, index, heap) → element.
535
+ * @param [thisArg] - Value for `this` inside the callback.
536
+ * @returns A new heap with mapped elements.
537
+ */
538
+ mapSame(callback, thisArg) {
539
+ const out = this._createInstance();
540
+ let i = 0;
541
+ for (const x of this) {
542
+ const v = thisArg === undefined ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
543
+ out.add(v);
544
+ }
545
+ return out;
496
546
  }
497
547
  _DEFAULT_COMPARATOR = (a, b) => {
498
548
  if (typeof a === 'object' || typeof b === 'object') {
499
- throw TypeError(`When comparing object types, a custom comparator must be defined in the constructor's options parameter.`);
549
+ throw TypeError('When comparing object types, define a custom comparator in options.');
500
550
  }
501
551
  if (a > b)
502
552
  return 1;
@@ -504,29 +554,23 @@ export class Heap extends IterableElementBase {
504
554
  return -1;
505
555
  return 0;
506
556
  };
507
- _comparator = this._DEFAULT_COMPARATOR;
557
+ _comparator = this._DEFAULT_COMPARATOR; /**
558
+ * Get the comparator used to order elements.
559
+ * @remarks Time O(1), Space O(1)
560
+ * @returns Comparator function.
561
+ */
508
562
  /**
509
- * The function returns the value of the _comparator property.
510
- * @returns The `_comparator` property is being returned.
563
+ * Get the comparator used to order elements.
564
+ * @remarks Time O(1), Space O(1)
565
+ * @returns Comparator function.
511
566
  */
512
567
  get comparator() {
513
568
  return this._comparator;
514
569
  }
515
- /**
516
- * The function `_getIterator` returns an iterable iterator for the elements in the class.
517
- */
518
570
  *_getIterator() {
519
- for (const element of this.elements) {
571
+ for (const element of this.elements)
520
572
  yield element;
521
- }
522
573
  }
523
- /**
524
- * Time Complexity: O(log n)
525
- * Space Complexity: O(1)
526
- *
527
- * Float operation to maintain heap properties after adding an element.
528
- * @param index - The index of the newly added element.
529
- */
530
574
  _bubbleUp(index) {
531
575
  const element = this.elements[index];
532
576
  while (index > 0) {
@@ -540,14 +584,6 @@ export class Heap extends IterableElementBase {
540
584
  this.elements[index] = element;
541
585
  return true;
542
586
  }
543
- /**
544
- * Time Complexity: O(log n)
545
- * Space Complexity: O(1)
546
- *
547
- * Sinking operation to maintain heap properties after removing the top element.
548
- * @param index - The index from which to start sinking.
549
- * @param halfLength
550
- */
551
587
  _sinkDown(index, halfLength) {
552
588
  const element = this.elements[index];
553
589
  while (index < halfLength) {
@@ -566,7 +602,47 @@ export class Heap extends IterableElementBase {
566
602
  this.elements[index] = element;
567
603
  return true;
568
604
  }
605
+ /**
606
+ * (Protected) Create an empty instance of the same concrete class.
607
+ * @remarks Time O(1), Space O(1)
608
+ * @param [options] - Options to override comparator or toElementFn.
609
+ * @returns A like-kind empty heap instance.
610
+ */
611
+ _createInstance(options) {
612
+ const Ctor = this.constructor;
613
+ const next = new Ctor([], { comparator: this.comparator, toElementFn: this.toElementFn, ...(options ?? {}) });
614
+ return next;
615
+ }
616
+ /**
617
+ * (Protected) Create a like-kind instance seeded by elements.
618
+ * @remarks Time O(N log N), Space O(N)
619
+ * @template EM
620
+ * @template RM
621
+ * @param [elements] - Iterable of elements or raw values to seed.
622
+ * @param [options] - Options forwarded to the constructor.
623
+ * @returns A like-kind heap instance.
624
+ */
625
+ _createLike(elements = [], options) {
626
+ const Ctor = this.constructor;
627
+ return new Ctor(elements, options);
628
+ }
629
+ /**
630
+ * (Protected) Spawn an empty like-kind heap instance.
631
+ * @remarks Time O(1), Space O(1)
632
+ * @template EM
633
+ * @template RM
634
+ * @param [options] - Options forwarded to the constructor.
635
+ * @returns An empty like-kind heap instance.
636
+ */
637
+ _spawnLike(options) {
638
+ return this._createLike([], options);
639
+ }
569
640
  }
641
+ /**
642
+ * Node container used by FibonacciHeap.
643
+ * @remarks Time O(1), Space O(1)
644
+ * @template E
645
+ */
570
646
  export class FibonacciHeapNode {
571
647
  element;
572
648
  degree;
@@ -575,158 +651,117 @@ export class FibonacciHeapNode {
575
651
  child;
576
652
  parent;
577
653
  marked;
578
- /**
579
- * The constructor function initializes an object with an element and a degree, and sets the marked
580
- * property to false.
581
- * @param {E} element - The "element" parameter represents the value or data that will be stored in
582
- * the node of a data structure. It can be any type of data, such as a number, string, object, or
583
- * even another data structure.
584
- * @param [degree=0] - The degree parameter represents the degree of the element in a data structure
585
- * called a Fibonacci heap. The degree of a node is the number of children it has. By default, the
586
- * degree is set to 0 when a new node is created.
587
- */
588
654
  constructor(element, degree = 0) {
589
655
  this.element = element;
590
656
  this.degree = degree;
591
657
  this.marked = false;
592
658
  }
593
659
  }
660
+ /**
661
+ * Fibonacci heap (min-heap) optimized for fast merges and amortized operations.
662
+ * @remarks Time O(1), Space O(1)
663
+ * @template E
664
+ * @example examples will be generated by unit test
665
+ */
594
666
  export class FibonacciHeap {
595
667
  /**
596
- * The constructor function initializes a FibonacciHeap object with an optional comparator function.
597
- * @param [comparator] - The `comparator` parameter is an optional argument that represents a
598
- * function used to compare elements in the FibonacciHeap. If a comparator function is provided, it
599
- * will be used to determine the order of elements in the heap. If no comparator function is
600
- * provided, a default comparator function will be used.
668
+ * Create a FibonacciHeap.
669
+ * @remarks Time O(1), Space O(1)
670
+ * @param [comparator] - Comparator to order elements (min-heap by default).
671
+ * @returns New FibonacciHeap instance.
601
672
  */
602
673
  constructor(comparator) {
603
674
  this.clear();
604
675
  this._comparator = comparator || this._defaultComparator;
605
- if (typeof this.comparator !== 'function') {
606
- throw new Error('FibonacciHeap constructor: given comparator should be a function.');
607
- }
676
+ if (typeof this.comparator !== 'function')
677
+ throw new Error('FibonacciHeap: comparator must be a function.');
608
678
  }
609
679
  _root;
610
680
  /**
611
- * The function returns the root node of a Fibonacci heap.
612
- * @returns The method is returning either a FibonacciHeapNode object or undefined.
681
+ * Get the circular root list head.
682
+ * @remarks Time O(1), Space O(1)
683
+ * @returns Root node or undefined.
613
684
  */
614
685
  get root() {
615
686
  return this._root;
616
687
  }
617
688
  _size = 0;
618
- /**
619
- * The function returns the size of an object.
620
- * @returns The size of the object, which is a number.
621
- */
622
689
  get size() {
623
690
  return this._size;
624
691
  }
625
692
  _min;
626
693
  /**
627
- * The function returns the minimum node in a Fibonacci heap.
628
- * @returns The method is returning the minimum node of the Fibonacci heap, which is of type
629
- * `FibonacciHeapNode<E>`. If there is no minimum node, it will return `undefined`.
694
+ * Get the current minimum node.
695
+ * @remarks Time O(1), Space O(1)
696
+ * @returns Min node or undefined.
630
697
  */
631
698
  get min() {
632
699
  return this._min;
633
700
  }
634
701
  _comparator;
635
- /**
636
- * The function returns the comparator used for comparing elements.
637
- * @returns The `_comparator` property of the object.
638
- */
639
702
  get comparator() {
640
703
  return this._comparator;
641
704
  }
642
- /**
643
- * Get the size (number of elements) of the heap.
644
- * @returns {number} The size of the heap. Returns 0 if the heap is empty. Returns -1 if the heap is invalid.
645
- */
646
705
  clear() {
647
706
  this._root = undefined;
648
707
  this._min = undefined;
649
708
  this._size = 0;
650
709
  }
651
- /**
652
- * Time Complexity: O(1)
653
- * Space Complexity: O(1)
654
- *
655
- * Insert an element into the heap and maintain the heap properties.
656
- * @param element
657
- * @returns {FibonacciHeap<E>} FibonacciHeap<E> - The heap itself.
658
- */
659
710
  add(element) {
660
- return this.push(element);
711
+ this.push(element);
712
+ return true;
661
713
  }
662
714
  /**
663
- * Time Complexity: O(1)
664
- * Space Complexity: O(1)
665
- *
666
- * Insert an element into the heap and maintain the heap properties.
667
- * @param element
668
- * @returns {FibonacciHeap<E>} FibonacciHeap<E> - The heap itself.
715
+ * Push an element into the root list.
716
+ * @remarks Time O(1) amortized, Space O(1)
717
+ * @param element - Element to insert.
718
+ * @returns This heap.
669
719
  */
670
720
  push(element) {
671
- const node = this.createNode(element);
721
+ const node = this._createNode(element);
672
722
  node.left = node;
673
723
  node.right = node;
674
724
  this.mergeWithRoot(node);
675
- if (!this.min || this.comparator(node.element, this.min.element) <= 0) {
725
+ if (!this.min || this.comparator(node.element, this.min.element) <= 0)
676
726
  this._min = node;
677
- }
678
727
  this._size++;
679
728
  return this;
680
729
  }
681
- /**
682
- * Time Complexity: O(1)
683
- * Space Complexity: O(1)
684
- *
685
- * Peek at the top element of the heap without removing it.
686
- * @returns The top element or undefined if the heap is empty.
687
- * @protected
688
- */
689
730
  peek() {
690
731
  return this.min ? this.min.element : undefined;
691
732
  }
692
733
  /**
693
- * Time Complexity: O(n), where n is the number of elements in the linked list.
694
- * Space Complexity: O(1)
695
- *
696
- * Get the size (number of elements) of the heap.
697
- * @param {FibonacciHeapNode<E>} head - The head of the linked list.
698
- * @protected
699
- * @returns FibonacciHeapNode<E>[] - An array containing the elements of the linked list.
734
+ * Collect nodes from a circular doubly linked list starting at head.
735
+ * @remarks Time O(K), Space O(K)
736
+ * @param [head] - Start node of the circular list.
737
+ * @returns Array of nodes from the list.
700
738
  */
701
739
  consumeLinkedList(head) {
702
740
  const elements = [];
703
741
  if (!head)
704
742
  return elements;
705
743
  let node = head;
706
- let flag = false;
744
+ let started = false;
707
745
  while (true) {
708
- if (node === head && flag)
746
+ if (node === head && started)
709
747
  break;
710
748
  else if (node === head)
711
- flag = true;
712
- if (node) {
713
- elements.push(node);
714
- node = node.right;
715
- }
749
+ started = true;
750
+ elements.push(node);
751
+ node = node.right;
716
752
  }
717
753
  return elements;
718
754
  }
719
755
  /**
720
- * Time Complexity: O(1)
721
- * Space Complexity: O(1)
722
- *
723
- * @param parent
724
- * @param node
756
+ * Insert a node into a parent's child list (circular).
757
+ * @remarks Time O(1), Space O(1)
758
+ * @param parent - Parent node.
759
+ * @param node - Child node to insert.
760
+ * @returns void
725
761
  */
726
762
  mergeWithChild(parent, node) {
727
- if (!parent.child) {
763
+ if (!parent.child)
728
764
  parent.child = node;
729
- }
730
765
  else {
731
766
  node.right = parent.child.right;
732
767
  node.left = parent.child;
@@ -734,22 +769,13 @@ export class FibonacciHeap {
734
769
  parent.child.right = node;
735
770
  }
736
771
  }
737
- /**
738
- * Time Complexity: O(log n)
739
- * Space Complexity: O(1)
740
- *
741
- * Remove and return the top element (the smallest or largest element) from the heap.
742
- * @returns The top element or undefined if the heap is empty.
743
- */
744
772
  poll() {
745
773
  return this.pop();
746
774
  }
747
775
  /**
748
- * Time Complexity: O(log n)
749
- * Space Complexity: O(1)
750
- *
751
- * Remove and return the top element (the smallest or largest element) from the heap.
752
- * @returns The top element or undefined if the heap is empty.
776
+ * Remove and return the minimum element, consolidating the root list.
777
+ * @remarks Time O(log N) amortized, Space O(1)
778
+ * @returns Minimum element or undefined.
753
779
  */
754
780
  pop() {
755
781
  if (this._size === 0)
@@ -775,50 +801,37 @@ export class FibonacciHeap {
775
801
  return z.element;
776
802
  }
777
803
  /**
778
- * Time Complexity: O(1)
779
- * Space Complexity: O(1)
780
- *
781
- * merge two heaps. The heap that is merged will be cleared. The heap that is merged into will remain.
782
- * @param heapToMerge
804
+ * Meld another heap into this heap.
805
+ * @remarks Time O(1), Space O(1)
806
+ * @param heapToMerge - Another FibonacciHeap to meld into this one.
807
+ * @returns void
783
808
  */
784
809
  merge(heapToMerge) {
785
- if (heapToMerge.size === 0) {
786
- return; // Nothing to merge
787
- }
788
- // Merge the root lists of the two heaps
810
+ if (heapToMerge.size === 0)
811
+ return;
789
812
  if (this.root && heapToMerge.root) {
790
- const thisRoot = this.root;
791
- const otherRoot = heapToMerge.root;
792
- const thisRootRight = thisRoot.right;
793
- const otherRootLeft = otherRoot.left;
813
+ const thisRoot = this.root, otherRoot = heapToMerge.root;
814
+ const thisRootRight = thisRoot.right, otherRootLeft = otherRoot.left;
794
815
  thisRoot.right = otherRoot;
795
816
  otherRoot.left = thisRoot;
796
817
  thisRootRight.left = otherRootLeft;
797
818
  otherRootLeft.right = thisRootRight;
798
819
  }
799
- // Update the minimum node
820
+ else if (!this.root && heapToMerge.root) {
821
+ this._root = heapToMerge.root;
822
+ }
800
823
  if (!this.min || (heapToMerge.min && this.comparator(heapToMerge.min.element, this.min.element) < 0)) {
801
824
  this._min = heapToMerge.min;
802
825
  }
803
- // Update the size
804
826
  this._size += heapToMerge.size;
805
- // Clear the heap that was merged
806
827
  heapToMerge.clear();
807
828
  }
808
- /**
809
- * Create a new node.
810
- * @param element
811
- * @protected
812
- */
813
- createNode(element) {
829
+ _createNode(element) {
814
830
  return new FibonacciHeapNode(element);
815
831
  }
816
- /**
817
- * Default comparator function used by the heap.
818
- * @param {E} a
819
- * @param {E} b
820
- * @protected
821
- */
832
+ isEmpty() {
833
+ return this._size === 0;
834
+ }
822
835
  _defaultComparator(a, b) {
823
836
  if (a < b)
824
837
  return -1;
@@ -826,17 +839,9 @@ export class FibonacciHeap {
826
839
  return 1;
827
840
  return 0;
828
841
  }
829
- /**
830
- * Time Complexity: O(1)
831
- * Space Complexity: O(1)
832
- *
833
- * Merge the given node with the root list.
834
- * @param node - The node to be merged.
835
- */
836
842
  mergeWithRoot(node) {
837
- if (!this.root) {
843
+ if (!this.root)
838
844
  this._root = node;
839
- }
840
845
  else {
841
846
  node.right = this.root.right;
842
847
  node.left = this.root;
@@ -844,14 +849,6 @@ export class FibonacciHeap {
844
849
  this.root.right = node;
845
850
  }
846
851
  }
847
- /**
848
- * Time Complexity: O(1)
849
- * Space Complexity: O(1)
850
- *
851
- * Remove and return the top element (the smallest or largest element) from the heap.
852
- * @param node - The node to be removed.
853
- * @protected
854
- */
855
852
  removeFromRoot(node) {
856
853
  if (this.root === node)
857
854
  this._root = node.right;
@@ -860,15 +857,6 @@ export class FibonacciHeap {
860
857
  if (node.right)
861
858
  node.right.left = node.left;
862
859
  }
863
- /**
864
- * Time Complexity: O(1)
865
- * Space Complexity: O(1)
866
- *
867
- * Remove and return the top element (the smallest or largest element) from the heap.
868
- * @param y
869
- * @param x
870
- * @protected
871
- */
872
860
  _link(y, x) {
873
861
  this.removeFromRoot(y);
874
862
  y.left = y;
@@ -877,13 +865,6 @@ export class FibonacciHeap {
877
865
  x.degree++;
878
866
  y.parent = x;
879
867
  }
880
- /**
881
- * Time Complexity: O(n log n)
882
- * Space Complexity: O(n)
883
- *
884
- * Remove and return the top element (the smallest or largest element) from the heap.
885
- * @protected
886
- */
887
868
  _consolidate() {
888
869
  const A = new Array(this._size);
889
870
  const elements = this.consumeLinkedList(this.root);
@@ -904,10 +885,9 @@ export class FibonacciHeap {
904
885
  }
905
886
  A[d] = x;
906
887
  }
907
- for (let i = 0; i < this._size; i++) {
908
- if (A[i] && this.comparator(A[i].element, this.min.element) <= 0) {
888
+ for (let i = 0; i < A.length; i++) {
889
+ if (A[i] && (!this.min || this.comparator(A[i].element, this.min.element) <= 0))
909
890
  this._min = A[i];
910
- }
911
891
  }
912
892
  }
913
893
  }