data-structure-typed 0.9.16 → 1.3.1

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 (264) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +665 -172
  3. package/dist/bundle.js +2 -0
  4. package/dist/bundle.js.LICENSE.txt +13 -0
  5. package/dist/data-structures/binary-tree/aa-tree.js +2 -5
  6. package/dist/data-structures/binary-tree/abstract-binary-tree.d.ts +364 -0
  7. package/dist/data-structures/binary-tree/abstract-binary-tree.js +1308 -0
  8. package/dist/data-structures/binary-tree/avl-tree.d.ts +85 -14
  9. package/dist/data-structures/binary-tree/avl-tree.js +142 -116
  10. package/dist/data-structures/binary-tree/b-tree.js +2 -5
  11. package/dist/data-structures/binary-tree/binary-indexed-tree.d.ts +39 -1
  12. package/dist/data-structures/binary-tree/binary-indexed-tree.js +54 -13
  13. package/dist/data-structures/binary-tree/binary-tree.d.ts +29 -126
  14. package/dist/data-structures/binary-tree/binary-tree.js +31 -1093
  15. package/dist/data-structures/binary-tree/bst.d.ts +117 -23
  16. package/dist/data-structures/binary-tree/bst.js +233 -240
  17. package/dist/data-structures/binary-tree/index.d.ts +1 -0
  18. package/dist/data-structures/binary-tree/index.js +1 -0
  19. package/dist/data-structures/binary-tree/rb-tree.d.ts +18 -1
  20. package/dist/data-structures/binary-tree/rb-tree.js +40 -5
  21. package/dist/data-structures/binary-tree/segment-tree.d.ts +61 -11
  22. package/dist/data-structures/binary-tree/segment-tree.js +126 -93
  23. package/dist/data-structures/binary-tree/splay-tree.js +2 -5
  24. package/dist/data-structures/binary-tree/tree-multiset.d.ts +213 -6
  25. package/dist/data-structures/binary-tree/tree-multiset.js +687 -34
  26. package/dist/data-structures/binary-tree/two-three-tree.js +2 -5
  27. package/dist/data-structures/graph/abstract-graph.d.ts +270 -36
  28. package/dist/data-structures/graph/abstract-graph.js +610 -572
  29. package/dist/data-structures/graph/directed-graph.d.ts +173 -16
  30. package/dist/data-structures/graph/directed-graph.js +345 -313
  31. package/dist/data-structures/graph/index.d.ts +1 -0
  32. package/dist/data-structures/graph/index.js +1 -0
  33. package/dist/data-structures/graph/map-graph.d.ts +79 -0
  34. package/dist/data-structures/graph/map-graph.js +111 -0
  35. package/dist/data-structures/graph/undirected-graph.d.ts +111 -9
  36. package/dist/data-structures/graph/undirected-graph.js +203 -178
  37. package/dist/data-structures/hash/coordinate-map.d.ts +38 -1
  38. package/dist/data-structures/hash/coordinate-map.js +59 -36
  39. package/dist/data-structures/hash/coordinate-set.d.ts +32 -2
  40. package/dist/data-structures/hash/coordinate-set.js +49 -33
  41. package/dist/data-structures/hash/hash-table.d.ts +2 -1
  42. package/dist/data-structures/hash/hash-table.js +4 -0
  43. package/dist/data-structures/hash/pair.d.ts +2 -1
  44. package/dist/data-structures/hash/pair.js +4 -0
  45. package/dist/data-structures/hash/tree-map.d.ts +2 -1
  46. package/dist/data-structures/hash/tree-map.js +4 -0
  47. package/dist/data-structures/hash/tree-set.d.ts +2 -1
  48. package/dist/data-structures/hash/tree-set.js +4 -0
  49. package/dist/data-structures/heap/heap.d.ts +62 -45
  50. package/dist/data-structures/heap/heap.js +124 -86
  51. package/dist/data-structures/heap/max-heap.d.ts +13 -5
  52. package/dist/data-structures/heap/max-heap.js +18 -28
  53. package/dist/data-structures/heap/min-heap.d.ts +14 -5
  54. package/dist/data-structures/heap/min-heap.js +19 -28
  55. package/dist/data-structures/index.d.ts +1 -1
  56. package/dist/data-structures/index.js +1 -1
  57. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +193 -56
  58. package/dist/data-structures/linked-list/doubly-linked-list.js +484 -220
  59. package/dist/data-structures/linked-list/index.d.ts +1 -0
  60. package/dist/data-structures/linked-list/index.js +1 -0
  61. package/dist/data-structures/linked-list/singly-linked-list.d.ts +117 -315
  62. package/dist/data-structures/linked-list/singly-linked-list.js +374 -727
  63. package/dist/data-structures/linked-list/skip-linked-list.d.ts +2 -1
  64. package/dist/data-structures/linked-list/skip-linked-list.js +4 -0
  65. package/dist/data-structures/matrix/matrix.d.ts +12 -0
  66. package/dist/data-structures/matrix/matrix.js +21 -8
  67. package/dist/data-structures/matrix/matrix2d.d.ts +85 -2
  68. package/dist/data-structures/matrix/matrix2d.js +146 -80
  69. package/dist/data-structures/matrix/navigator.d.ts +36 -1
  70. package/dist/data-structures/matrix/navigator.js +46 -37
  71. package/dist/data-structures/matrix/vector2d.d.ts +142 -15
  72. package/dist/data-structures/matrix/vector2d.js +215 -109
  73. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -2
  74. package/dist/data-structures/priority-queue/max-priority-queue.js +33 -26
  75. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +12 -2
  76. package/dist/data-structures/priority-queue/min-priority-queue.js +34 -26
  77. package/dist/data-structures/priority-queue/priority-queue.d.ts +153 -3
  78. package/dist/data-structures/priority-queue/priority-queue.js +244 -143
  79. package/dist/data-structures/queue/deque.d.ts +141 -13
  80. package/dist/data-structures/queue/deque.js +200 -82
  81. package/dist/data-structures/queue/queue.d.ts +65 -38
  82. package/dist/data-structures/queue/queue.js +110 -66
  83. package/dist/data-structures/stack/stack.d.ts +27 -32
  84. package/dist/data-structures/stack/stack.js +47 -53
  85. package/dist/data-structures/tree/index.d.ts +1 -0
  86. package/dist/data-structures/tree/index.js +17 -0
  87. package/dist/data-structures/tree/tree.d.ts +14 -0
  88. package/dist/data-structures/tree/tree.js +60 -0
  89. package/dist/data-structures/trie/trie.d.ts +33 -10
  90. package/dist/data-structures/trie/trie.js +123 -208
  91. package/dist/index.d.ts +3 -0
  92. package/dist/index.js +3 -0
  93. package/dist/interfaces/abstract-binary-tree.d.ts +90 -0
  94. package/dist/interfaces/abstract-graph.d.ts +17 -0
  95. package/dist/interfaces/avl-tree.d.ts +9 -0
  96. package/dist/interfaces/binary-tree.d.ts +6 -0
  97. package/dist/interfaces/bst.d.ts +17 -0
  98. package/dist/interfaces/directed-graph.d.ts +12 -0
  99. package/{src/data-structures/types/index.ts → dist/interfaces/index.d.ts} +10 -8
  100. package/dist/interfaces/index.js +31 -0
  101. package/{src/data-structures/hash/hash-table.ts → dist/interfaces/priority-queue.d.ts} +1 -1
  102. package/dist/interfaces/rb-tree.d.ts +8 -0
  103. package/dist/interfaces/segment-tree.d.ts +1 -0
  104. package/dist/interfaces/singly-linked-list.d.ts +1 -0
  105. package/dist/interfaces/singly-linked-list.js +2 -0
  106. package/dist/interfaces/tree-multiset.d.ts +7 -0
  107. package/dist/interfaces/tree-multiset.js +2 -0
  108. package/dist/interfaces/undirected-graph.d.ts +5 -0
  109. package/dist/interfaces/undirected-graph.js +2 -0
  110. package/dist/types/data-structures/abstract-binary-tree.d.ts +34 -0
  111. package/dist/types/data-structures/abstract-binary-tree.js +25 -0
  112. package/dist/types/data-structures/abstract-graph.d.ts +11 -0
  113. package/dist/types/data-structures/abstract-graph.js +2 -0
  114. package/dist/types/data-structures/avl-tree.d.ts +4 -0
  115. package/dist/types/data-structures/avl-tree.js +2 -0
  116. package/dist/types/data-structures/binary-tree.d.ts +4 -0
  117. package/dist/types/data-structures/binary-tree.js +2 -0
  118. package/dist/types/data-structures/bst.d.ts +13 -0
  119. package/dist/types/data-structures/bst.js +9 -0
  120. package/dist/types/data-structures/directed-graph.d.ts +6 -0
  121. package/dist/types/data-structures/directed-graph.js +9 -0
  122. package/dist/types/data-structures/doubly-linked-list.d.ts +1 -0
  123. package/dist/types/data-structures/doubly-linked-list.js +2 -0
  124. package/dist/types/data-structures/heap.d.ts +3 -0
  125. package/dist/types/data-structures/heap.js +2 -0
  126. package/dist/{data-structures/types → types/data-structures}/index.d.ts +3 -1
  127. package/dist/{data-structures/types → types/data-structures}/index.js +3 -1
  128. package/dist/types/data-structures/map-graph.d.ts +1 -0
  129. package/dist/types/data-structures/map-graph.js +2 -0
  130. package/dist/{data-structures/types → types/data-structures}/navigator.d.ts +2 -2
  131. package/dist/types/data-structures/navigator.js +2 -0
  132. package/dist/{data-structures/types → types/data-structures}/priority-queue.d.ts +2 -2
  133. package/dist/types/data-structures/priority-queue.js +2 -0
  134. package/dist/types/data-structures/rb-tree.d.ts +8 -0
  135. package/dist/types/data-structures/rb-tree.js +8 -0
  136. package/dist/types/data-structures/segment-tree.js +2 -0
  137. package/dist/types/data-structures/singly-linked-list.d.ts +1 -0
  138. package/dist/types/data-structures/singly-linked-list.js +2 -0
  139. package/dist/types/data-structures/tree-multiset.d.ts +4 -0
  140. package/dist/types/data-structures/tree-multiset.js +2 -0
  141. package/dist/types/helpers.d.ts +1 -0
  142. package/dist/types/helpers.js +2 -0
  143. package/dist/types/index.d.ts +3 -0
  144. package/dist/types/index.js +19 -0
  145. package/dist/types/utils/index.d.ts +2 -0
  146. package/dist/types/utils/index.js +18 -0
  147. package/dist/types/utils/utils.d.ts +7 -0
  148. package/dist/types/utils/utils.js +2 -0
  149. package/dist/types/utils/validate-type.d.ts +19 -0
  150. package/dist/types/utils/validate-type.js +2 -0
  151. package/dist/utils/utils.d.ts +17 -103
  152. package/dist/utils/utils.js +40 -625
  153. package/package.json +134 -23
  154. package/.idea/data-structure-typed.iml +0 -12
  155. package/.idea/modules.xml +0 -8
  156. package/.idea/vcs.xml +0 -6
  157. package/dist/data-structures/trampoline.d.ts +0 -16
  158. package/dist/data-structures/trampoline.js +0 -130
  159. package/dist/data-structures/types/abstract-graph.d.ts +0 -29
  160. package/dist/data-structures/types/avl-tree.d.ts +0 -5
  161. package/dist/data-structures/types/binary-tree.d.ts +0 -16
  162. package/dist/data-structures/types/bst.d.ts +0 -7
  163. package/dist/data-structures/types/directed-graph.d.ts +0 -10
  164. package/dist/data-structures/types/doubly-linked-list.d.ts +0 -1
  165. package/dist/data-structures/types/heap.d.ts +0 -7
  166. package/dist/data-structures/types/singly-linked-list.d.ts +0 -5
  167. package/dist/data-structures/types/tree-multiset.d.ts +0 -5
  168. package/dist/data-structures/types/utils.d.ts +0 -52
  169. package/dist/data-structures/types/utils.js +0 -54
  170. package/src/data-structures/binary-tree/aa-tree.ts +0 -3
  171. package/src/data-structures/binary-tree/avl-tree.ts +0 -227
  172. package/src/data-structures/binary-tree/b-tree.ts +0 -3
  173. package/src/data-structures/binary-tree/binary-indexed-tree.ts +0 -33
  174. package/src/data-structures/binary-tree/binary-tree.ts +0 -1133
  175. package/src/data-structures/binary-tree/bst.ts +0 -395
  176. package/src/data-structures/binary-tree/diagrams/avl-tree-inserting.gif +0 -0
  177. package/src/data-structures/binary-tree/diagrams/bst-rotation.gif +0 -0
  178. package/src/data-structures/binary-tree/diagrams/segment-tree.png +0 -0
  179. package/src/data-structures/binary-tree/index.ts +0 -11
  180. package/src/data-structures/binary-tree/rb-tree.ts +0 -3
  181. package/src/data-structures/binary-tree/segment-tree.ts +0 -172
  182. package/src/data-structures/binary-tree/splay-tree.ts +0 -3
  183. package/src/data-structures/binary-tree/tree-multiset.ts +0 -18
  184. package/src/data-structures/binary-tree/two-three-tree.ts +0 -3
  185. package/src/data-structures/diagrams/README.md +0 -7
  186. package/src/data-structures/graph/abstract-graph.ts +0 -753
  187. package/src/data-structures/graph/diagrams/adjacency-list-pros-cons.png +0 -0
  188. package/src/data-structures/graph/diagrams/adjacency-list.png +0 -0
  189. package/src/data-structures/graph/diagrams/adjacency-matrix-pros-cons.png +0 -0
  190. package/src/data-structures/graph/diagrams/adjacency-matrix.png +0 -0
  191. package/src/data-structures/graph/diagrams/dfs-can-do.png +0 -0
  192. package/src/data-structures/graph/diagrams/edge-list-pros-cons.png +0 -0
  193. package/src/data-structures/graph/diagrams/edge-list.png +0 -0
  194. package/src/data-structures/graph/diagrams/max-flow.png +0 -0
  195. package/src/data-structures/graph/diagrams/mst.png +0 -0
  196. package/src/data-structures/graph/diagrams/tarjan-articulation-point-bridge.png +0 -0
  197. package/src/data-structures/graph/diagrams/tarjan-complicate-simple.png +0 -0
  198. package/src/data-structures/graph/diagrams/tarjan-strongly-connected-component.png +0 -0
  199. package/src/data-structures/graph/diagrams/tarjan.mp4 +0 -0
  200. package/src/data-structures/graph/directed-graph.ts +0 -306
  201. package/src/data-structures/graph/index.ts +0 -3
  202. package/src/data-structures/graph/undirected-graph.ts +0 -155
  203. package/src/data-structures/hash/coordinate-map.ts +0 -24
  204. package/src/data-structures/hash/coordinate-set.ts +0 -20
  205. package/src/data-structures/hash/index.ts +0 -6
  206. package/src/data-structures/heap/heap.ts +0 -127
  207. package/src/data-structures/heap/index.ts +0 -3
  208. package/src/data-structures/heap/max-heap.ts +0 -23
  209. package/src/data-structures/heap/min-heap.ts +0 -25
  210. package/src/data-structures/index.ts +0 -12
  211. package/src/data-structures/linked-list/doubly-linked-list.ts +0 -250
  212. package/src/data-structures/linked-list/index.ts +0 -2
  213. package/src/data-structures/linked-list/singly-linked-list.ts +0 -736
  214. package/src/data-structures/linked-list/skip-linked-list.ts +0 -1
  215. package/src/data-structures/matrix/index.ts +0 -4
  216. package/src/data-structures/matrix/matrix.ts +0 -13
  217. package/src/data-structures/matrix/matrix2d.ts +0 -125
  218. package/src/data-structures/matrix/navigator.ts +0 -87
  219. package/src/data-structures/matrix/vector2d.ts +0 -189
  220. package/src/data-structures/priority-queue/index.ts +0 -3
  221. package/src/data-structures/priority-queue/max-priority-queue.ts +0 -13
  222. package/src/data-structures/priority-queue/min-priority-queue.ts +0 -13
  223. package/src/data-structures/priority-queue/priority-queue.ts +0 -200
  224. package/src/data-structures/queue/deque.ts +0 -139
  225. package/src/data-structures/queue/index.ts +0 -2
  226. package/src/data-structures/queue/queue.ts +0 -122
  227. package/src/data-structures/stack/index.ts +0 -1
  228. package/src/data-structures/stack/stack.ts +0 -103
  229. package/src/data-structures/trampoline.ts +0 -51
  230. package/src/data-structures/trie/index.ts +0 -1
  231. package/src/data-structures/trie/trie.ts +0 -203
  232. package/src/data-structures/types/abstract-graph.ts +0 -51
  233. package/src/data-structures/types/avl-tree.ts +0 -6
  234. package/src/data-structures/types/binary-tree.ts +0 -15
  235. package/src/data-structures/types/bst.ts +0 -5
  236. package/src/data-structures/types/directed-graph.ts +0 -18
  237. package/src/data-structures/types/doubly-linked-list.ts +0 -1
  238. package/src/data-structures/types/heap.ts +0 -8
  239. package/src/data-structures/types/navigator.ts +0 -12
  240. package/src/data-structures/types/priority-queue.ts +0 -9
  241. package/src/data-structures/types/segment-tree.ts +0 -1
  242. package/src/data-structures/types/singly-linked-list.ts +0 -15
  243. package/src/data-structures/types/tree-multiset.ts +0 -3
  244. package/src/data-structures/types/utils.ts +0 -173
  245. package/src/index.ts +0 -1
  246. package/src/utils/index.ts +0 -1
  247. package/src/utils/utils.ts +0 -505
  248. package/tsconfig.json +0 -56
  249. /package/dist/{data-structures/types/abstract-graph.js → interfaces/abstract-binary-tree.js} +0 -0
  250. /package/dist/{data-structures/types/avl-tree.js → interfaces/abstract-graph.js} +0 -0
  251. /package/dist/{data-structures/types/binary-tree.js → interfaces/avl-tree.js} +0 -0
  252. /package/dist/{data-structures/types/bst.js → interfaces/binary-tree.js} +0 -0
  253. /package/dist/{data-structures/types/directed-graph.js → interfaces/bst.js} +0 -0
  254. /package/dist/{data-structures/types/doubly-linked-list.js → interfaces/directed-graph.js} +0 -0
  255. /package/{src/data-structures/hash/pair.ts → dist/interfaces/doubly-linked-list.d.ts} +0 -0
  256. /package/dist/{data-structures/types/heap.js → interfaces/doubly-linked-list.js} +0 -0
  257. /package/{src/data-structures/hash/tree-map.ts → dist/interfaces/heap.d.ts} +0 -0
  258. /package/dist/{data-structures/types/navigator.js → interfaces/heap.js} +0 -0
  259. /package/{src/data-structures/hash/tree-set.ts → dist/interfaces/navigator.d.ts} +0 -0
  260. /package/dist/{data-structures/types/priority-queue.js → interfaces/navigator.js} +0 -0
  261. /package/dist/{data-structures/types/segment-tree.js → interfaces/priority-queue.js} +0 -0
  262. /package/dist/{data-structures/types/singly-linked-list.js → interfaces/rb-tree.js} +0 -0
  263. /package/dist/{data-structures/types/tree-multiset.js → interfaces/segment-tree.js} +0 -0
  264. /package/dist/{data-structures/types → types/data-structures}/segment-tree.d.ts +0 -0
