data-structure-typed 2.0.4 → 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 (261) hide show
  1. package/CHANGELOG.md +3 -1
  2. package/COMMANDS.md +17 -0
  3. package/README.md +11 -11
  4. package/benchmark/report.html +13 -77
  5. package/benchmark/report.json +158 -190
  6. package/dist/cjs/data-structures/base/iterable-element-base.d.ts +186 -83
  7. package/dist/cjs/data-structures/base/iterable-element-base.js +149 -107
  8. package/dist/cjs/data-structures/base/iterable-element-base.js.map +1 -1
  9. package/dist/cjs/data-structures/base/iterable-entry-base.d.ts +95 -119
  10. package/dist/cjs/data-structures/base/iterable-entry-base.js +59 -116
  11. package/dist/cjs/data-structures/base/iterable-entry-base.js.map +1 -1
  12. package/dist/cjs/data-structures/base/linear-base.d.ts +250 -192
  13. package/dist/cjs/data-structures/base/linear-base.js +137 -274
  14. package/dist/cjs/data-structures/base/linear-base.js.map +1 -1
  15. package/dist/cjs/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
  16. package/dist/cjs/data-structures/binary-tree/avl-tree-counter.js +171 -205
  17. package/dist/cjs/data-structures/binary-tree/avl-tree-counter.js.map +1 -1
  18. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
  19. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
  20. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  21. package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +138 -149
  22. package/dist/cjs/data-structures/binary-tree/avl-tree.js +208 -195
  23. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  24. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +476 -632
  25. package/dist/cjs/data-structures/binary-tree/binary-tree.js +608 -875
  26. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  27. package/dist/cjs/data-structures/binary-tree/bst.d.ts +258 -306
  28. package/dist/cjs/data-structures/binary-tree/bst.js +505 -481
  29. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  30. package/dist/cjs/data-structures/binary-tree/red-black-tree.d.ts +107 -179
  31. package/dist/cjs/data-structures/binary-tree/red-black-tree.js +114 -209
  32. package/dist/cjs/data-structures/binary-tree/red-black-tree.js.map +1 -1
  33. package/dist/cjs/data-structures/binary-tree/tree-counter.d.ts +132 -154
  34. package/dist/cjs/data-structures/binary-tree/tree-counter.js +172 -203
  35. package/dist/cjs/data-structures/binary-tree/tree-counter.js.map +1 -1
  36. package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
  37. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +105 -85
  38. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  39. package/dist/cjs/data-structures/graph/abstract-graph.d.ts +238 -233
  40. package/dist/cjs/data-structures/graph/abstract-graph.js +267 -237
  41. package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
  42. package/dist/cjs/data-structures/graph/directed-graph.d.ts +108 -224
  43. package/dist/cjs/data-structures/graph/directed-graph.js +146 -233
  44. package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
  45. package/dist/cjs/data-structures/graph/map-graph.d.ts +49 -55
  46. package/dist/cjs/data-structures/graph/map-graph.js +56 -59
  47. package/dist/cjs/data-structures/graph/map-graph.js.map +1 -1
  48. package/dist/cjs/data-structures/graph/undirected-graph.d.ts +103 -146
  49. package/dist/cjs/data-structures/graph/undirected-graph.js +129 -149
  50. package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
  51. package/dist/cjs/data-structures/hash/hash-map.d.ts +164 -338
  52. package/dist/cjs/data-structures/hash/hash-map.js +270 -457
  53. package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
  54. package/dist/cjs/data-structures/heap/heap.d.ts +214 -289
  55. package/dist/cjs/data-structures/heap/heap.js +340 -349
  56. package/dist/cjs/data-structures/heap/heap.js.map +1 -1
  57. package/dist/cjs/data-structures/heap/max-heap.d.ts +11 -47
  58. package/dist/cjs/data-structures/heap/max-heap.js +11 -66
  59. package/dist/cjs/data-structures/heap/max-heap.js.map +1 -1
  60. package/dist/cjs/data-structures/heap/min-heap.d.ts +12 -47
  61. package/dist/cjs/data-structures/heap/min-heap.js +11 -66
  62. package/dist/cjs/data-structures/heap/min-heap.js.map +1 -1
  63. package/dist/cjs/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
  64. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js +368 -494
  65. package/dist/cjs/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  66. package/dist/cjs/data-structures/linked-list/singly-linked-list.d.ts +261 -310
  67. package/dist/cjs/data-structures/linked-list/singly-linked-list.js +447 -466
  68. package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
  69. package/dist/cjs/data-structures/linked-list/skip-linked-list.d.ts +0 -107
  70. package/dist/cjs/data-structures/linked-list/skip-linked-list.js +0 -100
  71. package/dist/cjs/data-structures/linked-list/skip-linked-list.js.map +1 -1
  72. package/dist/cjs/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
  73. package/dist/cjs/data-structures/priority-queue/max-priority-queue.js +11 -78
  74. package/dist/cjs/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  75. package/dist/cjs/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
  76. package/dist/cjs/data-structures/priority-queue/min-priority-queue.js +10 -79
  77. package/dist/cjs/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  78. package/dist/cjs/data-structures/priority-queue/priority-queue.d.ts +2 -61
  79. package/dist/cjs/data-structures/priority-queue/priority-queue.js +8 -83
  80. package/dist/cjs/data-structures/priority-queue/priority-queue.js.map +1 -1
  81. package/dist/cjs/data-structures/queue/deque.d.ts +227 -254
  82. package/dist/cjs/data-structures/queue/deque.js +309 -348
  83. package/dist/cjs/data-structures/queue/deque.js.map +1 -1
  84. package/dist/cjs/data-structures/queue/queue.d.ts +180 -201
  85. package/dist/cjs/data-structures/queue/queue.js +265 -248
  86. package/dist/cjs/data-structures/queue/queue.js.map +1 -1
  87. package/dist/cjs/data-structures/stack/stack.d.ts +124 -102
  88. package/dist/cjs/data-structures/stack/stack.js +181 -125
  89. package/dist/cjs/data-structures/stack/stack.js.map +1 -1
  90. package/dist/cjs/data-structures/trie/trie.d.ts +164 -165
  91. package/dist/cjs/data-structures/trie/trie.js +189 -172
  92. package/dist/cjs/data-structures/trie/trie.js.map +1 -1
  93. package/dist/cjs/interfaces/binary-tree.d.ts +56 -6
  94. package/dist/cjs/interfaces/graph.d.ts +16 -0
  95. package/dist/cjs/types/data-structures/base/base.d.ts +1 -1
  96. package/dist/cjs/types/data-structures/graph/abstract-graph.d.ts +4 -0
  97. package/dist/cjs/types/utils/utils.d.ts +6 -6
  98. package/dist/cjs/utils/utils.d.ts +110 -49
  99. package/dist/cjs/utils/utils.js +148 -73
  100. package/dist/cjs/utils/utils.js.map +1 -1
  101. package/dist/esm/data-structures/base/iterable-element-base.d.ts +186 -83
  102. package/dist/esm/data-structures/base/iterable-element-base.js +155 -107
  103. package/dist/esm/data-structures/base/iterable-element-base.js.map +1 -1
  104. package/dist/esm/data-structures/base/iterable-entry-base.d.ts +95 -119
  105. package/dist/esm/data-structures/base/iterable-entry-base.js +59 -116
  106. package/dist/esm/data-structures/base/iterable-entry-base.js.map +1 -1
  107. package/dist/esm/data-structures/base/linear-base.d.ts +250 -192
  108. package/dist/esm/data-structures/base/linear-base.js +137 -274
  109. package/dist/esm/data-structures/base/linear-base.js.map +1 -1
  110. package/dist/esm/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
  111. package/dist/esm/data-structures/binary-tree/avl-tree-counter.js +171 -212
  112. package/dist/esm/data-structures/binary-tree/avl-tree-counter.js.map +1 -1
  113. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
  114. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js +133 -94
  115. package/dist/esm/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  116. package/dist/esm/data-structures/binary-tree/avl-tree.d.ts +138 -149
  117. package/dist/esm/data-structures/binary-tree/avl-tree.js +206 -200
  118. package/dist/esm/data-structures/binary-tree/avl-tree.js.map +1 -1
  119. package/dist/esm/data-structures/binary-tree/binary-tree.d.ts +476 -632
  120. package/dist/esm/data-structures/binary-tree/binary-tree.js +613 -885
  121. package/dist/esm/data-structures/binary-tree/binary-tree.js.map +1 -1
  122. package/dist/esm/data-structures/binary-tree/bst.d.ts +258 -306
  123. package/dist/esm/data-structures/binary-tree/bst.js +507 -487
  124. package/dist/esm/data-structures/binary-tree/bst.js.map +1 -1
  125. package/dist/esm/data-structures/binary-tree/red-black-tree.d.ts +107 -179
  126. package/dist/esm/data-structures/binary-tree/red-black-tree.js +114 -215
  127. package/dist/esm/data-structures/binary-tree/red-black-tree.js.map +1 -1
  128. package/dist/esm/data-structures/binary-tree/tree-counter.d.ts +132 -154
  129. package/dist/esm/data-structures/binary-tree/tree-counter.js +175 -209
  130. package/dist/esm/data-structures/binary-tree/tree-counter.js.map +1 -1
  131. package/dist/esm/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
  132. package/dist/esm/data-structures/binary-tree/tree-multi-map.js +103 -92
  133. package/dist/esm/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  134. package/dist/esm/data-structures/graph/abstract-graph.d.ts +238 -233
  135. package/dist/esm/data-structures/graph/abstract-graph.js +267 -237
  136. package/dist/esm/data-structures/graph/abstract-graph.js.map +1 -1
  137. package/dist/esm/data-structures/graph/directed-graph.d.ts +108 -224
  138. package/dist/esm/data-structures/graph/directed-graph.js +145 -233
  139. package/dist/esm/data-structures/graph/directed-graph.js.map +1 -1
  140. package/dist/esm/data-structures/graph/map-graph.d.ts +49 -55
  141. package/dist/esm/data-structures/graph/map-graph.js +56 -59
  142. package/dist/esm/data-structures/graph/map-graph.js.map +1 -1
  143. package/dist/esm/data-structures/graph/undirected-graph.d.ts +103 -146
  144. package/dist/esm/data-structures/graph/undirected-graph.js +128 -149
  145. package/dist/esm/data-structures/graph/undirected-graph.js.map +1 -1
  146. package/dist/esm/data-structures/hash/hash-map.d.ts +164 -338
  147. package/dist/esm/data-structures/hash/hash-map.js +270 -457
  148. package/dist/esm/data-structures/hash/hash-map.js.map +1 -1
  149. package/dist/esm/data-structures/heap/heap.d.ts +214 -289
  150. package/dist/esm/data-structures/heap/heap.js +329 -349
  151. package/dist/esm/data-structures/heap/heap.js.map +1 -1
  152. package/dist/esm/data-structures/heap/max-heap.d.ts +11 -47
  153. package/dist/esm/data-structures/heap/max-heap.js +11 -66
  154. package/dist/esm/data-structures/heap/max-heap.js.map +1 -1
  155. package/dist/esm/data-structures/heap/min-heap.d.ts +12 -47
  156. package/dist/esm/data-structures/heap/min-heap.js +11 -66
  157. package/dist/esm/data-structures/heap/min-heap.js.map +1 -1
  158. package/dist/esm/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
  159. package/dist/esm/data-structures/linked-list/doubly-linked-list.js +368 -495
  160. package/dist/esm/data-structures/linked-list/doubly-linked-list.js.map +1 -1
  161. package/dist/esm/data-structures/linked-list/singly-linked-list.d.ts +261 -310
  162. package/dist/esm/data-structures/linked-list/singly-linked-list.js +448 -467
  163. package/dist/esm/data-structures/linked-list/singly-linked-list.js.map +1 -1
  164. package/dist/esm/data-structures/linked-list/skip-linked-list.d.ts +0 -107
  165. package/dist/esm/data-structures/linked-list/skip-linked-list.js +0 -100
  166. package/dist/esm/data-structures/linked-list/skip-linked-list.js.map +1 -1
  167. package/dist/esm/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
  168. package/dist/esm/data-structures/priority-queue/max-priority-queue.js +11 -78
  169. package/dist/esm/data-structures/priority-queue/max-priority-queue.js.map +1 -1
  170. package/dist/esm/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
  171. package/dist/esm/data-structures/priority-queue/min-priority-queue.js +10 -79
  172. package/dist/esm/data-structures/priority-queue/min-priority-queue.js.map +1 -1
  173. package/dist/esm/data-structures/priority-queue/priority-queue.d.ts +2 -61
  174. package/dist/esm/data-structures/priority-queue/priority-queue.js +8 -83
  175. package/dist/esm/data-structures/priority-queue/priority-queue.js.map +1 -1
  176. package/dist/esm/data-structures/queue/deque.d.ts +227 -254
  177. package/dist/esm/data-structures/queue/deque.js +313 -348
  178. package/dist/esm/data-structures/queue/deque.js.map +1 -1
  179. package/dist/esm/data-structures/queue/queue.d.ts +180 -201
  180. package/dist/esm/data-structures/queue/queue.js +263 -248
  181. package/dist/esm/data-structures/queue/queue.js.map +1 -1
  182. package/dist/esm/data-structures/stack/stack.d.ts +124 -102
  183. package/dist/esm/data-structures/stack/stack.js +181 -125
  184. package/dist/esm/data-structures/stack/stack.js.map +1 -1
  185. package/dist/esm/data-structures/trie/trie.d.ts +164 -165
  186. package/dist/esm/data-structures/trie/trie.js +193 -172
  187. package/dist/esm/data-structures/trie/trie.js.map +1 -1
  188. package/dist/esm/interfaces/binary-tree.d.ts +56 -6
  189. package/dist/esm/interfaces/graph.d.ts +16 -0
  190. package/dist/esm/types/data-structures/base/base.d.ts +1 -1
  191. package/dist/esm/types/data-structures/graph/abstract-graph.d.ts +4 -0
  192. package/dist/esm/types/utils/utils.d.ts +6 -6
  193. package/dist/esm/utils/utils.d.ts +110 -49
  194. package/dist/esm/utils/utils.js +139 -68
  195. package/dist/esm/utils/utils.js.map +1 -1
  196. package/dist/umd/data-structure-typed.js +4737 -6525
  197. package/dist/umd/data-structure-typed.min.js +8 -6
  198. package/dist/umd/data-structure-typed.min.js.map +1 -1
  199. package/package.json +3 -4
  200. package/src/data-structures/base/iterable-element-base.ts +238 -115
  201. package/src/data-structures/base/iterable-entry-base.ts +96 -120
  202. package/src/data-structures/base/linear-base.ts +271 -277
  203. package/src/data-structures/binary-tree/avl-tree-counter.ts +198 -216
  204. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +192 -101
  205. package/src/data-structures/binary-tree/avl-tree.ts +239 -206
  206. package/src/data-structures/binary-tree/binary-tree.ts +677 -901
  207. package/src/data-structures/binary-tree/bst.ts +568 -570
  208. package/src/data-structures/binary-tree/red-black-tree.ts +161 -222
  209. package/src/data-structures/binary-tree/tree-counter.ts +199 -218
  210. package/src/data-structures/binary-tree/tree-multi-map.ts +131 -97
  211. package/src/data-structures/graph/abstract-graph.ts +339 -264
  212. package/src/data-structures/graph/directed-graph.ts +146 -236
  213. package/src/data-structures/graph/map-graph.ts +63 -60
  214. package/src/data-structures/graph/undirected-graph.ts +129 -152
  215. package/src/data-structures/hash/hash-map.ts +274 -496
  216. package/src/data-structures/heap/heap.ts +389 -402
  217. package/src/data-structures/heap/max-heap.ts +12 -76
  218. package/src/data-structures/heap/min-heap.ts +13 -76
  219. package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
  220. package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
  221. package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
  222. package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
  223. package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
  224. package/src/data-structures/priority-queue/priority-queue.ts +3 -92
  225. package/src/data-structures/queue/deque.ts +381 -357
  226. package/src/data-structures/queue/queue.ts +310 -264
  227. package/src/data-structures/stack/stack.ts +217 -131
  228. package/src/data-structures/trie/trie.ts +240 -175
  229. package/src/interfaces/binary-tree.ts +240 -6
  230. package/src/interfaces/graph.ts +37 -0
  231. package/src/types/data-structures/base/base.ts +5 -5
  232. package/src/types/data-structures/graph/abstract-graph.ts +5 -0
  233. package/src/types/utils/utils.ts +9 -5
  234. package/src/utils/utils.ts +152 -86
  235. package/test/integration/index.html +1 -1
  236. package/test/performance/benchmark-runner.ts +528 -0
  237. package/test/performance/reportor.mjs +43 -43
  238. package/test/performance/runner-config.json +39 -0
  239. package/test/performance/single-suite-runner.ts +69 -0
  240. package/test/unit/data-structures/binary-tree/avl-tree-counter.test.ts +3 -3
  241. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +5 -5
  242. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +4 -4
  243. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +350 -90
  244. package/test/unit/data-structures/binary-tree/bst.test.ts +84 -5
  245. package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +2 -2
  246. package/test/unit/data-structures/binary-tree/tree-counter.test.ts +25 -24
  247. package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +3 -3
  248. package/test/unit/data-structures/graph/abstract-graph.test.ts +0 -4
  249. package/test/unit/data-structures/graph/directed-graph.test.ts +1 -1
  250. package/test/unit/data-structures/heap/heap.test.ts +14 -21
  251. package/test/unit/data-structures/heap/max-heap.test.ts +5 -9
  252. package/test/unit/data-structures/heap/min-heap.test.ts +1 -4
  253. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +14 -14
  254. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +0 -7
  255. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +8 -11
  256. package/test/unit/data-structures/priority-queue/min-priority-queue.test.ts +1 -4
  257. package/test/unit/data-structures/priority-queue/priority-queue.test.ts +1 -4
  258. package/test/unit/data-structures/queue/queue.test.ts +4 -5
  259. package/test/unit/utils/utils.test.ts +0 -1
  260. package/test/performance/data-structures/binary-tree/avl-tree.test.mjs +0 -71
  261. package/test/performance/data-structures/binary-tree/red-black-tree.test.mjs +0 -81
