tree-set-typed 2.3.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 (273) hide show
  1. package/.eslintrc.js +61 -0
  2. package/.prettierignore +6 -0
  3. package/.prettierrc.js +16 -0
  4. package/LICENSE +21 -0
  5. package/README.md +482 -0
  6. package/coverage/clover.xml +13 -0
  7. package/coverage/coverage-final.json +96 -0
  8. package/coverage/coverage-summary.json +60 -0
  9. package/coverage/lcov-report/base.css +403 -0
  10. package/coverage/lcov-report/block-navigation.js +87 -0
  11. package/coverage/lcov-report/favicon.png +0 -0
  12. package/coverage/lcov-report/index.html +119 -0
  13. package/coverage/lcov-report/index.ts.html +109 -0
  14. package/coverage/lcov-report/prettify.css +1 -0
  15. package/coverage/lcov-report/prettify.js +2 -0
  16. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  17. package/coverage/lcov-report/sorter.js +206 -0
  18. package/coverage/lcov.info +14 -0
  19. package/dist/cjs/index.cjs +12 -0
  20. package/dist/cjs/index.cjs.map +1 -0
  21. package/dist/cjs-legacy/index.cjs +12 -0
  22. package/dist/cjs-legacy/index.cjs.map +1 -0
  23. package/dist/esm/index.mjs +3 -0
  24. package/dist/esm/index.mjs.map +1 -0
  25. package/dist/esm-legacy/index.mjs +3 -0
  26. package/dist/esm-legacy/index.mjs.map +1 -0
  27. package/dist/types/common/index.d.ts +12 -0
  28. package/dist/types/constants/index.d.ts +4 -0
  29. package/dist/types/data-structures/base/index.d.ts +2 -0
  30. package/dist/types/data-structures/base/iterable-element-base.d.ts +219 -0
  31. package/dist/types/data-structures/base/iterable-entry-base.d.ts +150 -0
  32. package/dist/types/data-structures/base/linear-base.d.ts +335 -0
  33. package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +236 -0
  34. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +197 -0
  35. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +440 -0
  36. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +174 -0
  37. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +807 -0
  38. package/dist/types/data-structures/binary-tree/bst.d.ts +645 -0
  39. package/dist/types/data-structures/binary-tree/index.d.ts +10 -0
  40. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +312 -0
  41. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +160 -0
  42. package/dist/types/data-structures/binary-tree/tree-counter.d.ts +243 -0
  43. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +333 -0
  44. package/dist/types/data-structures/graph/abstract-graph.d.ts +340 -0
  45. package/dist/types/data-structures/graph/directed-graph.d.ts +332 -0
  46. package/dist/types/data-structures/graph/index.d.ts +4 -0
  47. package/dist/types/data-structures/graph/map-graph.d.ts +78 -0
  48. package/dist/types/data-structures/graph/undirected-graph.d.ts +347 -0
  49. package/dist/types/data-structures/hash/hash-map.d.ts +428 -0
  50. package/dist/types/data-structures/hash/index.d.ts +1 -0
  51. package/dist/types/data-structures/heap/heap.d.ts +552 -0
  52. package/dist/types/data-structures/heap/index.d.ts +3 -0
  53. package/dist/types/data-structures/heap/max-heap.d.ts +32 -0
  54. package/dist/types/data-structures/heap/min-heap.d.ts +33 -0
  55. package/dist/types/data-structures/index.d.ts +12 -0
  56. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +437 -0
  57. package/dist/types/data-structures/linked-list/index.d.ts +3 -0
  58. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +567 -0
  59. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +27 -0
  60. package/dist/types/data-structures/matrix/index.d.ts +2 -0
  61. package/dist/types/data-structures/matrix/matrix.d.ts +168 -0
  62. package/dist/types/data-structures/matrix/navigator.d.ts +55 -0
  63. package/dist/types/data-structures/priority-queue/index.d.ts +3 -0
  64. package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +27 -0
  65. package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +26 -0
  66. package/dist/types/data-structures/priority-queue/priority-queue.d.ts +15 -0
  67. package/dist/types/data-structures/queue/deque.d.ts +459 -0
  68. package/dist/types/data-structures/queue/index.d.ts +2 -0
  69. package/dist/types/data-structures/queue/queue.d.ts +364 -0
  70. package/dist/types/data-structures/stack/index.d.ts +1 -0
  71. package/dist/types/data-structures/stack/stack.d.ts +324 -0
  72. package/dist/types/data-structures/tree/index.d.ts +1 -0
  73. package/dist/types/data-structures/tree/tree.d.ts +62 -0
  74. package/dist/types/data-structures/trie/index.d.ts +1 -0
  75. package/dist/types/data-structures/trie/trie.d.ts +412 -0
  76. package/dist/types/index.d.ts +23 -0
  77. package/dist/types/interfaces/binary-tree.d.ts +60 -0
  78. package/dist/types/interfaces/doubly-linked-list.d.ts +1 -0
  79. package/dist/types/interfaces/graph.d.ts +21 -0
  80. package/dist/types/interfaces/heap.d.ts +1 -0
  81. package/dist/types/interfaces/index.d.ts +8 -0
  82. package/dist/types/interfaces/navigator.d.ts +1 -0
  83. package/dist/types/interfaces/priority-queue.d.ts +1 -0
  84. package/dist/types/interfaces/segment-tree.d.ts +1 -0
  85. package/dist/types/interfaces/singly-linked-list.d.ts +1 -0
  86. package/dist/types/types/common.d.ts +15 -0
  87. package/dist/types/types/data-structures/base/base.d.ts +13 -0
  88. package/dist/types/types/data-structures/base/index.d.ts +1 -0
  89. package/dist/types/types/data-structures/binary-tree/avl-tree-counter.d.ts +2 -0
  90. package/dist/types/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +2 -0
  91. package/dist/types/types/data-structures/binary-tree/avl-tree.d.ts +2 -0
  92. package/dist/types/types/data-structures/binary-tree/binary-indexed-tree.d.ts +1 -0
  93. package/dist/types/types/data-structures/binary-tree/binary-tree.d.ts +29 -0
  94. package/dist/types/types/data-structures/binary-tree/bst.d.ts +12 -0
  95. package/dist/types/types/data-structures/binary-tree/index.d.ts +9 -0
  96. package/dist/types/types/data-structures/binary-tree/red-black-tree.d.ts +3 -0
  97. package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -0
  98. package/dist/types/types/data-structures/binary-tree/tree-counter.d.ts +2 -0
  99. package/dist/types/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -0
  100. package/dist/types/types/data-structures/graph/abstract-graph.d.ts +14 -0
  101. package/dist/types/types/data-structures/graph/directed-graph.d.ts +1 -0
  102. package/dist/types/types/data-structures/graph/index.d.ts +3 -0
  103. package/dist/types/types/data-structures/graph/map-graph.d.ts +1 -0
  104. package/dist/types/types/data-structures/graph/undirected-graph.d.ts +1 -0
  105. package/dist/types/types/data-structures/hash/hash-map.d.ts +19 -0
  106. package/dist/types/types/data-structures/hash/index.d.ts +2 -0
  107. package/dist/types/types/data-structures/heap/heap.d.ts +5 -0
  108. package/dist/types/types/data-structures/heap/index.d.ts +1 -0
  109. package/dist/types/types/data-structures/heap/max-heap.d.ts +1 -0
  110. package/dist/types/types/data-structures/heap/min-heap.d.ts +1 -0
  111. package/dist/types/types/data-structures/index.d.ts +12 -0
  112. package/dist/types/types/data-structures/linked-list/doubly-linked-list.d.ts +2 -0
  113. package/dist/types/types/data-structures/linked-list/index.d.ts +3 -0
  114. package/dist/types/types/data-structures/linked-list/singly-linked-list.d.ts +2 -0
  115. package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +4 -0
  116. package/dist/types/types/data-structures/matrix/index.d.ts +2 -0
  117. package/dist/types/types/data-structures/matrix/matrix.d.ts +7 -0
  118. package/dist/types/types/data-structures/matrix/navigator.d.ts +14 -0
  119. package/dist/types/types/data-structures/priority-queue/index.d.ts +3 -0
  120. package/dist/types/types/data-structures/priority-queue/max-priority-queue.d.ts +1 -0
  121. package/dist/types/types/data-structures/priority-queue/min-priority-queue.d.ts +1 -0
  122. package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +2 -0
  123. package/dist/types/types/data-structures/queue/deque.d.ts +4 -0
  124. package/dist/types/types/data-structures/queue/index.d.ts +2 -0
  125. package/dist/types/types/data-structures/queue/queue.d.ts +4 -0
  126. package/dist/types/types/data-structures/stack/index.d.ts +1 -0
  127. package/dist/types/types/data-structures/stack/stack.d.ts +2 -0
  128. package/dist/types/types/data-structures/tree/index.d.ts +1 -0
  129. package/dist/types/types/data-structures/tree/tree.d.ts +1 -0
  130. package/dist/types/types/data-structures/trie/index.d.ts +1 -0
  131. package/dist/types/types/data-structures/trie/trie.d.ts +4 -0
  132. package/dist/types/types/index.d.ts +3 -0
  133. package/dist/types/types/utils/index.d.ts +2 -0
  134. package/dist/types/types/utils/utils.d.ts +22 -0
  135. package/dist/types/types/utils/validate-type.d.ts +19 -0
  136. package/dist/types/utils/index.d.ts +2 -0
  137. package/dist/types/utils/number.d.ts +14 -0
  138. package/dist/types/utils/utils.d.ts +209 -0
  139. package/dist/umd/red-black-tree-typed.js +14578 -0
  140. package/dist/umd/red-black-tree-typed.js.map +1 -0
  141. package/dist/umd/red-black-tree-typed.min.js +44 -0
  142. package/dist/umd/red-black-tree-typed.min.js.map +1 -0
  143. package/docs/.nojekyll +1 -0
  144. package/docs/assets/highlight.css +92 -0
  145. package/docs/assets/main.js +59 -0
  146. package/docs/assets/navigation.js +1 -0
  147. package/docs/assets/search.js +1 -0
  148. package/docs/assets/style.css +1383 -0
  149. package/docs/classes/AVLTree.html +2046 -0
  150. package/docs/classes/AVLTreeNode.html +263 -0
  151. package/docs/index.html +523 -0
  152. package/docs/modules.html +45 -0
  153. package/jest.config.js +8 -0
  154. package/package.json +113 -0
  155. package/src/common/index.ts +23 -0
  156. package/src/constants/index.ts +4 -0
  157. package/src/data-structures/base/index.ts +2 -0
  158. package/src/data-structures/base/iterable-element-base.ts +352 -0
  159. package/src/data-structures/base/iterable-entry-base.ts +246 -0
  160. package/src/data-structures/base/linear-base.ts +643 -0
  161. package/src/data-structures/binary-tree/avl-tree-counter.ts +539 -0
  162. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +438 -0
  163. package/src/data-structures/binary-tree/avl-tree.ts +840 -0
  164. package/src/data-structures/binary-tree/binary-indexed-tree.ts +331 -0
  165. package/src/data-structures/binary-tree/binary-tree.ts +2492 -0
  166. package/src/data-structures/binary-tree/bst.ts +2024 -0
  167. package/src/data-structures/binary-tree/index.ts +10 -0
  168. package/src/data-structures/binary-tree/red-black-tree.ts +767 -0
  169. package/src/data-structures/binary-tree/segment-tree.ts +324 -0
  170. package/src/data-structures/binary-tree/tree-counter.ts +575 -0
  171. package/src/data-structures/binary-tree/tree-multi-map.ts +549 -0
  172. package/src/data-structures/graph/abstract-graph.ts +1081 -0
  173. package/src/data-structures/graph/directed-graph.ts +715 -0
  174. package/src/data-structures/graph/index.ts +4 -0
  175. package/src/data-structures/graph/map-graph.ts +132 -0
  176. package/src/data-structures/graph/undirected-graph.ts +626 -0
  177. package/src/data-structures/hash/hash-map.ts +813 -0
  178. package/src/data-structures/hash/index.ts +1 -0
  179. package/src/data-structures/heap/heap.ts +1020 -0
  180. package/src/data-structures/heap/index.ts +3 -0
  181. package/src/data-structures/heap/max-heap.ts +47 -0
  182. package/src/data-structures/heap/min-heap.ts +36 -0
  183. package/src/data-structures/index.ts +12 -0
  184. package/src/data-structures/linked-list/doubly-linked-list.ts +876 -0
  185. package/src/data-structures/linked-list/index.ts +3 -0
  186. package/src/data-structures/linked-list/singly-linked-list.ts +1050 -0
  187. package/src/data-structures/linked-list/skip-linked-list.ts +173 -0
  188. package/src/data-structures/matrix/index.ts +2 -0
  189. package/src/data-structures/matrix/matrix.ts +491 -0
  190. package/src/data-structures/matrix/navigator.ts +124 -0
  191. package/src/data-structures/priority-queue/index.ts +3 -0
  192. package/src/data-structures/priority-queue/max-priority-queue.ts +42 -0
  193. package/src/data-structures/priority-queue/min-priority-queue.ts +29 -0
  194. package/src/data-structures/priority-queue/priority-queue.ts +19 -0
  195. package/src/data-structures/queue/deque.ts +1001 -0
  196. package/src/data-structures/queue/index.ts +2 -0
  197. package/src/data-structures/queue/queue.ts +592 -0
  198. package/src/data-structures/stack/index.ts +1 -0
  199. package/src/data-structures/stack/stack.ts +469 -0
  200. package/src/data-structures/tree/index.ts +1 -0
  201. package/src/data-structures/tree/tree.ts +115 -0
  202. package/src/data-structures/trie/index.ts +1 -0
  203. package/src/data-structures/trie/trie.ts +756 -0
  204. package/src/index.ts +24 -0
  205. package/src/interfaces/binary-tree.ts +252 -0
  206. package/src/interfaces/doubly-linked-list.ts +1 -0
  207. package/src/interfaces/graph.ts +44 -0
  208. package/src/interfaces/heap.ts +1 -0
  209. package/src/interfaces/index.ts +8 -0
  210. package/src/interfaces/navigator.ts +1 -0
  211. package/src/interfaces/priority-queue.ts +1 -0
  212. package/src/interfaces/segment-tree.ts +1 -0
  213. package/src/interfaces/singly-linked-list.ts +1 -0
  214. package/src/types/common.ts +25 -0
  215. package/src/types/data-structures/base/base.ts +34 -0
  216. package/src/types/data-structures/base/index.ts +1 -0
  217. package/src/types/data-structures/binary-tree/avl-tree-counter.ts +3 -0
  218. package/src/types/data-structures/binary-tree/avl-tree-multi-map.ts +3 -0
  219. package/src/types/data-structures/binary-tree/avl-tree.ts +3 -0
  220. package/src/types/data-structures/binary-tree/binary-indexed-tree.ts +1 -0
  221. package/src/types/data-structures/binary-tree/binary-tree.ts +31 -0
  222. package/src/types/data-structures/binary-tree/bst.ts +19 -0
  223. package/src/types/data-structures/binary-tree/index.ts +9 -0
  224. package/src/types/data-structures/binary-tree/red-black-tree.ts +5 -0
  225. package/src/types/data-structures/binary-tree/segment-tree.ts +1 -0
  226. package/src/types/data-structures/binary-tree/tree-counter.ts +3 -0
  227. package/src/types/data-structures/binary-tree/tree-multi-map.ts +3 -0
  228. package/src/types/data-structures/graph/abstract-graph.ts +18 -0
  229. package/src/types/data-structures/graph/directed-graph.ts +2 -0
  230. package/src/types/data-structures/graph/index.ts +3 -0
  231. package/src/types/data-structures/graph/map-graph.ts +1 -0
  232. package/src/types/data-structures/graph/undirected-graph.ts +1 -0
  233. package/src/types/data-structures/hash/hash-map.ts +19 -0
  234. package/src/types/data-structures/hash/index.ts +3 -0
  235. package/src/types/data-structures/heap/heap.ts +6 -0
  236. package/src/types/data-structures/heap/index.ts +1 -0
  237. package/src/types/data-structures/heap/max-heap.ts +1 -0
  238. package/src/types/data-structures/heap/min-heap.ts +1 -0
  239. package/src/types/data-structures/index.ts +12 -0
  240. package/src/types/data-structures/linked-list/doubly-linked-list.ts +3 -0
  241. package/src/types/data-structures/linked-list/index.ts +3 -0
  242. package/src/types/data-structures/linked-list/singly-linked-list.ts +3 -0
  243. package/src/types/data-structures/linked-list/skip-linked-list.ts +1 -0
  244. package/src/types/data-structures/matrix/index.ts +2 -0
  245. package/src/types/data-structures/matrix/matrix.ts +7 -0
  246. package/src/types/data-structures/matrix/navigator.ts +14 -0
  247. package/src/types/data-structures/priority-queue/index.ts +3 -0
  248. package/src/types/data-structures/priority-queue/max-priority-queue.ts +1 -0
  249. package/src/types/data-structures/priority-queue/min-priority-queue.ts +1 -0
  250. package/src/types/data-structures/priority-queue/priority-queue.ts +3 -0
  251. package/src/types/data-structures/queue/deque.ts +5 -0
  252. package/src/types/data-structures/queue/index.ts +2 -0
  253. package/src/types/data-structures/queue/queue.ts +5 -0
  254. package/src/types/data-structures/stack/index.ts +1 -0
  255. package/src/types/data-structures/stack/stack.ts +3 -0
  256. package/src/types/data-structures/tree/index.ts +1 -0
  257. package/src/types/data-structures/tree/tree.ts +1 -0
  258. package/src/types/data-structures/trie/index.ts +1 -0
  259. package/src/types/data-structures/trie/trie.ts +3 -0
  260. package/src/types/index.ts +3 -0
  261. package/src/types/utils/index.ts +2 -0
  262. package/src/types/utils/utils.ts +33 -0
  263. package/src/types/utils/validate-type.ts +35 -0
  264. package/src/utils/index.ts +2 -0
  265. package/src/utils/number.ts +22 -0
  266. package/src/utils/utils.ts +350 -0
  267. package/test/index.test.ts +111 -0
  268. package/tsconfig.base.json +23 -0
  269. package/tsconfig.json +12 -0
  270. package/tsconfig.test.json +8 -0
  271. package/tsconfig.types.json +15 -0
  272. package/tsup.config.js +28 -0
  273. package/tsup.node.config.js +71 -0
