Advertisement
Guest User

Untitled

a guest
Jun 24th, 2019
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.48 KB | None | 0 0
  1. /**
  2. * @flow
  3. */
  4.  
  5. type Node<V> = {|
  6. left: ?Node<V>,
  7. right: ?Node<V>,
  8. parent: ?Node<V>,
  9. height: number,
  10. value: V,
  11. |};
  12.  
  13. export class Tree<V, K = V> {
  14. root: ?Node<V>;
  15. cmp: (K, V) => number;
  16. key: V => K;
  17.  
  18. constructor(cmp: (K, V) => number, key: V => K) {
  19. this.cmp = cmp;
  20. this.key = key;
  21. }
  22.  
  23. find(k: K): ?V {
  24. const cmp = this.cmp;
  25. let node: ?Node<V> = this.root;
  26. while (node != null) {
  27. const c = cmp(k, node.value);
  28. if (c === 0) {
  29. return node.value;
  30. } else if (c > 0) {
  31. node = node.right;
  32. } else {
  33. node = node.left;
  34. }
  35. }
  36. }
  37.  
  38. insert(v: V, k: ?K): Node<V> {
  39. if (k == null) k = this.key(v);
  40. if (this.root == null) {
  41. return (this.root = {
  42. value: v,
  43. height: 1,
  44. left: null,
  45. right: null,
  46. parent: null,
  47. });
  48. }
  49. const cmp = this.cmp;
  50. let node: Node<V> = this.root;
  51. let result;
  52. while (result == null) {
  53. const c = cmp(k, node.value);
  54. if (c === 0) {
  55. node.value = v;
  56. return node;
  57. } else if (c < 0) {
  58. if (node.left == null) {
  59. result = {
  60. parent: node,
  61. ret: (node.left = {
  62. value: v,
  63. parent: node,
  64. height: 1,
  65. left: null,
  66. right: null,
  67. }),
  68. };
  69. } else {
  70. node = node.left;
  71. }
  72. } else {
  73. if (node.right == null) {
  74. result = {
  75. parent: node,
  76. ret: (node.right = {
  77. value: v,
  78. parent: node,
  79. height: 1,
  80. left: null,
  81. right: null,
  82. }),
  83. };
  84. } else {
  85. node = node.right;
  86. }
  87. }
  88. }
  89. this.fixHeights(result.parent);
  90. return result.ret;
  91. }
  92.  
  93. remove(k: K): ?V {
  94. const cmp = this.cmp;
  95. let node: ?Node<V> = this.root;
  96. while (node != null) {
  97. const c = cmp(k, node.value);
  98. if (c === 0) {
  99. break;
  100. } else if (c > 0) {
  101. node = node.right;
  102. } else {
  103. node = node.left;
  104. }
  105. }
  106. if (node == null) {
  107. return;
  108. }
  109.  
  110. if (node.left == null && node.right == null) {
  111. if (node.parent == null) {
  112. this.root = null;
  113. } else if (node.parent.left === node) {
  114. node.parent.left = null;
  115. } else {
  116. node.parent.right = null;
  117. }
  118. } else if (node.left != null && node.right != null) {
  119. const oldNode = node;
  120. while (node.left != null) {
  121. node = node.left;
  122. }
  123. oldNode.value = node.value;
  124. node.parent.left = node.right;
  125. if (node.right != null) {
  126. node.right.parent = node.parent;
  127. }
  128. } else if (node.left == null) {
  129. if (node.parent == null) {
  130. this.root = node.right;
  131. node.right.parent = null;
  132. } else {
  133. if (node.parent.left === node) {
  134. node.parent.left = node.right;
  135. } else {
  136. node.parent.right = node.right;
  137. }
  138. node.right.parent = node.parent;
  139. }
  140. } else {
  141. if (node.parent == null) {
  142. this.root = node.left;
  143. node.left.parent = null;
  144. } else {
  145. if (node.parent.right === node) {
  146. node.parent.right = node.left;
  147. } else {
  148. node.parent.left = node.left;
  149. }
  150. node.left.parent = node.parent;
  151. }
  152. }
  153. if (node.parent != null) {
  154. const parent = node.parent;
  155. node.parent = null;
  156. node.left = null;
  157. node.right = null;
  158. this.fixHeights(parent);
  159. }
  160. return node.value;
  161. }
  162.  
  163. fixHeights(node: Node<V>) {
  164. let parent = node;
  165. while (parent != null) {
  166. let {left, right} = parent;
  167. const leftHeight = left == null ? 0 : left.height;
  168. const rightHeight = right == null ? 0 : right.height;
  169. if (Math.abs(leftHeight - rightHeight) > 1) {
  170. const y = leftHeight > rightHeight ? left : right;
  171. if (y == null) throw new Error();
  172. let z;
  173. {
  174. const {left, right} = y;
  175. const leftHeight = left == null ? 0 : left.height;
  176. const rightHeight = right == null ? 0 : right.height;
  177. z = leftHeight > rightHeight ? left : right;
  178. }
  179. if (z == null) throw new Error();
  180. const connection: ?Node<V> = parent.parent;
  181. let isRightChild: ?boolean = connection && connection.right === parent;
  182. parent = this.restruct(parent, y, z);
  183. if (connection != null) {
  184. if (isRightChild) {
  185. connection.right = parent;
  186. } else {
  187. connection.left = parent;
  188. }
  189. } else {
  190. this.root = parent;
  191. }
  192. parent.parent = connection;
  193. } else {
  194. parent.height = Math.max(leftHeight, rightHeight) + 1;
  195. }
  196. parent = parent.parent;
  197. }
  198. }
  199.  
  200. restruct(x: Node<V>, y: Node<V>, z: Node<V>): Node<V> {
  201. let a, b, c, t1, t2, t3, t4;
  202. if (x.left === y) {
  203. if (y.left === z) {
  204. a = z;
  205. b = y;
  206. c = x;
  207. t1 = a.left;
  208. t2 = a.right;
  209. t3 = b.right;
  210. t4 = c.right;
  211. } else {
  212. a = y;
  213. b = z;
  214. c = x;
  215. t1 = a.left;
  216. t2 = b.left;
  217. t3 = b.right;
  218. t4 = c.right;
  219. }
  220. } else {
  221. if (y.right === z) {
  222. a = x;
  223. b = y;
  224. c = z;
  225. t1 = a.left;
  226. t2 = b.left;
  227. t3 = c.left;
  228. t4 = c.right;
  229. } else {
  230. a = x;
  231. b = z;
  232. c = y;
  233. t1 = a.left;
  234. t2 = b.left;
  235. t3 = b.right;
  236. t4 = c.right;
  237. }
  238. }
  239. a.left = t1;
  240. a.right = t2;
  241. let h1 = 0;
  242. let h2 = 0;
  243. if (t1) {
  244. t1.parent = a;
  245. h1 = t1.height;
  246. }
  247. if (t2) {
  248. t2.parent = a;
  249. h2 = t2.height;
  250. }
  251. a.height = Math.max(h1, h2) + 1;
  252. h1 = 0;
  253. h2 = 0;
  254. c.left = t3;
  255. c.right = t4;
  256. if (t3) {
  257. t3.parent = c;
  258. h1 = t3.height;
  259. }
  260. if (t4) {
  261. t4.parent = c;
  262. h2 = t4.height;
  263. }
  264. c.height = Math.max(h1, h2) + 1;
  265. b.left = a;
  266. b.right = c;
  267. a.parent = b;
  268. c.parent = b;
  269. b.height = Math.max(a.height, c.height) + 1;
  270. return b;
  271. }
  272.  
  273. inOrder(fn: V => void) {
  274. let node = this.root;
  275. const stack = [];
  276. while (stack.length !== 0 || node != null) {
  277. while (node != null) {
  278. stack.push(node);
  279. node = node.left;
  280. }
  281. node = stack.pop();
  282. fn(node.value);
  283. node = node.right;
  284. }
  285. }
  286.  
  287. preOrder(fn: V => void) {
  288. if (this.root == null) return;
  289. const stack = [this.root];
  290. while (stack.length > 0) {
  291. let node = stack.pop();
  292. fn(node.value);
  293. if (node.right) stack.push(node.right);
  294. if (node.left) stack.push(node.left);
  295. }
  296. }
  297.  
  298. postOrder(fn: V => void) {
  299. if (this.root == null) return;
  300. const stack = [this.root];
  301. const array = [];
  302. while (stack.length > 0) {
  303. let node = stack.pop();
  304. node = stack.pop();
  305. if (node.right) stack.push(node.right);
  306. if (node.left) stack.push(node.left);
  307. array.push(node.value);
  308. }
  309. for (let i = array.length - 1; i >= 0; i--) {
  310. fn(array[i]);
  311. }
  312. }
  313.  
  314. range(start: K, end: K): V[] {
  315. let node = this.root;
  316. const cmp = this.cmp;
  317. const result: V[] = [];
  318. const stack = [];
  319. while (stack.length > 0 || node != null) {
  320. while (node != null) {
  321. stack.push(node);
  322. if (cmp(start, node.value) < 0) {
  323. node = node.left;
  324. } else {
  325. node = null;
  326. }
  327. }
  328. node = stack.pop();
  329. if (cmp(start, node.value) <= 0 && cmp(end, node.value) >= 0) {
  330. result.push(node.value);
  331. }
  332. if (node.right && cmp(end, node.value) > 0) {
  333. node = node.right;
  334. } else {
  335. node = null;
  336. }
  337. }
  338. return result;
  339. }
  340.  
  341. first(): ?V {
  342. const min = this.min(this.root);
  343. return min && min.value;
  344. }
  345.  
  346. last(): ?V {
  347. const max = this.max(this.root);
  348. return max && max.value;
  349. }
  350.  
  351. min(node: ?Node<V> = this.root): ?Node<V> {
  352. if (node == null) return;
  353. while (node.left != null) {
  354. node = node.left;
  355. }
  356. return node;
  357. }
  358.  
  359. max(node: ?Node<V> = this.root): ?Node<V> {
  360. if (node == null) return;
  361. while (node.right != null) {
  362. node = node.right;
  363. }
  364. return node;
  365. }
  366.  
  367. next(node: Node<V>): ?Node<V> {
  368. if (node.right != null) {
  369. return this.min(node.right);
  370. }
  371. while (node.parent != null && node.parent.right === node) {
  372. node = node.parent;
  373. }
  374. return node.parent;
  375. }
  376.  
  377. prev(node: Node<V>): ?Node<V> {
  378. if (node.left != null) {
  379. return this.min(node.left);
  380. }
  381. while (node.parent != null && node.parent.left === node) {
  382. node = node.parent;
  383. }
  384. return node.parent;
  385. }
  386.  
  387. toString(toString: V => string, node: ?Node<V> = this.root) {
  388. if (node == null) return '';
  389. let children =
  390. '[' +
  391. this.toString(toString, node.left) +
  392. ',' +
  393. this.toString(toString, node.right) +
  394. ']';
  395. if (node.left == null && node.right == null) return toString(node.value);
  396. return toString(node.value) + (children == '[,]' ? '' : children);
  397. }
  398.  
  399. checkAVL(
  400. node: ?Node<V> = this.root,
  401. map: Map<Node<V>, number> = new Map<Node<V>, number>(),
  402. ): boolean {
  403. if (node == null) return true;
  404. const left = this.checkAVL(node.left, map);
  405. const right = this.checkAVL(node.right, map);
  406. if (!(left && right)) return false;
  407. const leftHeight = node.left ? map.get(node.left) : 0;
  408. const rightHeight = node.right ? map.get(node.right) : 0;
  409. if (leftHeight == null || rightHeight == null) throw new Error();
  410. if (Math.abs(leftHeight - rightHeight) > 1) return false;
  411. map.set(node, Math.max(leftHeight, rightHeight) + 1);
  412. return true;
  413. }
  414. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement