Guest User

Untitled

a guest
Jul 19th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.48 KB | None | 0 0
  1. /*
  2. * Andrew Shultzabarger
  3. * CS 4343
  4. * Due: December 7th (allowed by Dr. Rao)
  5. *
  6. * Red-Black Tree Implementation
  7. * All algorithms were taken from the book.
  8. *
  9. */
  10.  
  11. package rbt;
  12.  
  13. import java.util.Random;
  14.  
  15. enum Color { RED, BLACK }
  16.  
  17. /*
  18. * Node elements used for storing in the red-black tree
  19. *
  20. * Satellite data is of type integer
  21. */
  22. class Node
  23. {
  24. public Node left, right, p;
  25. public Color color;
  26. public int key;
  27.  
  28. public Node(int k)
  29. {
  30. this.key = k;
  31. this.color = Color.BLACK;
  32. this.left = null;
  33. this.right = null;
  34. this.p = null;
  35. }
  36. }
  37.  
  38. /*
  39. * Red-Black tree implementation
  40. *
  41. * Performs insert and delete for any given Node element.
  42. * Also performs treewalks starting from the root node.
  43. *
  44. * Satellite data comparisons are done using boolean inequality operators
  45. */
  46. class Tree
  47. {
  48. public Node nil;
  49. public Node root;
  50.  
  51. /*
  52. * Tree object constructor. Initializes the sentinel nil node to refer
  53. * to itself.
  54. */
  55. public Tree(Node n)
  56. {
  57. this.nil = n;
  58. this.root = this.nil;
  59.  
  60. this.nil.left = this.nil;
  61. this.nil.right = this.nil;
  62. this.nil.p = this.nil;
  63. }
  64.  
  65. /*
  66. * Finds the minimum element from a given node in a tree
  67. */
  68. public Node treeMinimum(Node n)
  69. {
  70. while(n.left != this.nil)
  71. {
  72. n = n.left;
  73. }
  74. return n;
  75. }
  76.  
  77. /*
  78. * Finds the next element from a given node in a tree
  79. */
  80. public Node treeSuccessor(Node n)
  81. {
  82. Node y = this.nil;
  83.  
  84. if(n.right != this.nil)
  85. {
  86. return this.treeMinimum(n.right);
  87. }
  88.  
  89. y = n.p;
  90.  
  91. while(y != this.nil && n == y.right)
  92. {
  93. n = y;
  94. y = y.p;
  95. }
  96. return y;
  97. }
  98.  
  99. /*
  100. * Performs a left rotation from a given node in the tree
  101. */
  102. public void leftRotate(Node x)
  103. {
  104. Node y = x.right;
  105. x.right = y.left;
  106.  
  107. if(y.left != this.nil)
  108. {
  109. y.left.p = x;
  110. }
  111. y.p = x.p;
  112.  
  113. if(x.p == this.nil)
  114. {
  115. this.root = y;
  116. }
  117. else
  118. {
  119. if(x == x.p.left)
  120. {
  121. x.p.left = y;
  122. }
  123. else
  124. {
  125. x.p.right = y;
  126. }
  127. }
  128. y.left = x;
  129. x.p = y;
  130. }
  131.  
  132. /*
  133. * Performs a right rotation from a given node in the tree
  134. */
  135. public void rightRotate(Node x)
  136. {
  137. Node y = x.left;
  138. x.left = y.right;
  139.  
  140. if(y.right != this.nil)
  141. {
  142. y.right.p = x;
  143. }
  144. y.p = x.p;
  145.  
  146. if(x.p == this.nil)
  147. {
  148. this.root = y;
  149. }
  150. else
  151. {
  152. if(x == x.p.right)
  153. {
  154. x.p.right = y;
  155. }
  156. else
  157. {
  158. x.p.left = y;
  159. }
  160. }
  161. y.right = x;
  162. x.p = y;
  163. }
  164.  
  165. /*
  166. * Reorders the tree using the rotation methods to preserve the red-black
  167. * tree properties.
  168. */
  169. public void rbInsertFixup(Node z)
  170. {
  171. Node y = this.nil;
  172.  
  173. while(z.p.color == Color.RED)
  174. {
  175. if(z.p == z.p.p.left)
  176. {
  177. y = z.p.p.right;
  178.  
  179. if(y.color == Color.RED)
  180. {
  181. z.p.color = Color.BLACK;
  182. y.color = Color.BLACK;
  183. z.p.p.color = Color.RED;
  184. z = z.p.p;
  185. }
  186. else
  187. {
  188. if(z == z.p.right)
  189. {
  190. z = z.p;
  191. leftRotate(z);
  192. }
  193. z.p.color = Color.BLACK;
  194. z.p.p.color = Color.RED;
  195. rightRotate(z.p.p);
  196. }
  197. }
  198. else
  199. {
  200. y = z.p.p.left;
  201.  
  202. if(y.color == Color.RED)
  203. {
  204. z.p.color = Color.BLACK;
  205. y.color = Color.BLACK;
  206. z.p.p.color = Color.RED;
  207. z = z.p.p;
  208. }
  209. else
  210. {
  211. if(z == z.p.left)
  212. {
  213. z = z.p;
  214. rightRotate(z);
  215. }
  216. z.p.color = Color.BLACK;
  217. z.p.p.color = Color.RED;
  218. leftRotate(z.p.p);
  219. }
  220. }
  221. }
  222. this.root.color = Color.BLACK;
  223. }
  224.  
  225. /*
  226. * Inserts a given node into the tree. Calls rbInsertFixup() to reorder
  227. * the tree to preserve the red-black tree properties
  228. */
  229. public void rbInsert(Node z)
  230. {
  231. Node y = this.nil;
  232. Node x = this.root;
  233.  
  234. while(x != this.nil)
  235. {
  236. y = x;
  237.  
  238. if(z.key < x.key)
  239. {
  240. x = x.left;
  241. }
  242. else
  243. {
  244. x = x.right;
  245. }
  246. }
  247. z.p = y;
  248.  
  249. if(y == this.nil)
  250. {
  251. this.root = z;
  252. }
  253. else
  254. {
  255. if(z.key < y.key)
  256. {
  257. y.left = z;
  258. }
  259. else
  260. {
  261. y.right = z;
  262. }
  263. }
  264.  
  265. z.left = this.nil;
  266. z.right = this.nil;
  267. z.color = Color.RED;
  268. rbInsertFixup(z);
  269. }
  270.  
  271. /*
  272. * Reorders the tree using the rotation methods to preserve the red-black
  273. * tree properties.
  274. */
  275. public void rbDeleteFixup(Node x)
  276. {
  277. Node w = this.nil;
  278.  
  279. while(x != this.root && x.color == Color.BLACK)
  280. {
  281. if(x == x.p.left)
  282. {
  283. w = x.p.right;
  284.  
  285. if(w.color == Color.RED)
  286. {
  287. w.color = Color.BLACK;
  288. x.p.color = Color.RED;
  289. leftRotate(x.p);
  290. w = x.p.right;
  291. }
  292.  
  293. if(w.left.color == Color.BLACK && w.right.color == Color.BLACK)
  294. {
  295. w.color = Color.RED;
  296. x = x.p;
  297. }
  298. else
  299. {
  300. if(w.right.color == Color.BLACK)
  301. {
  302. w.left.color = Color.BLACK;
  303. w.color = Color.RED;
  304. rightRotate(w);
  305. w = x.p.right;
  306. }
  307.  
  308. w.color = x.p.color;
  309. x.p.color = Color.BLACK;
  310. w.right.color = Color.BLACK;
  311. leftRotate(x.p);
  312. x = this.root;
  313. }
  314. }
  315. else
  316. {
  317. w = x.p.left;
  318.  
  319. if(w.color == Color.RED)
  320. {
  321. w.color = Color.BLACK;
  322. x.p.color = Color.RED;
  323. rightRotate(x.p);
  324. w = x.p.left;
  325. }
  326.  
  327. if(w.right.color == Color.BLACK && w.left.color == Color.BLACK)
  328. {
  329. w.color = Color.RED;
  330. x = x.p;
  331. }
  332. else
  333. {
  334. if(w.left.color == Color.BLACK)
  335. {
  336. w.right.color = Color.BLACK;
  337. w.color = Color.RED;
  338. leftRotate(w);
  339. w = x.p.left;
  340. }
  341.  
  342. w.color = x.p.color;
  343. x.p.color = Color.BLACK;
  344. w.left.color = Color.BLACK;
  345. rightRotate(x.p);
  346. x = this.root;
  347. }
  348. }
  349. }
  350. x.color = Color.BLACK;
  351. }
  352.  
  353. /*
  354. * Deletes a specified node from the tree. Calls rbDeleteFixup() to reorder
  355. * the tree to preserve the red-black tree properties.
  356. */
  357. public Node rbDelete(Node z)
  358. {
  359. Node x = this.nil;
  360. Node y = this.nil;
  361.  
  362. if(z.left == this.nil || z.right == this.nil)
  363. {
  364. y = z;
  365. }
  366. else
  367. {
  368. y = this.treeSuccessor(z);
  369. }
  370.  
  371. if(y.left != this.nil)
  372. {
  373. x = y.left;
  374. }
  375. else
  376. {
  377. x = y.right;
  378. }
  379. x.p = y.p;
  380.  
  381. if(y.p == this.nil)
  382. {
  383. this.root = x;
  384. }
  385. else
  386. {
  387. if(y == y.p.left)
  388. {
  389. y.p.left = x;
  390. }
  391. else
  392. {
  393. y.p.right = x;
  394. }
  395. }
  396.  
  397. if(y != z)
  398. {
  399. z.key = y.key;
  400. }
  401.  
  402. if(y.color == Color.BLACK)
  403. {
  404. rbDeleteFixup(x);
  405. }
  406. return y;
  407. }
  408.  
  409. public void inorderWalk(Node n)
  410. {
  411. boolean printParen;
  412.  
  413. if(n != this.nil)
  414. {
  415. printParen = n.left != this.nil || n.right != this.nil;
  416.  
  417. if(printParen) { System.out.print("( "); }
  418.  
  419. this.inorderWalk(n.left);
  420. System.out.print(n.key + " " + n.color + ", ");
  421. this.inorderWalk(n.right);
  422.  
  423. if(printParen) { System.out.print(") "); }
  424. }
  425. }
  426.  
  427. public void preorderWalk(Node n)
  428. {
  429. if(n != this.nil)
  430. {
  431. System.out.print(n.key + " " + n.color + ", ");
  432. this.preorderWalk(n.left);
  433. this.preorderWalk(n.right);
  434. }
  435. }
  436.  
  437. public void postorderWalk(Node n)
  438. {
  439. if(n != this.nil)
  440. {
  441. this.postorderWalk(n.left);
  442. this.postorderWalk(n.right);
  443. System.out.print(n.key + " " + n.color + ", ");
  444. }
  445. }
  446. }
  447.  
  448. public class Main
  449. {
  450. private static final int NUM_KEYS = 40;
  451. private static final Random rand = new Random();
  452.  
  453. /*
  454. * Method for generating a list of random integers
  455. */
  456. private static final int[] getNewKeySet(int numKeys)
  457. {
  458. int keySet[] = new int[numKeys];
  459.  
  460. for(int i = 0; i < numKeys; ++i)
  461. {
  462. keySet[i] = Main.rand.nextInt(numKeys * numKeys);
  463. }
  464. return keySet;
  465. }
  466.  
  467. /*
  468. * Main method
  469. */
  470. public static void main(String[] args)
  471. {
  472. int keySet[] = getNewKeySet(Main.NUM_KEYS);
  473. Node dList[] = new Node[Main.NUM_KEYS];
  474. Node curr;
  475. int index;
  476.  
  477. Tree tree = new Tree(new Node(-1));
  478.  
  479. /*
  480. * Insert the initial 30 keys, save a copy of the generated nodes
  481. * in the dList[] array. This is used to reference the exact objects
  482. * for deletion.
  483. */
  484. System.out.println("\n\n---------------------------------------\n\n");
  485. System.out.println("[!] INITIAL 30 NODE INSERTIONS");
  486. System.out.println("\n\n---------------------------------------\n\n");
  487.  
  488. for(int i = 0; i < 30; ++i)
  489. {
  490. curr = new Node(keySet[i]);
  491. tree.rbInsert(curr);
  492. dList[i] = curr;
  493. }
  494.  
  495. /*
  496. * Print the tree using all three tree-walk algorithms
  497. */
  498. System.out.println("\n\n---------------------------------------\n\n");
  499. System.out.println("[!] INITIAL TREE TRAVERSALS");
  500. System.out.println("\n\n---------------------------------------\n\n");
  501.  
  502. System.out.println("Inorder");
  503. tree.inorderWalk(tree.root);
  504. System.out.println();
  505.  
  506. System.out.println("\nPreorder");
  507. tree.preorderWalk(tree.root);
  508. System.out.println();
  509.  
  510. System.out.println("\nPostorder");
  511. tree.postorderWalk(tree.root);
  512. System.out.println();
  513.  
  514. /*
  515. * Delete from the tree 5 keys slected at random.
  516. */
  517. System.out.println("\n\n---------------------------------------\n\n");
  518. System.out.println("[!] 5 RANDOM NODE DELETIONS");
  519. System.out.println("\n\n---------------------------------------\n\n");
  520.  
  521. index = rand.nextInt(25);
  522. for(int i = index, count = 0; count < 5; ++i, ++count)
  523. {
  524. System.out.println("\nDeleting key " + dList[i].key);
  525. tree.rbDelete(dList[i]);
  526. tree.inorderWalk(tree.root);
  527. System.out.println();
  528. }
  529.  
  530. /*
  531. * Insert the remaining 10 keys from the keyList[]
  532. */
  533. System.out.println("\n\n---------------------------------------\n\n");
  534. System.out.println("[!] REMAINING 10 NODE INSERTIONS");
  535. System.out.println("\n\n---------------------------------------\n\n");
  536.  
  537. for(int i = 30; i < Main.NUM_KEYS; ++i)
  538. {
  539. curr = new Node(keySet[i]);
  540. tree.rbInsert(curr);
  541. }
  542.  
  543. /*
  544. * Print the resulting tree using inorder tree traversal
  545. */
  546. System.out.println("\n\n---------------------------------------\n\n");
  547. System.out.println("[!] RESULTING TREE TRAVERSAL");
  548. System.out.println("\n\n---------------------------------------\n\n");
  549.  
  550. System.out.println("Inorder");
  551. tree.inorderWalk(tree.root);
  552. System.out.println();
  553. }
  554. }
Add Comment
Please, Sign In to add comment