@@ -0,0 +1,767 @@
1
+ /**
2
+ * data-structure-typed
3
+ *
4
+ * @author Pablo Zeng
5
+ * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
6
+ * @license MIT License
7
+ */
8
+
9
+ import type {
10
+ BinaryTreeDeleteResult,
11
+ CRUD,
12
+ EntryCallback,
13
+ FamilyPosition,
14
+ OptNode,
15
+ RBTNColor,
16
+ RedBlackTreeOptions
17
+ } from '../../types';
18
+ import { BST } from './bst';
19
+ import { IBinaryTree } from '../../interfaces';
20
+
21
+ export class RedBlackTreeNode<K = any, V = any> {
22
+ key: K;
23
+ value?: V;
24
+ parent?: RedBlackTreeNode<K, V> = undefined;
25
+
26
+ /**
27
+ * Create a Red-Black Tree and optionally bulk-insert items.
28
+ * @remarks Time O(n log n), Space O(n)
29
+ * @param key - See parameter type for details.
30
+ * @param [value]- See parameter type for details.
31
+ * @param color - See parameter type for details.
32
+ * @returns New RedBlackTree instance.
33
+ */
34
+
35
+ constructor(key: K, value?: V, color: RBTNColor = 'BLACK') {
36
+ this.key = key;
37
+ this.value = value;
38
+ this.color = color;
39
+ }
40
+
41
+ _left?: RedBlackTreeNode<K, V> | null | undefined = undefined;
42
+
43
+ /**
44
+ * Get the left child pointer.
45
+ * @remarks Time O(1), Space O(1)
46
+ * @returns Left child node, or null/undefined.
47
+ */
48
+
49
+ get left(): RedBlackTreeNode<K, V> | null | undefined {
50
+ return this._left;
51
+ }
52
+
53
+ /**
54
+ * Set the left child and update its parent pointer.
55
+ * @remarks Time O(1), Space O(1)
56
+ * @param v - New left node, or null/undefined.
57
+ * @returns void
58
+ */
59
+
60
+ set left(v: RedBlackTreeNode<K, V> | null | undefined) {
61
+ if (v) {
62
+ v.parent = this;
63
+ }
64
+ this._left = v;
65
+ }
66
+
67
+ _right?: RedBlackTreeNode<K, V> | null | undefined = undefined;
68
+
69
+ /**
70
+ * Get the right child pointer.
71
+ * @remarks Time O(1), Space O(1)
72
+ * @returns Right child node, or null/undefined.
73
+ */
74
+
75
+ get right(): RedBlackTreeNode<K, V> | null | undefined {
76
+ return this._right;
77
+ }
78
+
79
+ /**
80
+ * Set the right child and update its parent pointer.
81
+ * @remarks Time O(1), Space O(1)
82
+ * @param v - New right node, or null/undefined.
83
+ * @returns void
84
+ */
85
+
86
+ set right(v: RedBlackTreeNode<K, V> | null | undefined) {
87
+ if (v) {
88
+ v.parent = this;
89
+ }
90
+ this._right = v;
91
+ }
92
+
93
+ _height: number = 0;
94
+
95
+ /**
96
+ * Gets the height of the node (used in self-balancing trees).
97
+ * @remarks Time O(1), Space O(1)
98
+ *
99
+ * @returns The height.
100
+ */
101
+ get height(): number {
102
+ return this._height;
103
+ }
104
+
105
+ /**
106
+ * Sets the height of the node.
107
+ * @remarks Time O(1), Space O(1)
108
+ *
109
+ * @param value - The new height.
110
+ */
111
+ set height(value: number) {
112
+ this._height = value;
113
+ }
114
+
115
+ _color: RBTNColor = 'BLACK';
116
+
117
+ /**
118
+ * Gets the color of the node (used in Red-Black trees).
119
+ * @remarks Time O(1), Space O(1)
120
+ *
121
+ * @returns The node's color.
122
+ */
123
+ get color(): RBTNColor {
124
+ return this._color;
125
+ }
126
+
127
+ /**
128
+ * Sets the color of the node.
129
+ * @remarks Time O(1), Space O(1)
130
+ *
131
+ * @param value - The new color.
132
+ */
133
+ set color(value: RBTNColor) {
134
+ this._color = value;
135
+ }
136
+
137
+ _count: number = 1;
138
+
139
+ /**
140
+ * Gets the count of nodes in the subtree rooted at this node (used in order-statistic trees).
141
+ * @remarks Time O(1), Space O(1)
142
+ *
143
+ * @returns The subtree node count.
144
+ */
145
+ get count(): number {
146
+ return this._count;
147
+ }
148
+
149
+ /**
150
+ * Sets the count of nodes in the subtree.
151
+ * @remarks Time O(1), Space O(1)
152
+ *
153
+ * @param value - The new count.
154
+ */
155
+ set count(value: number) {
156
+ this._count = value;
157
+ }
158
+
159
+ /**
160
+ * Gets the position of the node relative to its parent.
161
+ * @remarks Time O(1), Space O(1)
162
+ *
163
+ * @returns The family position (e.g., 'ROOT', 'LEFT', 'RIGHT').
164
+ */
165
+ get familyPosition(): FamilyPosition {
166
+ if (!this.parent) {
167
+ return this.left || this.right ? 'ROOT' : 'ISOLATED';
168
+ }
169
+
170
+ if (this.parent.left === this) {
171
+ return this.left || this.right ? 'ROOT_LEFT' : 'LEFT';
172
+ } else if (this.parent.right === this) {
173
+ return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';
174
+ }
175
+
176
+ return 'MAL_NODE';
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Represents a Red-Black Tree (self-balancing BST) supporting map-like mode and stable O(log n) updates.
182
+ * @remarks Time O(1), Space O(1)
183
+ * @template K
184
+ * @template V
185
+ * @template R
186
+ * 1. Efficient self-balancing, but not completely balanced. Compared with AVLTree, the addition and deletion efficiency is high, but the query efficiency is slightly lower.
187
+ * 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
188
+ *
189
+ * @example
190
+ * // basic Red-Black Tree with simple number keys
191
+ * // Create a simple Red-Black Tree with numeric keys
192
+ * const tree = new RedBlackTree([5, 2, 8, 1, 9]);
193
+ *
194
+ * tree.print();
195
+ * // _2___
196
+ * // / \
197
+ * // 1 _8_
198
+ * // / \
199
+ * // 5 9
200
+ *
201
+ * // Verify the tree maintains sorted order
202
+ * console.log([...tree.keys()]); // [1, 2, 5, 8, 9];
203
+ *
204
+ * // Check size
205
+ * console.log(tree.size); // 5;
206
+ * @example
207
+ * // Red-Black Tree with key-value pairs for lookups
208
+ * interface Employee {
209
+ * id: number;
210
+ * name: string;
211
+ * }
212
+ *
213
+ * // Create tree with employee data
214
+ * const employees = new RedBlackTree<number, Employee>([
215
+ * [1, { id: 1, name: 'Alice' }],
216
+ * [3, { id: 3, name: 'Charlie' }],
217
+ * [2, { id: 2, name: 'Bob' }]
218
+ * ]);
219
+ *
220
+ * // Retrieve employee by ID
221
+ * const alice = employees.get(1);
222
+ * console.log(alice?.name); // 'Alice';
223
+ *
224
+ * // Verify sorted order by ID
225
+ * console.log([...employees.keys()]); // [1, 2, 3];
226
+ * @example
227
+ * // Red-Black Tree range search for filtering
228
+ * interface Product {
229
+ * name: string;
230
+ * price: number;
231
+ * }
232
+ *
233
+ * const products = new RedBlackTree<number, Product>([
234
+ * [10, { name: 'Item A', price: 10 }],
235
+ * [25, { name: 'Item B', price: 25 }],
236
+ * [40, { name: 'Item C', price: 40 }],
237
+ * [50, { name: 'Item D', price: 50 }]
238
+ * ]);
239
+ *
240
+ * // Find products in price range [20, 45]
241
+ * const pricesInRange = products.rangeSearch([20, 45], node => {
242
+ * return products.get(node)?.name;
243
+ * });
244
+ *
245
+ * console.log(pricesInRange); // ['Item B', 'Item C'];
246
+ * @example
247
+ * // Red-Black Tree as database index for stock market data
248
+ * interface StockPrice {
249
+ * symbol: string;
250
+ * volume: number;
251
+ * timestamp: Date;
252
+ * }
253
+ *
254
+ * // Simulate real-time stock price index
255
+ * const priceIndex = new RedBlackTree<number, StockPrice>([
256
+ * [142.5, { symbol: 'AAPL', volume: 1000000, timestamp: new Date() }],
257
+ * [335.2, { symbol: 'MSFT', volume: 800000, timestamp: new Date() }],
258
+ * [3285.04, { symbol: 'AMZN', volume: 500000, timestamp: new Date() }],
259
+ * [267.98, { symbol: 'META', volume: 750000, timestamp: new Date() }],
260
+ * [234.57, { symbol: 'GOOGL', volume: 900000, timestamp: new Date() }]
261
+ * ]);
262
+ *
263
+ * // Find highest-priced stock
264
+ * const maxPrice = priceIndex.getRightMost();
265
+ * console.log(priceIndex.get(maxPrice)?.symbol); // 'AMZN';
266
+ *
267
+ * // Find stocks in price range [200, 400] for portfolio balancing
268
+ * const stocksInRange = priceIndex.rangeSearch([200, 400], node => {
269
+ * const stock = priceIndex.get(node);
270
+ * return {
271
+ * symbol: stock?.symbol,
272
+ * price: node,
273
+ * volume: stock?.volume
274
+ * };
275
+ * });
276
+ *
277
+ * console.log(stocksInRange.length); // 3;
278
+ * console.log(stocksInRange.some((s: any) => s.symbol === 'GOOGL')); // true;
279
+ * console.log(stocksInRange.some((s: any) => s.symbol === 'META')); // true;
280
+ * console.log(stocksInRange.some((s: any) => s.symbol === 'MSFT')); // true;
281
+ */
282
+
283
+ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implements IBinaryTree<K, V, R> {
284
+ constructor(
285
+ keysNodesEntriesOrRaws: Iterable<
286
+ K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R
287
+ > = [],
288
+ options?: RedBlackTreeOptions<K, V, R>
289
+ ) {
290
+ super([], options);
291
+
292
+ this._root = this.NIL;
293
+
294
+ if (keysNodesEntriesOrRaws) {
295
+ this.setMany(keysNodesEntriesOrRaws);
296
+ }
297
+ }
298
+
299
+ protected override _root: RedBlackTreeNode<K, V> | undefined;
300
+
301
+ /**
302
+ * Get the current root node.
303
+ * @remarks Time O(1), Space O(1)
304
+ * @returns Root node, or undefined.
305
+ */
306
+ override get root(): RedBlackTreeNode<K, V> | undefined {
307
+ return this._root;
308
+ }
309
+
310
+ /**
311
+ * Create a red-black node for the given key/value (value ignored in map mode).
312
+ * @remarks Time O(1), Space O(1)
313
+ * @param key - See parameter type for details.
314
+ * @param [value] - See parameter type for details.
315
+ * @param color - See parameter type for details.
316
+ * @returns A new RedBlackTreeNode instance.
317
+ */
318
+ override createNode(key: K, value?: V, color: RBTNColor = 'BLACK'): RedBlackTreeNode<K, V> {
319
+ return new RedBlackTreeNode<K, V>(key, this._isMapMode ? undefined : value, color);
320
+ }
321
+
322
+ /**
323
+ * Type guard: check whether the input is a RedBlackTreeNode.
324
+ * @remarks Time O(1), Space O(1)
325
+ * @param keyNodeOrEntry - See parameter type for details.
326
+ * @returns True if the value is a RedBlackTreeNode.
327
+ */
328
+
329
+ override isNode(
330
+ keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
331
+ ): keyNodeOrEntry is RedBlackTreeNode<K, V> {
332
+ return keyNodeOrEntry instanceof RedBlackTreeNode;
333
+ }
334
+
335
+ /**
336
+ * Remove all nodes and clear the key→value store (if in map mode).
337
+ * @remarks Time O(n), Space O(1)
338
+ * @returns void
339
+ */
340
+
341
+ override clear() {
342
+ super.clear();
343
+ this._root = this.NIL;
344
+ }
345
+
346
+ /**
347
+ * Insert or replace an entry using BST order and red-black fix-up.
348
+ * @remarks Time O(log n), Space O(1)
349
+ * @param keyNodeOrEntry - Key, node, or [key, value] entry to insert.
350
+ * @param [value]- See parameter type for details.
351
+ * @returns True if inserted or updated; false if ignored.
352
+ */
353
+ override set(
354
+ keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
355
+ value?: V
356
+ ): boolean {
357
+ const [newNode, newValue] = this._keyValueNodeOrEntryToNodeAndValue(keyNodeOrEntry, value);
358
+ if (!this.isRealNode(newNode)) return false;
359
+
360
+ const insertStatus = this._insert(newNode);
361
+
362
+ if (insertStatus === 'CREATED') {
363
+ if (this.isRealNode(this._root)) {
364
+ this._root.color = 'BLACK';
365
+ } else {
366
+ return false;
367
+ }
368
+ if (this._isMapMode) this._setValue(newNode.key, newValue);
369
+ this._size++;
370
+ return true;
371
+ }
372
+ if (insertStatus === 'UPDATED') {
373
+ if (this._isMapMode) this._setValue(newNode.key, newValue);
374
+ return true;
375
+ }
376
+ return false;
377
+ }
378
+
379
+ /**
380
+ * Delete a node by key/node/entry and rebalance as needed.
381
+ * @remarks Time O(log n), Space O(1)
382
+ * @param keyNodeOrEntry - Key, node, or [key, value] entry identifying the node to delete.
383
+ * @returns Array with deletion metadata (removed node, rebalancing hint if any).
384
+ */
385
+
386
+ override delete(
387
+ keyNodeOrEntry: K | RedBlackTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
388
+ ): BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>[] {
389
+ if (keyNodeOrEntry === null) return [];
390
+
391
+ const results: BinaryTreeDeleteResult<RedBlackTreeNode<K, V>>[] = [];
392
+ let nodeToDelete: OptNode<RedBlackTreeNode<K, V>>;
393
+ if (this._isPredicate(keyNodeOrEntry)) nodeToDelete = this.getNode(keyNodeOrEntry);
394
+ else nodeToDelete = this.isRealNode(keyNodeOrEntry) ? keyNodeOrEntry : this.getNode(keyNodeOrEntry);
395
+
396
+ if (!nodeToDelete) {
397
+ return results;
398
+ }
399
+
400
+ let originalColor = nodeToDelete.color;
401
+ let replacementNode: RedBlackTreeNode<K, V> | undefined;
402
+
403
+ if (!this.isRealNode(nodeToDelete.left)) {
404
+ if (nodeToDelete.right !== null) {
405
+ replacementNode = nodeToDelete.right;
406
+ this._transplant(nodeToDelete, nodeToDelete.right);
407
+ }
408
+ } else if (!this.isRealNode(nodeToDelete.right)) {
409
+ replacementNode = nodeToDelete.left;
410
+ this._transplant(nodeToDelete, nodeToDelete.left);
411
+ } else {
412
+ const successor = this.getLeftMost(node => node, nodeToDelete.right);
413
+ if (successor) {
414
+ originalColor = successor.color;
415
+ if (successor.right !== null) replacementNode = successor.right;
416
+
417
+ if (successor.parent === nodeToDelete) {
418
+ if (this.isRealNode(replacementNode)) {
419
+ replacementNode.parent = successor;
420
+ }
421
+ } else {
422
+ if (successor.right !== null) {
423
+ this._transplant(successor, successor.right);
424
+ successor.right = nodeToDelete.right;
425
+ }
426
+ if (this.isRealNode(successor.right)) {
427
+ successor.right.parent = successor;
428
+ }
429
+ }
430
+
431
+ this._transplant(nodeToDelete, successor);
432
+ successor.left = nodeToDelete.left;
433
+ if (this.isRealNode(successor.left)) {
434
+ successor.left.parent = successor;
435
+ }
436
+ successor.color = nodeToDelete.color;
437
+ }
438
+ }
439
+ if (this._isMapMode) this._store.delete(nodeToDelete.key);
440
+ this._size--;
441
+
442
+ if (originalColor === 'BLACK') {
443
+ this._deleteFixup(replacementNode);
444
+ }
445
+
446
+ results.push({ deleted: nodeToDelete, needBalanced: undefined });
447
+
448
+ return results;
449
+ }
450
+
451
+ /**
452
+ * Transform entries into a like-kind red-black tree with possibly different key/value types.
453
+ * @remarks Time O(n), Space O(n)
454
+ * @template MK
455
+ * @template MV
456
+ * @template MR
457
+ * @param callback - Mapping function from (key, value, index, tree) to a new [key, value].
458
+ * @param [options] - See parameter type for details.
459
+ * @param [thisArg] - See parameter type for details.
460
+ * @returns A new RedBlackTree with mapped entries.
461
+ */
462
+
463
+ override map<MK = K, MV = V, MR = any>(
464
+ callback: EntryCallback<K, V | undefined, [MK, MV]>,
465
+ options?: Partial<RedBlackTreeOptions<MK, MV, MR>>,
466
+ thisArg?: unknown
467
+ ): RedBlackTree<MK, MV, MR> {
468
+ const out = this._createLike<MK, MV, MR>([], options);
469
+
470
+ let index = 0;
471
+ for (const [key, value] of this) {
472
+ out.set(callback.call(thisArg, value, key, index++, this));
473
+ }
474
+ return out;
475
+ }
476
+
477
+ protected override _createInstance<TK = K, TV = V, TR = R>(options?: Partial<RedBlackTreeOptions<TK, TV, TR>>): this {
478
+ const Ctor = this.constructor as unknown as new (
479
+ iter?: Iterable<TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
480
+ opts?: RedBlackTreeOptions<TK, TV, TR>
481
+ ) => RedBlackTree<TK, TV, TR>;
482
+ return new Ctor([], { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) }) as unknown as this;
483
+ }
484
+
485
+ protected override _createLike<TK = K, TV = V, TR = R>(
486
+ iter: Iterable<
487
+ TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
488
+ > = [],
489
+ options?: Partial<RedBlackTreeOptions<TK, TV, TR>>
490
+ ): RedBlackTree<TK, TV, TR> {
491
+ const Ctor = this.constructor as unknown as new (
492
+ iter?: Iterable<TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
493
+ opts?: RedBlackTreeOptions<TK, TV, TR>
494
+ ) => RedBlackTree<TK, TV, TR>;
495
+ return new Ctor(iter, { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) });
496
+ }
497
+
498
+ protected override _setRoot(v: RedBlackTreeNode<K, V> | undefined) {
499
+ if (v) {
500
+ v.parent = undefined;
501
+ }
502
+ this._root = v;
503
+ }
504
+
505
+ protected override _replaceNode(
506
+ oldNode: RedBlackTreeNode<K, V>,
507
+ newNode: RedBlackTreeNode<K, V>
508
+ ): RedBlackTreeNode<K, V> {
509
+ newNode.color = oldNode.color;
510
+
511
+ return super._replaceNode(oldNode, newNode);
512
+ }
513
+
514
+ /**
515
+ * (Protected) Standard BST insert followed by red-black fix-up.
516
+ * @remarks Time O(log n), Space O(1)
517
+ * @param node - Node to insert.
518
+ * @returns Status string: 'CREATED' or 'UPDATED'.
519
+ */
520
+
521
+ protected _insert(node: RedBlackTreeNode<K, V>): CRUD {
522
+ let current = this.root ?? this.NIL;
523
+ let parent: RedBlackTreeNode<K, V> | undefined = undefined;
524
+
525
+ while (current !== this.NIL) {
526
+ parent = current;
527
+ const compared = this._compare(node.key, current.key);
528
+ if (compared < 0) {
529
+ current = current.left ?? this.NIL;
530
+ } else if (compared > 0) {
531
+ current = current.right ?? this.NIL;
532
+ } else {
533
+ this._replaceNode(current, node);
534
+ return 'UPDATED';
535
+ }
536
+ }
537
+
538
+ node.parent = parent;
539
+
540
+ if (!parent) {
541
+ this._setRoot(node);
542
+ } else if (this._compare(node.key, parent.key) < 0) {
543
+ parent.left = node;
544
+ } else {
545
+ parent.right = node;
546
+ }
547
+
548
+ node.left = this.NIL;
549
+ node.right = this.NIL;
550
+ node.color = 'RED';
551
+
552
+ this._insertFixup(node);
553
+ return 'CREATED';
554
+ }
555
+
556
+ /**
557
+ * (Protected) Transplant a subtree in place of another during deletion.
558
+ * @remarks Time O(1), Space O(1)
559
+ * @param u - Node to replace.
560
+ * @param v - Replacement subtree root (may be undefined).
561
+ * @returns void
562
+ */
563
+
564
+ protected _transplant(u: RedBlackTreeNode<K, V>, v: RedBlackTreeNode<K, V> | undefined): void {
565
+ if (!u.parent) {
566
+ this._setRoot(v);
567
+ } else if (u === u.parent.left) {
568
+ u.parent.left = v;
569
+ } else {
570
+ u.parent.right = v;
571
+ }
572
+
573
+ if (v) {
574
+ v.parent = u.parent;
575
+ }
576
+ }
577
+
578
+ /**
579
+ * (Protected) Restore red-black properties after insertion (recolor/rotate).
580
+ * @remarks Time O(log n), Space O(1)
581
+ * @param z - Recently inserted node.
582
+ * @returns void
583
+ */
584
+
585
+ protected _insertFixup(z: RedBlackTreeNode<K, V> | undefined): void {
586
+ while (z?.parent?.color === 'RED') {
587
+ if (z.parent === z.parent.parent?.left) {
588
+ const y = z.parent.parent.right;
589
+ if (y?.color === 'RED') {
590
+ z.parent.color = 'BLACK';
591
+ y.color = 'BLACK';
592
+ z.parent.parent.color = 'RED';
593
+
594
+ z = z.parent.parent;
595
+ } else {
596
+ if (z === z.parent.right) {
597
+ z = z.parent;
598
+ this._leftRotate(z);
599
+ }
600
+
601
+ if (z && z.parent && z.parent.parent) {
602
+ z.parent.color = 'BLACK';
603
+ z.parent.parent.color = 'RED';
604
+ this._rightRotate(z.parent.parent);
605
+ }
606
+ }
607
+ } else {
608
+ const y: RedBlackTreeNode<K, V> | undefined = z?.parent?.parent?.left ?? undefined;
609
+ if (y?.color === 'RED') {
610
+ z.parent.color = 'BLACK';
611
+ y.color = 'BLACK';
612
+ z.parent.parent!.color = 'RED';
613
+ z = z.parent.parent;
614
+ } else {
615
+ if (z === z.parent.left) {
616
+ z = z.parent;
617
+ this._rightRotate(z);
618
+ }
619
+
620
+ if (z && z.parent && z.parent.parent) {
621
+ z.parent.color = 'BLACK';
622
+ z.parent.parent.color = 'RED';
623
+ this._leftRotate(z.parent.parent);
624
+ }
625
+ }
626
+ }
627
+ }
628
+
629
+ if (this.isRealNode(this._root)) this._root.color = 'BLACK';
630
+ }
631
+
632
+ /**
633
+ * (Protected) Restore red-black properties after deletion (recolor/rotate).
634
+ * @remarks Time O(log n), Space O(1)
635
+ * @param node - Child that replaced the deleted node (may be undefined).
636
+ * @returns void
637
+ */
638
+
639
+ protected _deleteFixup(node: RedBlackTreeNode<K, V> | undefined): void {
640
+ if (!node || node === this.root || node.color === 'BLACK') {
641
+ if (node) {
642
+ node.color = 'BLACK';
643
+ }
644
+ return;
645
+ }
646
+
647
+ while (node && node !== this.root && node.color === 'BLACK') {
648
+ const parent: RedBlackTreeNode<K, V> | undefined = node.parent;
649
+
650
+ if (!parent) {
651
+ break;
652
+ }
653
+
654
+ if (node === parent.left) {
655
+ let sibling = parent.right;
656
+
657
+ if (sibling?.color === 'RED') {
658
+ sibling.color = 'BLACK';
659
+ parent.color = 'RED';
660
+ this._leftRotate(parent);
661
+ sibling = parent.right;
662
+ }
663
+
664
+ if ((sibling?.left?.color ?? 'BLACK') === 'BLACK') {
665
+ if (sibling) sibling.color = 'RED';
666
+ node = parent;
667
+ } else {
668
+ if (sibling?.left) sibling.left.color = 'BLACK';
669
+ if (sibling) sibling.color = parent.color;
670
+ parent.color = 'BLACK';
671
+ this._rightRotate(parent);
672
+ node = this.root;
673
+ }
674
+ } else {
675
+ let sibling = parent.left;
676
+
677
+ if (sibling?.color === 'RED') {
678
+ sibling.color = 'BLACK';
679
+ if (parent) parent.color = 'RED';
680
+ this._rightRotate(parent);
681
+ if (parent) sibling = parent.left;
682
+ }
683
+
684
+ if ((sibling?.right?.color ?? 'BLACK') === 'BLACK') {
685
+ if (sibling) sibling.color = 'RED';
686
+ node = parent;
687
+ } else {
688
+ if (sibling?.right) sibling.right.color = 'BLACK';
689
+ if (sibling) sibling.color = parent.color;
690
+ if (parent) parent.color = 'BLACK';
691
+ this._leftRotate(parent);
692
+ node = this.root;
693
+ }
694
+ }
695
+ }
696
+
697
+ if (node) {
698
+ node.color = 'BLACK';
699
+ }
700
+ }
701
+
702
+ /**
703
+ * (Protected) Perform a left rotation around x.
704
+ * @remarks Time O(1), Space O(1)
705
+ * @param x - Pivot node to rotate around.
706
+ * @returns void
707
+ */
708
+
709
+ protected _leftRotate(x: RedBlackTreeNode<K, V> | undefined): void {
710
+ if (!x || !x.right) {
711
+ return;
712
+ }
713
+
714
+ const y = x.right;
715
+ x.right = y.left;
716
+
717
+ if (y.left && y.left !== this.NIL) {
718
+ y.left.parent = x;
719
+ }
720
+
721
+ y.parent = x.parent;
722
+
723
+ if (!x.parent) {
724
+ this._setRoot(y);
725
+ } else if (x === x.parent.left) {
726
+ x.parent.left = y;
727
+ } else {
728
+ x.parent.right = y;
729
+ }
730
+
731
+ y.left = x;
732
+ x.parent = y;
733
+ }
734
+
735
+ /**
736
+ * (Protected) Perform a right rotation around y.
737
+ * @remarks Time O(1), Space O(1)
738
+ * @param y - Pivot node to rotate around.
739
+ * @returns void
740
+ */
741
+
742
+ protected _rightRotate(y: RedBlackTreeNode<K, V> | undefined): void {
743
+ if (!y || !y.left) {
744
+ return;
745
+ }
746
+
747
+ const x = y.left;
748
+ y.left = x.right;
749
+
750
+ if (x.right && x.right !== this.NIL) {
751
+ x.right.parent = y;
752
+ }
753
+
754
+ x.parent = y.parent;
755
+
756
+ if (!y.parent) {
757
+ this._setRoot(x);
758
+ } else if (y === y.parent.left) {
759
+ y.parent.left = x;
760
+ } else {
761
+ y.parent.right = x;
762
+ }
763
+
764
+ x.right = y;
765
+ y.parent = x;
766
+ }
767
+ }