@@ -6,24 +6,41 @@
6
6
  * @license MIT License
7
7
  */
8
8
  import { BST, BSTNode } from './bst';
9
+ /**
10
+ * Represents a Node in an AVL (Adelson-Velsky and Landis) Tree.
11
+ * It extends a BSTNode and ensures the 'height' property is maintained.
12
+ *
13
+ * @template K - The type of the key.
14
+ * @template V - The type of the value.
15
+ */
9
16
  export class AVLTreeNode extends BSTNode {
10
17
  parent = undefined;
11
18
  /**
12
- * This TypeScript constructor function initializes an instance with a key and an optional value.
13
- * @param {K} key - The `key` parameter is typically used to uniquely identify an object or element
14
- * within a data structure. It serves as a reference or identifier for accessing or manipulating the
15
- * associated value or data.
16
- * @param {V} [value] - The `value` parameter in the constructor is optional, meaning it does not
17
- * have to be provided when creating an instance of the class. If a value is not provided, it will
18
- * default to `undefined`.
19
+ * Creates an instance of AVLTreeNode.
20
+ * @remarks Time O(1), Space O(1)
21
+ *
22
+ * @param key - The key of the node.
23
+ * @param [value] - The value associated with the key.
19
24
  */
20
25
  constructor(key, value) {
21
26
  super(key, value);
22
27
  }
23
28
  _left = undefined;
29
+ /**
30
+ * Gets the left child of the node.
31
+ * @remarks Time O(1), Space O(1)
32
+ *
33
+ * @returns The left child.
34
+ */
24
35
  get left() {
25
36
  return this._left;
26
37
  }
38
+ /**
39
+ * Sets the left child of the node and updates its parent reference.
40
+ * @remarks Time O(1), Space O(1)
41
+ *
42
+ * @param v - The node to set as the left child.
43
+ */
27
44
  set left(v) {
28
45
  if (v) {
29
46
  v.parent = this;
@@ -31,9 +48,21 @@ export class AVLTreeNode extends BSTNode {
31
48
  this._left = v;
32
49
  }
33
50
  _right = undefined;
51
+ /**
52
+ * Gets the right child of the node.
53
+ * @remarks Time O(1), Space O(1)
54
+ *
55
+ * @returns The right child.
56
+ */
34
57
  get right() {
35
58
  return this._right;
36
59
  }
60
+ /**
61
+ * Sets the right child of the node and updates its parent reference.
62
+ * @remarks Time O(1), Space O(1)
63
+ *
64
+ * @param v - The node to set as the right child.
65
+ */
37
66
  set right(v) {
38
67
  if (v) {
39
68
  v.parent = this;
@@ -42,14 +71,20 @@ export class AVLTreeNode extends BSTNode {
42
71
  }
43
72
  }
44
73
  /**
74
+ * Represents a self-balancing AVL (Adelson-Velsky and Landis) Tree.
75
+ * This tree extends BST and performs rotations on add/delete to maintain balance.
76
+ *
77
+ * @template K - The type of the key.
78
+ * @template V - The type of the value.
79
+ * @template R - The type of the raw data object (if using `toEntryFn`).
80
+ *
45
81
  * 1. Height-Balanced: Each node's left and right subtrees differ in height by no more than one.
46
82
  * 2. Automatic Rebalancing: AVL trees rebalance themselves automatically during insertions and deletions.
47
83
  * 3. Rotations for Balancing: Utilizes rotations (single or double) to maintain balance after updates.
48
84
  * 4. Order Preservation: Maintains the binary search tree property where left child values are less than the parent, and right child values are greater.
49
85
  * 5. Efficient Lookups: Offers O(log n) search time, where 'n' is the number of nodes, due to its balanced nature.
50
86
  * 6. Complex Insertions and Deletions: Due to rebalancing, these operations are more complex than in a regular BST.
51
- * 7. Path Length: The path length from the root to any leaf is longer compared to an unbalanced BST, but shorter than a linear chain of nodes.
52
- * @example
87
+ * 7. Path Length: The path length from the root to any leaf is longer compared to an unbalanced BST, but shorter than a linear chain of nodes.@example
53
88
  * // Find elements in a range
54
89
  * // In interval queries, AVL trees, with their strictly balanced structure and lower height, offer better query efficiency, making them ideal for frequent and high-performance interval queries. In contrast, Red-Black trees, with lower update costs, are more suitable for scenarios involving frequent insertions and deletions where the requirements for interval queries are less demanding.
55
90
  * type Datum = { timestamp: Date; temperature: number };
@@ -116,107 +151,66 @@ export class AVLTreeNode extends BSTNode {
116
151
  */
117
152
  export class AVLTree extends BST {
118
153
  /**
119
- * This TypeScript constructor initializes an AVLTree with keys, nodes, entries, or raw data provided
120
- * in an iterable format.
121
- * @param keysNodesEntriesOrRaws - The `keysNodesEntriesOrRaws` parameter in the constructor is an
122
- * iterable that can contain either `
123
- K | AVLTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined ` objects or `R` objects. It is
124
- * used to initialize the AVLTree with key-value pairs or raw data entries. If provided
125
- * @param [options] - The `options` parameter in the constructor is of type `AVLTreeOptions<K, V,
126
- * R>`. It is an optional parameter that allows you to specify additional options for configuring the
127
- * AVL tree. These options could include things like custom comparators, initial capacity, or any
128
- * other configuration settings specific
154
+ * Creates an instance of AVLTree.
155
+ * @remarks Time O(N log N) (from `addMany` with balanced add). Space O(N).
156
+ *
157
+ * @param [keysNodesEntriesOrRaws=[]] - An iterable of items to add.
158
+ * @param [options] - Configuration options for the AVL tree.
129
159
  */
130
160
  constructor(keysNodesEntriesOrRaws = [], options) {
131
161
  super([], options);
162
+ // Note: super.addMany is called, which in BST defaults to balanced add.
132
163
  if (keysNodesEntriesOrRaws)
133
164
  super.addMany(keysNodesEntriesOrRaws);
134
165
  }
135
166
  /**
136
- * Time Complexity: O(1)
137
- * Space Complexity: O(1)
167
+ * (Protected) Creates a new AVL tree node.
168
+ * @remarks Time O(1), Space O(1)
138
169
  *
139
- * The function creates a new AVL tree node with the given key and value.
140
- * @param {K} key - The key parameter is of type K, which represents the key of the node being
141
- * created.
142
- * @param {V} [value] - The "value" parameter is an optional parameter of type V. It represents the
143
- * value associated with the key in the node being created.
144
- * @returns The method is returning a new instance of the AVLTreeNode class, casted as the generic
145
- * type AVLTreeNode<K, V>.
170
+ * @param key - The key for the new node.
171
+ * @param [value] - The value for the new node.
172
+ * @returns The newly created AVLTreeNode.
146
173
  */
147
- createNode(key, value) {
174
+ _createNode(key, value) {
148
175
  return new AVLTreeNode(key, this._isMapMode ? undefined : value);
149
176
  }
150
177
  /**
151
- * Time Complexity: O(1)
152
- * Space Complexity: O(1)
153
- *
154
- * The function creates a new AVL tree with the specified options and returns it.
155
- * @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be
156
- * passed to the `createTree` function. It is used to customize the behavior of the AVL tree that is
157
- * being created.
158
- * @returns a new AVLTree object.
159
- */
160
- createTree(options) {
161
- return new AVLTree([], {
162
- iterationType: this.iterationType,
163
- isMapMode: this._isMapMode,
164
- specifyComparable: this._specifyComparable,
165
- toEntryFn: this._toEntryFn,
166
- isReverse: this._isReverse,
167
- ...options
168
- });
169
- }
170
- /**
171
- * Time Complexity: O(1)
172
- * Space Complexity: O(1)
178
+ * Checks if the given item is an `AVLTreeNode` instance.
179
+ * @remarks Time O(1), Space O(1)
173
180
  *
174
- * The function checks if the input is an instance of AVLTreeNode.
175
- * @param {K | AVLTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter
176
- * `keyNodeOrEntry` can be of type `R` or `
177
- K | AVLTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `.
178
- * @returns a boolean value indicating whether the input parameter `keyNodeOrEntry` is
179
- * an instance of the `AVLTreeNode` class.
181
+ * @param keyNodeOrEntry - The item to check.
182
+ * @returns True if it's an AVLTreeNode, false otherwise.
180
183
  */
181
184
  isNode(keyNodeOrEntry) {
182
185
  return keyNodeOrEntry instanceof AVLTreeNode;
183
186
  }
184
187
  /**
185
- * Time Complexity: O(log n)
186
- * Space Complexity: O(log n)
188
+ * Adds a new node to the AVL tree and balances the tree path.
189
+ * @remarks Time O(log N) (O(H) for BST add + O(H) for `_balancePath`). Space O(H) for path/recursion.
187
190
  *
188
- * The function overrides the add method of a class and inserts a key-value pair into a data
189
- * structure, then balances the path.
190
- * @param { K | AVLTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The parameter
191
- * `keyNodeOrEntry` can accept values of type `R`, `
192
- K | AVLTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `
193
- * @param {V} [value] - The `value` parameter is an optional value that you want to associate with
194
- * the key or node being added to the data structure.
195
- * @returns The method is returning a boolean value.
191
+ * @param keyNodeOrEntry - The key, node, or entry to add.
192
+ * @param [value] - The value, if providing just a key.
193
+ * @returns True if the addition was successful, false otherwise.
196
194
  */
197
195
  add(keyNodeOrEntry, value) {
198
196
  if (keyNodeOrEntry === null)
199
197
  return false;
200
198
  const inserted = super.add(keyNodeOrEntry, value);
199
+ // If insertion was successful, balance the path from the new node up to the root.
201
200
  if (inserted)
202
201
  this._balancePath(keyNodeOrEntry);
203
202
  return inserted;
204
203
  }
205
204
  /**
206
- * Time Complexity: O(log n)
207
- * Space Complexity: O(log n)
205
+ * Deletes a node from the AVL tree and re-balances the tree.
206
+ * @remarks Time O(log N) (O(H) for BST delete + O(H) for `_balancePath`). Space O(H) for path/recursion.
208
207
  *
209
- * The function overrides the delete method in a TypeScript class, performs deletion, and then
210
- * balances the tree if necessary.
211
- * @param { K | AVLTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } keyNodeOrEntry - The `keyNodeOrEntry`
212
- * parameter in the `override delete` method can be one of the following types:
213
- * @returns The `delete` method is being overridden in this code snippet. It first calls the `delete`
214
- * method from the superclass (presumably a parent class) with the provided `predicate`, which could
215
- * be a key, node, entry, or a custom predicate. The result of this deletion operation is stored in
216
- * `deletedResults`, which is an array of `BinaryTreeDeleteResult` objects.
208
+ * @param keyNodeOrEntry - The node to delete.
209
+ * @returns An array containing deletion results.
217
210
  */
218
211
  delete(keyNodeOrEntry) {
219
212
  const deletedResults = super.delete(keyNodeOrEntry);
213
+ // After deletion, balance the path from the parent of the *physically deleted* node.
220
214
  for (const { needBalanced } of deletedResults) {
221
215
  if (needBalanced) {
222
216
  this._balancePath(needBalanced);
@@ -225,71 +219,108 @@ export class AVLTree extends BST {
225
219
  return deletedResults;
226
220
  }
227
221
  /**
228
- * Time Complexity: O(n)
229
- * Space Complexity: O(n)
222
+ * Rebuilds the tree to be perfectly balanced.
223
+ * @remarks AVL trees are already height-balanced, but this makes them *perfectly* balanced (minimal height and all leaves at N or N-1).
224
+ * Time O(N) (O(N) for DFS, O(N) for sorted build). Space O(N) for node array and recursion stack.
230
225
  *
231
- * The `map` function in TypeScript overrides the default map behavior of an AVLTree data structure
232
- * by applying a callback function to each entry and creating a new AVLTree with the results.
233
- * @param callback - A function that will be called for each entry in the AVLTree. It takes four
234
- * arguments: the key, the value (which can be undefined), the index of the entry, and a reference to
235
- * the AVLTree itself.
236
- * @param [options] - The `options` parameter in the `override map` function is of type
237
- * `AVLTreeOptions<MK, MV, MR>`. It is an optional parameter that allows you to specify additional
238
- * options for the AVL tree being created during the mapping process. These options could include
239
- * custom comparators, initial
240
- * @param {any} [thisArg] - The `thisArg` parameter in the `override map` function is used to specify
241
- * the value of `this` when executing the `callback` function. It allows you to set the context
242
- * (value of `this`) within the callback function. This can be useful when you want to access
243
- * properties or
244
- * @returns The `map` method is returning a new AVLTree instance (`newTree`) with the entries
245
- * modified by the provided callback function.
226
+ * @param [iterationType=this.iterationType] - The traversal method for the initial node export.
227
+ * @returns True if successful, false if the tree was empty.
228
+ */
229
+ perfectlyBalance(iterationType = this.iterationType) {
230
+ const nodes = this.dfs(node => node, 'IN', false, this._root, iterationType);
231
+ const n = nodes.length;
232
+ if (n === 0)
233
+ return false;
234
+ this._clearNodes();
235
+ // Build balanced tree from sorted array
236
+ const build = (l, r, parent) => {
237
+ if (l > r)
238
+ return undefined;
239
+ const m = l + ((r - l) >> 1);
240
+ const root = nodes[m];
241
+ root.left = build(l, m - 1, root);
242
+ root.right = build(m + 1, r, root);
243
+ root.parent = parent;
244
+ // Update height during the build
245
+ const lh = root.left ? root.left.height : -1;
246
+ const rh = root.right ? root.right.height : -1;
247
+ root.height = Math.max(lh, rh) + 1;
248
+ return root;
249
+ };
250
+ const newRoot = build(0, n - 1, undefined);
251
+ this._setRoot(newRoot);
252
+ this._size = n;
253
+ return true;
254
+ }
255
+ /**
256
+ * Creates a new AVLTree by mapping each [key, value] pair.
257
+ * @remarks Time O(N log N) (O(N) iteration + O(log M) `add` for each item into the new tree). Space O(N) for the new tree.
258
+ *
259
+ * @template MK - New key type.
260
+ * @template MV - New value type.
261
+ * @template MR - New raw type.
262
+ * @param callback - A function to map each [key, value] pair.
263
+ * @param [options] - Options for the new AVLTree.
264
+ * @param [thisArg] - `this` context for the callback.
265
+ * @returns A new, mapped AVLTree.
246
266
  */
247
267
  map(callback, options, thisArg) {
248
- const newTree = new AVLTree([], options);
268
+ const out = this._createLike([], options);
249
269
  let index = 0;
270
+ // Iterates in-order
250
271
  for (const [key, value] of this) {
251
- newTree.add(callback.call(thisArg, key, value, index++, this));
272
+ // `add` on the new tree will be O(log N) and will self-balance.
273
+ out.add(callback.call(thisArg, key, value, index++, this));
252
274
  }
253
- return newTree;
275
+ return out;
276
+ }
277
+ /**
278
+ * (Protected) Creates a new, empty instance of the same AVLTree constructor.
279
+ * @remarks Time O(1)
280
+ *
281
+ * @template TK, TV, TR - Generic types for the new instance.
282
+ * @param [options] - Options for the new tree.
283
+ * @returns A new, empty tree.
284
+ */
285
+ _createInstance(options) {
286
+ const Ctor = this.constructor;
287
+ return new Ctor([], { ...this._snapshotOptions(), ...(options ?? {}) });
254
288
  }
255
289
  /**
256
- * Time Complexity: O(n)
257
- * Space Complexity: O(n)
290
+ * (Protected) Creates a new instance of the same AVLTree constructor, potentially with different generic types.
291
+ * @remarks Time O(N log N) (from constructor) due to processing the iterable.
258
292
  *
259
- * The function `clone` overrides the default cloning behavior to create a deep copy of a tree
260
- * structure.
261
- * @returns A cloned tree object is being returned.
293
+ * @template TK, TV, TR - Generic types for the new instance.
294
+ * @param [iter=[]] - An iterable to populate the new tree.
295
+ * @param [options] - Options for the new tree.
296
+ * @returns A new AVLTree.
262
297
  */
263
- clone() {
264
- const cloned = this.createTree();
265
- this._clone(cloned);
266
- return cloned;
298
+ _createLike(iter = [], options) {
299
+ const Ctor = this.constructor;
300
+ return new Ctor(iter, { ...this._snapshotOptions(), ...(options ?? {}) });
267
301
  }
268
302
  /**
269
- * Time Complexity: O(1)
270
- * Space Complexity: O(1)
303
+ * (Protected) Swaps properties of two nodes, including height.
304
+ * @remarks Time O(H) (due to `ensureNode`), but O(1) if nodes are passed directly.
271
305
  *
272
- * The `_swapProperties` function swaps the key, value, and height properties between two nodes in a
273
- * binary search tree.
274
- * @param {BSTNOptKeyOrNode<K, AVLTreeNode<K, V>>} srcNode - The `srcNode` parameter represents either a node
275
- * object (`AVLTreeNode<K, V>`) or a key-value pair (`R`) that is being swapped with another node.
276
- * @param {BSTNOptKeyOrNode<K, AVLTreeNode<K, V>>} destNode - The `destNode` parameter is either an instance of
277
- * `R` or an instance of `BSTNOptKeyOrNode<K, AVLTreeNode<K, V>>`.
278
- * @returns The method is returning the `destNodeEnsured` object if both `srcNodeEnsured` and
279
- * `destNodeEnsured` are truthy. Otherwise, it returns `undefined`.
306
+ * @param srcNode - The source node.
307
+ * @param destNode - The destination node.
308
+ * @returns The `destNode` (now holding `srcNode`'s properties).
280
309
  */
281
310
  _swapProperties(srcNode, destNode) {
282
311
  const srcNodeEnsured = this.ensureNode(srcNode);
283
312
  const destNodeEnsured = this.ensureNode(destNode);
284
313
  if (srcNodeEnsured && destNodeEnsured) {
285
314
  const { key, value, height } = destNodeEnsured;
286
- const tempNode = this.createNode(key, value);
315
+ const tempNode = this._createNode(key, value);
287
316
  if (tempNode) {
288
317
  tempNode.height = height;
318
+ // Copy src to dest
289
319
  destNodeEnsured.key = srcNodeEnsured.key;
290
320
  if (!this._isMapMode)
291
321
  destNodeEnsured.value = srcNodeEnsured.value;
292
322
  destNodeEnsured.height = srcNodeEnsured.height;
323
+ // Copy temp (original dest) to src
293
324
  srcNodeEnsured.key = tempNode.key;
294
325
  if (!this._isMapMode)
295
326
  srcNodeEnsured.value = tempNode.value;
@@ -300,55 +331,37 @@ export class AVLTree extends BST {
300
331
  return undefined;
301
332
  }
302
333
  /**
303
- * Time Complexity: O(1)
304
- * Space Complexity: O(1)
334
+ * (Protected) Calculates the balance factor (height(right) - height(left)).
335
+ * @remarks Time O(1) (assumes heights are stored).
305
336
  *
306
- * The function calculates the balance factor of a node in a binary tree.
307
- * @param {AVLTreeNode<K, V>} node - The parameter "node" is of type "AVLTreeNode<K, V>", which likely represents a node in a
308
- * binary tree data structure.
309
- * @returns the balance factor of a given node. The balance factor is calculated by subtracting the
310
- * height of the left subtree from the height of the right subtree.
337
+ * @param node - The node to check.
338
+ * @returns The balance factor (positive if right-heavy, negative if left-heavy).
311
339
  */
312
340
  _balanceFactor(node) {
313
- if (!node.right)
314
- // node has no right subtree
315
- return -node.height;
316
- else if (!node.left)
317
- // node has no left subtree
318
- return +node.height;
319
- else
320
- return node.right.height - node.left.height;
341
+ const left = node.left ? node.left.height : -1;
342
+ const right = node.right ? node.right.height : -1;
343
+ return right - left;
321
344
  }
322
345
  /**
323
- * Time Complexity: O(1)
324
- * Space Complexity: O(1)
346
+ * (Protected) Recalculates and updates the height of a node based on its children's heights.
347
+ * @remarks Time O(1) (assumes children's heights are correct).
325
348
  *
326
- * The function updates the height of a node in a binary tree based on the heights of its left and
327
- * right children.
328
- * @param {AVLTreeNode<K, V>} node - The parameter "node" represents a node in a binary tree data structure.
349
+ * @param node - The node to update.
329
350
  */
330
351
  _updateHeight(node) {
331
- if (!node.left && !node.right)
332
- node.height = 0;
333
- else if (!node.left) {
334
- const rightHeight = node.right ? node.right.height : 0;
335
- node.height = 1 + rightHeight;
336
- }
337
- else if (!node.right)
338
- node.height = 1 + node.left.height;
339
- else
340
- node.height = 1 + Math.max(node.right.height, node.left.height);
352
+ const leftHeight = node.left ? node.left.height : -1;
353
+ const rightHeight = node.right ? node.right.height : -1;
354
+ node.height = 1 + Math.max(leftHeight, rightHeight);
341
355
  }
342
356
  /**
343
- * Time Complexity: O(1)
344
- * Space Complexity: O(1)
357
+ * (Protected) Performs a Left-Left (LL) rotation (a single right rotation).
358
+ * @remarks Time O(1), Space O(1)
345
359
  *
346
- * The `_balanceLL` function performs a left-left rotation to balance a binary search tree.
347
- * @param {AVLTreeNode<K, V>} A - A is a node in a binary tree.
360
+ * @param A - The unbalanced node (root of the unbalanced subtree).
348
361
  */
349
362
  _balanceLL(A) {
350
363
  const parentOfA = A.parent;
351
- const B = A.left;
364
+ const B = A.left; // The left child
352
365
  if (B !== null)
353
366
  A.parent = B;
354
367
  if (B && B.right) {
@@ -356,6 +369,7 @@ export class AVLTree extends BST {
356
369
  }
357
370
  if (B)
358
371
  B.parent = parentOfA;
372
+ // Update parent's child pointer
359
373
  if (A === this.root) {
360
374
  if (B)
361
375
  this._setRoot(B);
@@ -369,6 +383,7 @@ export class AVLTree extends BST {
369
383
  parentOfA.right = B;
370
384
  }
371
385
  }
386
+ // Perform rotation
372
387
  if (B) {
373
388
  A.left = B.right;
374
389
  B.right = A;
@@ -378,18 +393,17 @@ export class AVLTree extends BST {
378
393
  this._updateHeight(B);
379
394
  }
380
395
  /**
381
- * Time Complexity: O(1)
382
- * Space Complexity: O(1)
396
+ * (Protected) Performs a Left-Right (LR) double rotation.
397
+ * @remarks Time O(1), Space O(1)
383
398
  *
384
- * The `_balanceLR` function performs a left-right rotation to balance a binary tree.
385
- * @param {AVLTreeNode<K, V>} A - A is a node in a binary tree.
399
+ * @param A - The unbalanced node (root of the unbalanced subtree).
386
400
  */
387
401
  _balanceLR(A) {
388
402
  const parentOfA = A.parent;
389
403
  const B = A.left;
390
404
  let C = undefined;
391
405
  if (B) {
392
- C = B.right;
406
+ C = B.right; // The "middle" node
393
407
  }
394
408
  if (A && C !== null)
395
409
  A.parent = C;
@@ -405,6 +419,7 @@ export class AVLTree extends BST {
405
419
  }
406
420
  C.parent = parentOfA;
407
421
  }
422
+ // Update parent's child pointer
408
423
  if (A === this.root) {
409
424
  if (C)
410
425
  this._setRoot(C);
@@ -419,6 +434,7 @@ export class AVLTree extends BST {
419
434
  }
420
435
  }
421
436
  }
437
+ // Perform rotation
422
438
  if (C) {
423
439
  A.left = C.right;
424
440
  if (B)
@@ -433,15 +449,14 @@ export class AVLTree extends BST {
433
449
  this._updateHeight(C);
434
450
  }
435
451
  /**
436
- * Time Complexity: O(1)
437
- * Space Complexity: O(1)
452
+ * (Protected) Performs a Right-Right (RR) rotation (a single left rotation).
453
+ * @remarks Time O(1), Space O(1)
438
454
  *
439
- * The function `_balanceRR` performs a right-right rotation to balance a binary tree.
440
- * @param {AVLTreeNode<K, V>} A - A is a node in a binary tree.
455
+ * @param A - The unbalanced node (root of the unbalanced subtree).
441
456
  */
442
457
  _balanceRR(A) {
443
458
  const parentOfA = A.parent;
444
- const B = A.right;
459
+ const B = A.right; // The right child
445
460
  if (B !== null)
446
461
  A.parent = B;
447
462
  if (B) {
@@ -450,6 +465,7 @@ export class AVLTree extends BST {
450
465
  }
451
466
  B.parent = parentOfA;
452
467
  }
468
+ // Update parent's child pointer
453
469
  if (A === this.root) {
454
470
  if (B)
455
471
  this._setRoot(B);
@@ -464,6 +480,7 @@ export class AVLTree extends BST {
464
480
  }
465
481
  }
466
482
  }
483
+ // Perform rotation
467
484
  if (B) {
468
485
  A.right = B.left;
469
486
  B.left = A;
@@ -473,18 +490,17 @@ export class AVLTree extends BST {
473
490
  this._updateHeight(B);
474
491
  }
475
492
  /**
476
- * Time Complexity: O(1)
477
- * Space Complexity: O(1)
493
+ * (Protected) Performs a Right-Left (RL) double rotation.
494
+ * @remarks Time O(1), Space O(1)
478
495
  *
479
- * The function `_balanceRL` performs a right-left rotation to balance a binary tree.
480
- * @param {AVLTreeNode<K, V>} A - A is a node in a binary tree.
496
+ * @param A - The unbalanced node (root of the unbalanced subtree).
481
497
  */
482
498
  _balanceRL(A) {
483
499
  const parentOfA = A.parent;
484
500
  const B = A.right;
485
501
  let C = undefined;
486
502
  if (B) {
487
- C = B.left;
503
+ C = B.left; // The "middle" node
488
504
  }
489
505
  if (C !== null)
490
506
  A.parent = C;
@@ -500,6 +516,7 @@ export class AVLTree extends BST {
500
516
  }
501
517
  C.parent = parentOfA;
502
518
  }
519
+ // Update parent's child pointer
503
520
  if (A === this.root) {
504
521
  if (C)
505
522
  this._setRoot(C);
@@ -514,6 +531,7 @@ export class AVLTree extends BST {
514
531
  }
515
532
  }
516
533
  }
534
+ // Perform rotation
517
535
  if (C)
518
536
  A.right = C.left;
519
537
  if (B && C)
@@ -529,71 +547,59 @@ export class AVLTree extends BST {
529
547
  this._updateHeight(C);
530
548
  }
531
549
  /**
532
- * Time Complexity: O(log n)
533
- * Space Complexity: O(1)
550
+ * (Protected) Traverses up the tree from the specified node, updating heights and performing rotations as needed.
551
+ * @remarks Time O(log N) (O(H)), as it traverses the path to root. Space O(H) for the path array.
534
552
  *
535
- * The `_balancePath` function is used to update the heights of nodes and perform rotation operations
536
- * to restore balance in an AVL tree after inserting a node.
537
- * @param { K | AVLTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined } node - The `node` parameter can be of type `R` or
538
- * `
539
- K | AVLTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined `.
553
+ * @param node - The node to start balancing from (e.g., the newly inserted node or parent of the deleted node).
540
554
  */
541
555
  _balancePath(node) {
556
+ // Get the path from the node to the root.
542
557
  node = this.ensureNode(node);
543
- const path = this.getPathToRoot(node, node => node, false); // first O(log n) + O(log n)
558
+ const path = this.getPathToRoot(node, node => node, false);
559
+ // Iterate up the path (from node to root)
544
560
  for (let i = 0; i < path.length; i++) {
545
- // second O(log n)
546
561
  const A = path[i];
547
562
  if (A) {
548
- // Update Heights: After inserting a node, backtrack from the insertion point to the root node, updating the height of each node along the way.
549
- this._updateHeight(A); // first O(1)
550
- // Check Balance: Simultaneously with height updates, check if each node violates the balance property of an AVL tree.
551
- // Balance Restoration: If a balance issue is discovered after inserting a node, it requires balance restoration operations. Balance restoration includes four basic cases where rotation operations need to be performed to fix the balance:
552
- switch (this._balanceFactor(A) // second O(1)
553
- ) {
554
- case -2:
563
+ this._updateHeight(A);
564
+ // Check the balance factor
565
+ switch (this._balanceFactor(A)) {
566
+ case -2: // Left-heavy
555
567
  if (A && A.left) {
556
568
  if (this._balanceFactor(A.left) <= 0) {
557
- // second O(1)
558
- // Left Rotation (LL Rotation): When the inserted node is in the left subtree of the left subtree, causing an imbalance.
569
+ // Left-Left case
559
570
  this._balanceLL(A);
560
571
  }
561
572
  else {
562
- // Left-Right Rotation (LR Rotation): When the inserted node is in the right subtree of the left subtree, causing an imbalance.
573
+ // Left-Right case
563
574
  this._balanceLR(A);
564
575
  }
565
576
  }
566
577
  break;
567
- case +2:
578
+ case +2: // Right-heavy
568
579
  if (A && A.right) {
569
580
  if (this._balanceFactor(A.right) >= 0) {
570
- // Right Rotation (RR Rotation): When the inserted node is in the right subtree of the right subtree, causing an imbalance.
581
+ // Right-Right case
571
582
  this._balanceRR(A);
572
583
  }
573
584
  else {
574
- // Right-Left Rotation (RL Rotation): When the inserted node is in the left subtree of the right subtree, causing an imbalance.
585
+ // Right-Left case
575
586
  this._balanceRL(A);
576
587
  }
577
588
  }
578
589
  }
579
- // TODO So far, no sure if this is necessary that Recursive Repair: Once rotation operations are executed, it may cause imbalance issues at higher levels of the tree. Therefore, you need to recursively check and repair imbalance problems upwards until you reach the root node.
580
590
  }
581
591
  }
582
592
  }
583
593
  /**
584
- * Time Complexity: O(1)
585
- * Space Complexity: O(1)
594
+ * (Protected) Replaces a node, ensuring height is copied.
595
+ * @remarks Time O(1)
586
596
  *
587
- * The function replaces an old node with a new node and sets the height of the new node to be the
588
- * same as the old node.
589
- * @param {AVLTreeNode<K, V>} oldNode - The `oldNode` parameter represents the node that needs to be replaced in
590
- * the data structure.
591
- * @param {AVLTreeNode<K, V>} newNode - The `newNode` parameter is the new node that will replace the `oldNode` in
592
- * the data structure.
593
- * @returns The method is returning the result of calling the `_replaceNode` method from the
594
- * superclass, with the `oldNode` and `newNode` as arguments.
597
+ * @param oldNode - The node to be replaced.
598
+ * @param newNode - The node to insert.
599
+ * @returns The `newNode`.
595
600
  */
596
601
  _replaceNode(oldNode, newNode) {
602
+ // When replacing a node (e.g., on duplicate key), preserve the height.
597
603
  newNode.height = oldNode.height;
598
604
  return super._replaceNode(oldNode, newNode);
599
605
  }