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