@@ -1,1133 +0,0 @@
1
- import {trampoline} from '../trampoline';
2
- import type {
3
- BinaryTreeDeleted,
4
- BinaryTreeNodeId,
5
- BinaryTreeNodePropertyName, DFSOrderPattern,
6
- NodeOrPropertyName, ResultByProperty,
7
- ResultsByProperty
8
- } from '../types';
9
-
10
- export enum FamilyPosition {root, left, right}
11
-
12
- export enum LoopType { iterative = 1, recursive = 2}
13
-
14
- export class BinaryTreeNode<T> {
15
- constructor(id: BinaryTreeNodeId, val: T, count?: number) {
16
- this._id = id;
17
- this._val = val;
18
- this._count = count ?? 1;
19
- }
20
-
21
- protected _id: BinaryTreeNodeId;
22
-
23
- get id(): BinaryTreeNodeId {
24
- return this._id;
25
- }
26
-
27
- set id(v: BinaryTreeNodeId) {
28
- this._id = v;
29
- }
30
-
31
- protected _val: T;
32
-
33
- get val(): T {
34
- return this._val;
35
- }
36
-
37
- set val(v: T) {
38
- this._val = v;
39
- }
40
-
41
- protected _left?: BinaryTreeNode<T> | null;
42
-
43
- get left(): BinaryTreeNode<T> | null | undefined {
44
- return this._left;
45
- }
46
-
47
- set left(v: BinaryTreeNode<T> | null | undefined) {
48
- if (v) {
49
- v.parent = this;
50
- v.familyPosition = FamilyPosition.left;
51
- }
52
- this._left = v;
53
- }
54
-
55
- protected _right?: BinaryTreeNode<T> | null;
56
-
57
- get right(): BinaryTreeNode<T> | null | undefined {
58
- return this._right;
59
- }
60
-
61
- set right(v: BinaryTreeNode<T> | null | undefined) {
62
- if (v) {
63
- v.parent = this;
64
- v.familyPosition = FamilyPosition.right;
65
- }
66
- this._right = v;
67
- }
68
-
69
- protected _parent: BinaryTreeNode<T> | null | undefined;
70
-
71
- get parent(): BinaryTreeNode<T> | null | undefined {
72
- return this._parent;
73
- }
74
-
75
- set parent(v: BinaryTreeNode<T> | null | undefined) {
76
- this._parent = v;
77
- }
78
-
79
- protected _familyPosition: FamilyPosition = FamilyPosition.root;
80
-
81
- get familyPosition(): FamilyPosition {
82
- return this._familyPosition;
83
- }
84
-
85
- set familyPosition(v: FamilyPosition) {
86
- this._familyPosition = v;
87
- }
88
-
89
- protected _count = 1;
90
-
91
- get count(): number {
92
- return this._count;
93
- }
94
-
95
- set count(v: number) {
96
- this._count = v;
97
- }
98
-
99
- protected _height = 0;
100
-
101
- get height(): number {
102
- return this._height;
103
- }
104
-
105
- set height(v: number) {
106
- this._height = v;
107
- }
108
-
109
- swapLocation(swapNode: BinaryTreeNode<T>): BinaryTreeNode<T> {
110
- const {val, count, height} = swapNode;
111
- const tempNode = new BinaryTreeNode<T>(swapNode.id, val);
112
- tempNode.val = val;
113
- tempNode.count = count;
114
- tempNode.height = height;
115
-
116
- swapNode.id = this.id;
117
- swapNode.val = this.val;
118
- swapNode.count = this.count;
119
- swapNode.height = this.height;
120
-
121
- this.id = tempNode.id;
122
- this.val = tempNode.val;
123
- this.count = tempNode.count;
124
- this.height = tempNode.height;
125
- return swapNode;
126
- }
127
-
128
- clone(): BinaryTreeNode<T> {
129
- return new BinaryTreeNode<T>(this.id, this.val, this.count);
130
- }
131
- }
132
-
133
- export class BinaryTree<T> {
134
- protected _loopType: LoopType = LoopType.iterative;
135
- protected _visitedId: BinaryTreeNodeId[] = [];
136
- protected _visitedVal: Array<T> = [];
137
- protected _visitedNode: BinaryTreeNode<T>[] = [];
138
- protected _visitedCount: number[] = [];
139
- protected _visitedLeftSum: number[] = [];
140
- private readonly _autoIncrementId: boolean = false;
141
- private _maxId: number = -1;
142
- private readonly _isDuplicatedVal: boolean = false;
143
-
144
- constructor(options?: {
145
- loopType?: LoopType,
146
- autoIncrementId?: boolean,
147
- isDuplicatedVal?: boolean
148
- }) {
149
- if (options !== undefined) {
150
- const {
151
- loopType = LoopType.iterative,
152
- autoIncrementId = false,
153
- isDuplicatedVal = false
154
- } = options;
155
- this._isDuplicatedVal = isDuplicatedVal;
156
- this._autoIncrementId = autoIncrementId;
157
- this._loopType = loopType;
158
- }
159
- }
160
-
161
- protected _root: BinaryTreeNode<T> | null = null;
162
-
163
- protected get root(): BinaryTreeNode<T> | null {
164
- return this._root;
165
- }
166
-
167
- protected set root(v: BinaryTreeNode<T> | null) {
168
- if (v) {
169
- v.parent = null;
170
- v.familyPosition = FamilyPosition.root;
171
- }
172
- this._root = v;
173
- }
174
-
175
- protected _size = 0;
176
-
177
- protected get size(): number {
178
- return this._size;
179
- }
180
-
181
- protected set size(v: number) {
182
- this._size = v;
183
- }
184
-
185
- protected _count = 0;
186
-
187
- protected get count(): number {
188
- return this._count;
189
- }
190
-
191
- protected set count(v: number) {
192
- this._count = v;
193
- }
194
-
195
- getCount(): number {
196
- return this._count;
197
- }
198
-
199
- createNode(id: BinaryTreeNodeId, val: T | null, count?: number): BinaryTreeNode<T> | null {
200
- return val !== null ? new BinaryTreeNode(id, val, count) : null;
201
- }
202
-
203
- clear() {
204
- this.root = null;
205
- this.size = 0;
206
- this.count = 0;
207
- this._maxId = -1;
208
- }
209
-
210
- isEmpty(): boolean {
211
- return this.size === 0;
212
- }
213
-
214
- insertTo({newNode, parent}: { newNode: BinaryTreeNode<T> | null, parent: BinaryTreeNode<T> }) {
215
- if (parent) {
216
- if (parent.left === undefined) {
217
- if (newNode) {
218
- newNode.parent = parent;
219
- newNode.familyPosition = FamilyPosition.left;
220
- }
221
- parent.left = newNode;
222
- if (newNode !== null) {
223
- this.size++;
224
- this.count += newNode?.count ?? 0;
225
- }
226
-
227
- return parent.left;
228
- } else if (parent.right === undefined) {
229
- if (newNode) {
230
- newNode.parent = parent;
231
- newNode.familyPosition = FamilyPosition.right;
232
- }
233
- parent.right = newNode;
234
- if (newNode !== null) {
235
- this.size++;
236
- this.count += newNode?.count ?? 0;
237
- }
238
- return parent.right;
239
- } else {
240
- return;
241
- }
242
- } else {
243
- return;
244
- }
245
- }
246
-
247
- put(id: BinaryTreeNodeId, val: T, count?: number): BinaryTreeNode<T> | null | undefined {
248
- count = count ?? 1;
249
-
250
- const _bfs = (root: BinaryTreeNode<T>, newNode: BinaryTreeNode<T> | null): BinaryTreeNode<T> | undefined | null => {
251
- const queue: Array<BinaryTreeNode<T> | null> = [root];
252
- while (queue.length > 0) {
253
- const cur = queue.shift();
254
- if (cur) {
255
- const inserted = this.insertTo({newNode, parent: cur});
256
- if (inserted !== undefined) return inserted;
257
- if (cur.left) queue.push(cur.left);
258
- if (cur.right) queue.push(cur.right);
259
- } else return;
260
- }
261
- return;
262
- };
263
-
264
- let inserted: BinaryTreeNode<T> | null | undefined;
265
- const needInsert = val !== null ? new BinaryTreeNode<T>(id, val, count) : null;
266
- const existNode = val !== null ? this.get(id, 'id') : null;
267
- if (this.root) {
268
- if (existNode) {
269
- existNode.count += count;
270
- existNode.val = val;
271
- if (needInsert !== null) {
272
- this.count += count;
273
- inserted = existNode;
274
- }
275
- } else {
276
- inserted = _bfs(this.root, needInsert);
277
- }
278
- } else {
279
- this.root = val !== null ? new BinaryTreeNode<T>(id, val, count) : null;
280
- if (needInsert !== null) {
281
- this.size = 1;
282
- this.count = count;
283
- }
284
- inserted = this.root;
285
- }
286
- return inserted;
287
- }
288
-
289
- insertMany(data: T[] | BinaryTreeNode<T>[]): (BinaryTreeNode<T> | null | undefined)[] {
290
- const inserted: (BinaryTreeNode<T> | null | undefined)[] = [];
291
- const map: Map<T | BinaryTreeNode<T>, number> = new Map();
292
-
293
- if (!this._isDuplicatedVal) {
294
- for (const i of data) map.set(i, (map.get(i) ?? 0) + 1);
295
- }
296
-
297
- for (const item of data) {
298
- const count = this._isDuplicatedVal ? 1 : map.get(item);
299
-
300
- if (item instanceof BinaryTreeNode) {
301
- inserted.push(this.put(item.id, item.val, item.count));
302
- } else if (typeof item === 'number' && !this._autoIncrementId) {
303
- if (!this._isDuplicatedVal) {
304
- if (map.get(item) !== undefined) {
305
- inserted.push(this.put(item, item, count));
306
- map.delete(item);
307
- }
308
- } else {
309
- inserted.push(this.put(item, item, 1));
310
- }
311
- } else {
312
- if (item !== null) {
313
- if (!this._isDuplicatedVal) {
314
- if (map.get(item) !== undefined) {
315
- inserted.push(this.put(++this._maxId, item, count));
316
- map.delete(item);
317
- }
318
- } else {
319
- inserted.push(this.put(++this._maxId, item, 1));
320
- }
321
- } else {
322
- inserted.push(this.put(Number.MAX_SAFE_INTEGER, item, 0));
323
- }
324
- }
325
- }
326
- return inserted;
327
- }
328
-
329
- fill(data: T[] | BinaryTreeNode<T>[]): boolean {
330
- this.clear();
331
- return data.length === this.insertMany(data).length;
332
- }
333
-
334
- remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeleted<T>[] {
335
- const nodes = this.getNodes(id, 'id', true);
336
- let node: BinaryTreeNode<T> | null | undefined = nodes[0];
337
-
338
- if (!node) node = undefined;
339
- else if (node.count > 1 && !ignoreCount) {
340
- node.count--;
341
- this.count--;
342
- } else if (node instanceof BinaryTreeNode) {
343
- const [subSize, subCount] = this.getSubTreeSizeAndCount(node);
344
-
345
- switch (node.familyPosition) {
346
- case 0:
347
- this.size -= subSize;
348
- this.count -= subCount;
349
- node = undefined;
350
- break;
351
- case 1:
352
- if (node.parent) {
353
- this.size -= subSize;
354
- this.count -= subCount;
355
- node.parent.left = null;
356
- }
357
- break;
358
- case 2:
359
- if (node.parent) {
360
- this.size -= subSize;
361
- this.count -= subCount;
362
- node.parent.right = null;
363
- }
364
- break;
365
- }
366
- }
367
- return [{deleted: node, needBalanced: null}];
368
- }
369
-
370
- getDepth(node: BinaryTreeNode<T>): number {
371
- let depth = 0;
372
- while (node.parent) {
373
- depth++;
374
- node = node.parent;
375
- }
376
- return depth;
377
- }
378
-
379
- getHeight(beginRoot?: BinaryTreeNode<T> | null): number {
380
- beginRoot = beginRoot ?? this.root;
381
- if (!beginRoot) return -1;
382
-
383
- if (this._loopType === LoopType.recursive) {
384
- const _getMaxHeight = (cur: BinaryTreeNode<T> | null | undefined): number => {
385
- if (!cur) return -1;
386
- const leftHeight = _getMaxHeight(cur.left);
387
- const rightHeight = _getMaxHeight(cur.right);
388
- return Math.max(leftHeight, rightHeight) + 1;
389
- };
390
-
391
- return _getMaxHeight(beginRoot);
392
- } else {
393
- const stack: BinaryTreeNode<T>[] = [];
394
- let node: BinaryTreeNode<T> | null | undefined = beginRoot, last: BinaryTreeNode<T> | null = null;
395
- const depths: Map<BinaryTreeNode<T>, number> = new Map();
396
-
397
- while (stack.length > 0 || node) {
398
- if (node) {
399
- stack.push(node);
400
- node = node.left;
401
- } else {
402
- node = stack[stack.length - 1]
403
- if (!node.right || last === node.right) {
404
- node = stack.pop();
405
- if (node) {
406
- const leftHeight = node.left ? depths.get(node.left) ?? -1 : -1;
407
- const rightHeight = node.right ? depths.get(node.right) ?? -1 : -1;
408
- depths.set(node, 1 + Math.max(leftHeight, rightHeight));
409
- last = node;
410
- node = null;
411
- }
412
- } else node = node.right
413
- }
414
- }
415
-
416
- return depths.get(beginRoot) ?? -1;
417
- }
418
- }
419
-
420
- getMinHeight(beginRoot?: BinaryTreeNode<T> | null): number {
421
- beginRoot = beginRoot || this.root;
422
- if (!beginRoot) return -1;
423
-
424
- if (this._loopType === LoopType.recursive) {
425
- const _getMinHeight = (cur: BinaryTreeNode<T> | null | undefined): number => {
426
- if (!cur) return 0;
427
- if (!cur.left && !cur.right) return 0;
428
- const leftMinHeight = _getMinHeight(cur.left);
429
- const rightMinHeight = _getMinHeight(cur.right);
430
- return Math.min(leftMinHeight, rightMinHeight) + 1;
431
- };
432
-
433
- return _getMinHeight(beginRoot);
434
- } else {
435
- const stack: BinaryTreeNode<T>[] = [];
436
- let node: BinaryTreeNode<T> | null | undefined = beginRoot, last: BinaryTreeNode<T> | null = null;
437
- const depths: Map<BinaryTreeNode<T>, number> = new Map();
438
-
439
- while (stack.length > 0 || node) {
440
- if (node) {
441
- stack.push(node);
442
- node = node.left;
443
- } else {
444
- node = stack[stack.length - 1]
445
- if (!node.right || last === node.right) {
446
- node = stack.pop();
447
- if (node) {
448
- const leftMinHeight = node.left ? depths.get(node.left) ?? -1 : -1;
449
- const rightMinHeight = node.right ? depths.get(node.right) ?? -1 : -1;
450
- depths.set(node, 1 + Math.min(leftMinHeight, rightMinHeight));
451
- last = node;
452
- node = null;
453
- }
454
- } else node = node.right
455
- }
456
- }
457
-
458
- return depths.get(beginRoot) ?? -1;
459
- }
460
- }
461
-
462
- isBalanced(beginRoot?: BinaryTreeNode<T> | null): boolean {
463
- return (this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot));
464
- }
465
-
466
- getNodes(nodeProperty: BinaryTreeNodeId | T, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean) {
467
- if (!this.root) return [] as null[];
468
- propertyName = propertyName ?? 'id';
469
-
470
- const result: (BinaryTreeNode<T> | null | undefined)[] = [];
471
-
472
- if (this._loopType === LoopType.recursive) {
473
- const _traverse = (cur: BinaryTreeNode<T>) => {
474
- if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return;
475
- if (!cur.left && !cur.right) return;
476
- cur.left && _traverse(cur.left);
477
- cur.right && _traverse(cur.right);
478
- }
479
-
480
- _traverse(this.root);
481
- } else {
482
- const queue: BinaryTreeNode<T>[] = [this.root];
483
- while (queue.length > 0) {
484
- const cur = queue.shift();
485
- if (cur) {
486
- if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return result;
487
- cur.left && queue.push(cur.left);
488
- cur.right && queue.push(cur.right);
489
- }
490
- }
491
- }
492
-
493
- return result;
494
- }
495
-
496
- has(nodeProperty: BinaryTreeNodeId | T, propertyName ?: BinaryTreeNodePropertyName): boolean {
497
- return this.getNodes(nodeProperty, propertyName).length > 0;
498
- }
499
-
500
- get(nodeProperty: BinaryTreeNodeId | T, propertyName ?: BinaryTreeNodePropertyName): BinaryTreeNode<T> | null {
501
- propertyName = propertyName ?? 'id';
502
- return this.getNodes(nodeProperty, propertyName, true)[0] ?? null;
503
- }
504
-
505
- getPathToRoot(node: BinaryTreeNode<T>): BinaryTreeNode<T>[] {
506
- const result: BinaryTreeNode<T>[] = [];
507
- while (node.parent) {
508
- result.unshift(node);
509
- node = node.parent;
510
- }
511
- result.unshift(node);
512
- return result;
513
- }
514
-
515
- getRoot(): BinaryTreeNode<T> | null {
516
- return this.root;
517
- }
518
-
519
- getLeftMost(): BinaryTreeNode<T> | null;
520
-
521
- getLeftMost(node: BinaryTreeNode<T>): BinaryTreeNode<T>;
522
-
523
- getLeftMost(node?: BinaryTreeNode<T> | null): BinaryTreeNode<T> | null {
524
- node = node ?? this.root;
525
- if (!node) return node;
526
-
527
- if (this._loopType === LoopType.recursive) {
528
-
529
- const _traverse = (cur: BinaryTreeNode<T>): BinaryTreeNode<T> => {
530
- if (!cur.left) return cur;
531
- return _traverse(cur.left);
532
- }
533
-
534
- return _traverse(node);
535
- } else {
536
- // Indirect implementation of iteration using tail recursion optimization
537
- const _traverse = trampoline((cur: BinaryTreeNode<T>) => {
538
- if (!cur.left) return cur;
539
- return _traverse.cont(cur.left);
540
- });
541
-
542
- return _traverse(node);
543
- }
544
- }
545
-
546
- getRightMost(): BinaryTreeNode<T> | null;
547
-
548
- getRightMost(node: BinaryTreeNode<T>): BinaryTreeNode<T>;
549
-
550
- getRightMost(node?: BinaryTreeNode<T> | null): BinaryTreeNode<T> | null {
551
- node = node ?? this.root;
552
- if (!node) return node;
553
-
554
- if (this._loopType === LoopType.recursive) {
555
- const _traverse = (cur: BinaryTreeNode<T>): BinaryTreeNode<T> => {
556
- if (!cur.right) return cur;
557
- return _traverse(cur.right);
558
- }
559
-
560
- return _traverse(node);
561
- } else {
562
- // Indirect implementation of iteration using tail recursion optimization
563
- const _traverse = trampoline((cur: BinaryTreeNode<T>) => {
564
- if (!cur.right) return cur;
565
- return _traverse.cont(cur.right);
566
- });
567
-
568
- return _traverse(node);
569
- }
570
- }
571
-
572
- // --- start additional methods ---
573
- isBST(node?: BinaryTreeNode<T> | null): boolean {
574
- node = node ?? this.root;
575
- if (!node) return true;
576
-
577
- if (this._loopType === LoopType.recursive) {
578
- const dfs = (cur: BinaryTreeNode<T> | null | undefined, min: BinaryTreeNodeId, max: BinaryTreeNodeId): boolean => {
579
- if (!cur) return true;
580
- if (cur.id <= min || cur.id >= max) return false;
581
- return dfs(cur.left, min, cur.id) && dfs(cur.right, cur.id, max);
582
- }
583
-
584
- return dfs(node, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
585
- } else {
586
- const stack = [];
587
- let prev = Number.MIN_SAFE_INTEGER, curr: BinaryTreeNode<T> | null | undefined = node;
588
- while (curr || stack.length > 0) {
589
- while (curr) {
590
- stack.push(curr);
591
- curr = curr.left;
592
- }
593
- curr = stack.pop()!;
594
- if (!(curr) || prev >= curr.id) return false;
595
- prev = curr.id;
596
- curr = curr.right;
597
- }
598
- return true;
599
- }
600
- }
601
-
602
- getSubTreeSizeAndCount(subTreeRoot: BinaryTreeNode<T> | null | undefined) {
603
- const res: [number, number] = [0, 0];
604
- if (!subTreeRoot) return res;
605
-
606
- if (this._loopType === LoopType.recursive) {
607
- const _traverse = (cur: BinaryTreeNode<T>) => {
608
- res[0]++;
609
- res[1] += cur.count;
610
- cur.left && _traverse(cur.left);
611
- cur.right && _traverse(cur.right);
612
- }
613
-
614
- _traverse(subTreeRoot);
615
- return res;
616
- } else {
617
- const stack: BinaryTreeNode<T>[] = [subTreeRoot];
618
-
619
- while (stack.length > 0) {
620
- const cur = stack.pop()!;
621
- res[0]++;
622
- res[1] += cur.count;
623
- cur.right && stack.push(cur.right);
624
- cur.left && stack.push(cur.left);
625
- }
626
-
627
- return res;
628
- }
629
- }
630
-
631
- subTreeSum(subTreeRoot: BinaryTreeNode<T>, propertyName ?: BinaryTreeNodePropertyName): number {
632
- propertyName = propertyName ?? 'val';
633
- if (!subTreeRoot) return 0;
634
-
635
- let sum = 0;
636
-
637
- const _sumByProperty = (cur: BinaryTreeNode<T>) => {
638
- let needSum: number;
639
- switch (propertyName) {
640
- case 'id':
641
- needSum = cur.id;
642
- break;
643
- case 'count':
644
- needSum = cur.count;
645
- break;
646
- case 'val':
647
- needSum = typeof cur.val === 'number' ? cur.val : 0;
648
- break;
649
- default:
650
- needSum = cur.id;
651
- break;
652
- }
653
- return needSum;
654
- }
655
-
656
- if (this._loopType === LoopType.recursive) {
657
- const _traverse = (cur: BinaryTreeNode<T>): void => {
658
- sum += _sumByProperty(cur);
659
- cur.left && _traverse(cur.left);
660
- cur.right && _traverse(cur.right);
661
- }
662
-
663
- _traverse(subTreeRoot);
664
- } else {
665
- const stack: BinaryTreeNode<T>[] = [subTreeRoot];
666
-
667
- while (stack.length > 0) {
668
- const cur = stack.pop()!;
669
- sum += _sumByProperty(cur);
670
- cur.right && stack.push(cur.right);
671
- cur.left && stack.push(cur.left);
672
- }
673
- }
674
-
675
- return sum;
676
- }
677
-
678
- subTreeAdd(subTreeRoot: BinaryTreeNode<T>, delta: number, propertyName ?: BinaryTreeNodePropertyName): boolean {
679
- propertyName = propertyName ?? 'id';
680
- if (!subTreeRoot) return false;
681
-
682
- const _addByProperty = (cur: BinaryTreeNode<T>) => {
683
- switch (propertyName) {
684
- case 'id':
685
- cur.id += delta;
686
- break;
687
- case 'count':
688
- cur.count += delta;
689
- this.count += delta;
690
- break;
691
- default:
692
- cur.id += delta;
693
- break;
694
- }
695
- }
696
-
697
- if (this._loopType === LoopType.recursive) {
698
- const _traverse = (cur: BinaryTreeNode<T>) => {
699
- _addByProperty(cur);
700
- cur.left && _traverse(cur.left);
701
- cur.right && _traverse(cur.right);
702
- };
703
-
704
- _traverse(subTreeRoot);
705
- } else {
706
- const stack: BinaryTreeNode<T>[] = [subTreeRoot];
707
-
708
- while (stack.length > 0) {
709
- const cur = stack.pop()!;
710
-
711
- _addByProperty(cur);
712
- cur.right && stack.push(cur.right);
713
- cur.left && stack.push(cur.left);
714
- }
715
- }
716
- return true;
717
- }
718
-
719
- BFS(): BinaryTreeNodeId[];
720
-
721
- BFS(nodeOrPropertyName: 'id'): BinaryTreeNodeId[];
722
-
723
- BFS(nodeOrPropertyName: 'val'): T[];
724
-
725
- BFS(nodeOrPropertyName: 'node'): BinaryTreeNode<T>[];
726
-
727
- BFS(nodeOrPropertyName: 'count'): number[];
728
-
729
- BFS(nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<T> {
730
- nodeOrPropertyName = nodeOrPropertyName ?? 'id';
731
- this._resetResults();
732
- const queue: Array<BinaryTreeNode<T> | null | undefined> = [this.root];
733
-
734
- while (queue.length !== 0) {
735
- const cur = queue.shift();
736
- if (cur) {
737
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
738
- if (cur?.left !== null) queue.push(cur.left);
739
- if (cur?.right !== null) queue.push(cur.right);
740
- }
741
- }
742
-
743
- return this._getResultByPropertyName(nodeOrPropertyName);
744
- }
745
-
746
- DFS(): BinaryTreeNodeId[];
747
-
748
- DFS(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[];
749
-
750
- DFS(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'val'): T[];
751
-
752
- DFS(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'node'): BinaryTreeNode<T>[];
753
-
754
- DFS(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'count'): number[];
755
-
756
- DFS(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<T> {
757
- pattern = pattern ?? 'in';
758
- nodeOrPropertyName = nodeOrPropertyName ?? 'id';
759
- this._resetResults();
760
- const _traverse = (node: BinaryTreeNode<T>) => {
761
- switch (pattern) {
762
- case 'in':
763
- if (node.left) _traverse(node.left);
764
- this._accumulatedByPropertyName(node, nodeOrPropertyName);
765
- if (node.right) _traverse(node.right);
766
- break;
767
- case 'pre':
768
- this._accumulatedByPropertyName(node, nodeOrPropertyName);
769
- if (node.left) _traverse(node.left);
770
- if (node.right) _traverse(node.right);
771
- break;
772
- case 'post':
773
- if (node.left) _traverse(node.left);
774
- if (node.right) _traverse(node.right);
775
- this._accumulatedByPropertyName(node, nodeOrPropertyName);
776
- break;
777
- }
778
- };
779
-
780
- this.root && _traverse(this.root);
781
- return this._getResultByPropertyName(nodeOrPropertyName);
782
- }
783
-
784
- DFSIterative(): BinaryTreeNodeId[];
785
-
786
- DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[];
787
-
788
- DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'val'): T[];
789
-
790
- DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'node'): BinaryTreeNode<T>[];
791
-
792
- DFSIterative(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'count'): number[];
793
-
794
- /**
795
- * Time complexity is O(n)
796
- * Space complexity of Iterative DFS equals to recursive DFS which is O(n) because of the stack
797
- * @param pattern
798
- * @param nodeOrPropertyName
799
- * @constructor
800
- */
801
- DFSIterative(pattern ?: 'in' | 'pre' | 'post', nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<T> {
802
- pattern = pattern || 'in';
803
- nodeOrPropertyName = nodeOrPropertyName || 'id';
804
- this._resetResults();
805
- if (!this.root) return this._getResultByPropertyName(nodeOrPropertyName);
806
- // 0: visit, 1: print
807
- const stack: { opt: 0 | 1, node: BinaryTreeNode<T> | null | undefined }[] = [{opt: 0, node: this.root}];
808
-
809
- while (stack.length > 0) {
810
- const cur = stack.pop();
811
- if (!cur || !cur.node) continue;
812
- if (cur.opt === 1) {
813
- this._accumulatedByPropertyName(cur.node, nodeOrPropertyName);
814
- } else {
815
- switch (pattern) {
816
- case 'in':
817
- stack.push({opt: 0, node: cur.node.right});
818
- stack.push({opt: 1, node: cur.node});
819
- stack.push({opt: 0, node: cur.node.left});
820
- break;
821
- case 'pre':
822
- stack.push({opt: 0, node: cur.node.right});
823
- stack.push({opt: 0, node: cur.node.left});
824
- stack.push({opt: 1, node: cur.node});
825
- break;
826
- case 'post':
827
- stack.push({opt: 1, node: cur.node});
828
- stack.push({opt: 0, node: cur.node.right});
829
- stack.push({opt: 0, node: cur.node.left});
830
- break;
831
- default:
832
- stack.push({opt: 0, node: cur.node.right});
833
- stack.push({opt: 1, node: cur.node});
834
- stack.push({opt: 0, node: cur.node.left});
835
- break;
836
- }
837
- }
838
- }
839
-
840
- return this._getResultByPropertyName(nodeOrPropertyName);
841
- }
842
-
843
- levelIterative(node: BinaryTreeNode<T> | null): BinaryTreeNodeId[];
844
-
845
- levelIterative(node: BinaryTreeNode<T> | null, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[];
846
-
847
- levelIterative(node: BinaryTreeNode<T> | null, nodeOrPropertyName?: 'val'): T[];
848
-
849
- levelIterative(node: BinaryTreeNode<T> | null, nodeOrPropertyName?: 'node'): BinaryTreeNode<T>[];
850
-
851
- levelIterative(node: BinaryTreeNode<T> | null, nodeOrPropertyName?: 'count'): number[];
852
-
853
- levelIterative(node: BinaryTreeNode<T> | null, nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<T> {
854
- nodeOrPropertyName = nodeOrPropertyName || 'id';
855
- node = node || this.root;
856
- if (!node) return [];
857
-
858
- this._resetResults();
859
- const queue: BinaryTreeNode<T>[] = [node];
860
-
861
- while (queue.length > 0) {
862
- const cur = queue.shift();
863
- if (cur) {
864
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
865
- if (cur.left) {
866
- queue.push(cur.left);
867
- }
868
- if (cur.right) {
869
- queue.push(cur.right);
870
- }
871
- }
872
- }
873
-
874
- return this._getResultByPropertyName(nodeOrPropertyName);
875
- }
876
-
877
- listLevels(node: BinaryTreeNode<T> | null): BinaryTreeNodeId[][];
878
-
879
- listLevels(node: BinaryTreeNode<T> | null, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[][];
880
-
881
- listLevels(node: BinaryTreeNode<T> | null, nodeOrPropertyName?: 'val'): T[][];
882
-
883
- listLevels(node: BinaryTreeNode<T> | null, nodeOrPropertyName?: 'node'): BinaryTreeNode<T>[][];
884
-
885
- listLevels(node: BinaryTreeNode<T> | null, nodeOrPropertyName?: 'count'): number[][];
886
-
887
- listLevels(node: BinaryTreeNode<T> | null, nodeOrPropertyName?: NodeOrPropertyName): ResultByProperty<T>[][] {
888
- nodeOrPropertyName = nodeOrPropertyName || 'id';
889
- node = node || this.root;
890
- if (!node) return [];
891
-
892
- const levelsNodes: ResultByProperty<T>[][] = [];
893
-
894
- const collectByProperty = (node: BinaryTreeNode<T>, level: number) => {
895
- switch (nodeOrPropertyName) {
896
- case 'id':
897
- levelsNodes[level].push(node.id);
898
- break;
899
- case 'val':
900
- levelsNodes[level].push(node.val);
901
- break;
902
- case 'node':
903
- levelsNodes[level].push(node);
904
- break;
905
- case 'count':
906
- levelsNodes[level].push(node.count);
907
- break;
908
- default:
909
- levelsNodes[level].push(node.id);
910
- break;
911
- }
912
- }
913
-
914
- if (this._loopType === LoopType.recursive) {
915
- const _recursive = (node: BinaryTreeNode<T>, level: number) => {
916
- if (!levelsNodes[level]) levelsNodes[level] = [];
917
- collectByProperty(node, level);
918
- if (node.left) _recursive(node.left, level + 1);
919
- if (node.right) _recursive(node.right, level + 1);
920
- };
921
-
922
- _recursive(node, 0);
923
- } else {
924
- const stack: [BinaryTreeNode<T>, number][] = [[node, 0]];
925
-
926
- while (stack.length > 0) {
927
- const head = stack.pop()!;
928
- const [node, level] = head;
929
-
930
- if (!levelsNodes[level]) levelsNodes[level] = [];
931
- collectByProperty(node, level);
932
- if (node.right) stack.push([node.right, level + 1]);
933
- if (node.left) stack.push([node.left, level + 1]);
934
- }
935
- }
936
-
937
- return levelsNodes;
938
- }
939
-
940
- getPredecessor(node: BinaryTreeNode<T>): BinaryTreeNode<T> {
941
- if (node.left) {
942
- let predecessor: BinaryTreeNode<T> | null | undefined = node.left;
943
- while (!(predecessor) || predecessor.right && predecessor.right !== node) {
944
- if (predecessor) {
945
- predecessor = predecessor.right;
946
- }
947
- }
948
- return predecessor;
949
- } else {
950
- return node;
951
- }
952
- }
953
-
954
- morris(): BinaryTreeNodeId[];
955
-
956
- morris(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'id'): BinaryTreeNodeId[];
957
-
958
- morris(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'val'): T[];
959
-
960
- morris(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'node'): BinaryTreeNode<T>[];
961
-
962
- morris(pattern?: DFSOrderPattern, nodeOrPropertyName?: 'count'): number[];
963
-
964
- /**
965
- * The time complexity of Morris traversal is O(n), it's may slower than others
966
- * The space complexity Morris traversal is O(1) because no using stack
967
- * @param pattern
968
- * @param nodeOrPropertyName
969
- */
970
- morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): ResultsByProperty<T> {
971
- if (this.root === null) return [];
972
-
973
- pattern = pattern || 'in';
974
- nodeOrPropertyName = nodeOrPropertyName || 'id';
975
-
976
- this._resetResults();
977
-
978
- let cur: BinaryTreeNode<T> | null | undefined = this.root;
979
- const _reverseEdge = (node: BinaryTreeNode<T> | null | undefined) => {
980
- let pre: BinaryTreeNode<T> | null | undefined = null;
981
- let next: BinaryTreeNode<T> | null | undefined = null;
982
- while (node) {
983
- next = node.right;
984
- node.right = pre;
985
- pre = node;
986
- node = next;
987
- }
988
- return pre;
989
- };
990
- const _printEdge = (node: BinaryTreeNode<T> | null) => {
991
- const tail: BinaryTreeNode<T> | null | undefined = _reverseEdge(node);
992
- let cur: BinaryTreeNode<T> | null | undefined = tail;
993
- while (cur) {
994
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
995
- cur = cur.right;
996
- }
997
- _reverseEdge(tail);
998
- };
999
- switch (pattern) {
1000
- case 'in':
1001
- while (cur) {
1002
- if (cur.left) {
1003
- const predecessor = this.getPredecessor(cur);
1004
- if (!predecessor.right) {
1005
- predecessor.right = cur;
1006
- cur = cur.left;
1007
- continue;
1008
- } else {
1009
- predecessor.right = null;
1010
- }
1011
- }
1012
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
1013
- cur = cur.right;
1014
- }
1015
- break;
1016
- case 'pre':
1017
- while (cur) {
1018
- if (cur.left) {
1019
- const predecessor = this.getPredecessor(cur);
1020
- if (!predecessor.right) {
1021
- predecessor.right = cur;
1022
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
1023
- cur = cur.left;
1024
- continue;
1025
- } else {
1026
- predecessor.right = null;
1027
- }
1028
- } else {
1029
- this._accumulatedByPropertyName(cur, nodeOrPropertyName);
1030
- }
1031
- cur = cur.right;
1032
- }
1033
- break;
1034
- case 'post':
1035
- while (cur) {
1036
- if (cur.left) {
1037
- const predecessor = this.getPredecessor(cur);
1038
- if (predecessor.right === null) {
1039
- predecessor.right = cur;
1040
- cur = cur.left;
1041
- continue;
1042
- } else {
1043
- predecessor.right = null;
1044
- _printEdge(cur.left);
1045
- }
1046
- }
1047
- cur = cur.right;
1048
- }
1049
- _printEdge(this.root);
1050
- break;
1051
- }
1052
-
1053
- return this._getResultByPropertyName(nodeOrPropertyName);
1054
- }
1055
-
1056
- protected _resetResults() {
1057
- this._visitedId = [];
1058
- this._visitedVal = [];
1059
- this._visitedNode = [];
1060
- this._visitedCount = [];
1061
- this._visitedLeftSum = [];
1062
- }
1063
-
1064
- protected _pushByPropertyNameStopOrNot(cur: BinaryTreeNode<T>, result: (BinaryTreeNode<T> | null | undefined)[], nodeProperty: BinaryTreeNodeId | T, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean) {
1065
- switch (propertyName) {
1066
- case 'id':
1067
- if (cur.id === nodeProperty) {
1068
- result.push(cur);
1069
- return !!onlyOne;
1070
- }
1071
- break;
1072
- case 'count':
1073
- if (cur.count === nodeProperty) {
1074
- result.push(cur);
1075
- return !!onlyOne;
1076
- }
1077
- break;
1078
- case 'val':
1079
- if (cur.val === nodeProperty) {
1080
- result.push(cur);
1081
- return !!onlyOne;
1082
- }
1083
- break;
1084
- default:
1085
- if (cur.id === nodeProperty) {
1086
- result.push(cur);
1087
- return !!onlyOne;
1088
- }
1089
- break;
1090
- }
1091
- }
1092
-
1093
- protected _accumulatedByPropertyName(node: BinaryTreeNode<T>, nodeOrPropertyName ?: NodeOrPropertyName) {
1094
- nodeOrPropertyName = nodeOrPropertyName ?? 'id';
1095
-
1096
- switch (nodeOrPropertyName) {
1097
- case 'id':
1098
- this._visitedId.push(node.id);
1099
- break;
1100
- case 'val':
1101
- this._visitedVal.push(node.val);
1102
- break;
1103
- case 'node':
1104
- this._visitedNode.push(node);
1105
- break;
1106
- case 'count':
1107
- this._visitedCount.push(node.count);
1108
- break;
1109
- default:
1110
- this._visitedId.push(node.id);
1111
- break;
1112
- }
1113
- }
1114
-
1115
- protected _getResultByPropertyName(nodeOrPropertyName ?: NodeOrPropertyName): ResultsByProperty<T> {
1116
- nodeOrPropertyName = nodeOrPropertyName ?? 'id';
1117
-
1118
- switch (nodeOrPropertyName) {
1119
- case 'id':
1120
- return this._visitedId;
1121
- case 'val':
1122
- return this._visitedVal;
1123
- case 'node':
1124
- return this._visitedNode;
1125
- case 'count':
1126
- return this._visitedCount;
1127
- default:
1128
- return this._visitedId;
1129
- }
1130
- }
1131
-
1132
- // --- end additional methods ---
1133
- }