Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.28 KB | None | 0 0
  1. import java.io.*;
  2. public class Tree
  3. {
  4. private TNode root = null;
  5.  
  6. public Tree ()
  7. {
  8. root = null;
  9. }
  10.  
  11.  
  12. public Tree (TNode r)
  13. {
  14. root = r;
  15. }
  16.  
  17.  
  18. public TNode getRoot ()
  19. {
  20. return root;
  21. }
  22.  
  23.  
  24. public void setRoot (TNode r)
  25. {
  26. root = r;
  27. }
  28.  
  29.  
  30. private void updateTreeHeights ()
  31. {
  32. if (this.root != null)
  33. {
  34. int leftHeight = 0;
  35. if (this.root.getLeft () != null)
  36. {
  37. Tree lTree = new Tree (this.root.getLeft ());
  38. lTree.updateTreeHeights ();
  39. leftHeight = this.root.getLeft ().getHeight ();
  40. }
  41. int rightHeight = 0;
  42. if (this.root.getRight () != null)
  43. {
  44. Tree rTree = new Tree (this.root.getRight ());
  45. rTree.updateTreeHeights ();
  46. rightHeight = this.root.getRight ().getHeight ();
  47. }
  48. this.root.setHeight (Math.max (leftHeight, rightHeight) + 1);
  49. }
  50. }
  51.  
  52.  
  53.  
  54. //calculate the height of the tree: one node is a height of 1
  55.  
  56. public int height ()
  57. {
  58. int treeHeight = 0;
  59. if (this.getRoot () != null)
  60. {
  61. Tree lTree = new Tree (this.getRoot ().getLeft ());
  62. int lHeight = 1 + lTree.height ();
  63.  
  64. Tree rTree = new Tree (this.getRoot ().getRight ());
  65. int rHeight = 1 + rTree.height ();
  66.  
  67. treeHeight = lHeight > rHeight ? lHeight:
  68. rHeight;
  69. }
  70. return treeHeight;
  71. }
  72.  
  73.  
  74. private int balanceFactor ()
  75. {
  76. int leftHeight = 0;
  77. int rightHeight = 0;
  78.  
  79. if (root.getLeft () != null)
  80. {
  81. leftHeight = root.getLeft ().getHeight ();
  82. }
  83.  
  84. if (root.getRight () != null)
  85. {
  86. rightHeight = root.getRight ().getHeight ();
  87. }
  88.  
  89. return leftHeight - rightHeight;
  90. }
  91.  
  92.  
  93. private void balance (TNode p)
  94. {
  95. if (p != null)
  96. {
  97. TNode ancestor = p;
  98.  
  99. while (ancestor != null)
  100. {
  101. Tree ancestorTree = new Tree (ancestor);
  102.  
  103. if (ancestorTree.balanceFactor () == -2)
  104. {
  105. Tree rTree = new Tree (ancestorTree.root.getRight ());
  106.  
  107. int rTreeBalanceFactor = rTree.balanceFactor ();
  108. if (rTreeBalanceFactor == -1 || rTreeBalanceFactor == 0)
  109. { //0 happens in delete case 7a
  110. if (ancestor == root)
  111. {
  112. root = ancestorTree.leftRotate ();
  113. this.updateTreeHeights ();
  114. }
  115. else
  116. {
  117.  
  118. // determine if the ancestor is a left or a right child
  119.  
  120. if (ancestor.getParent ().getLeft () == ancestor)
  121. ancestor.getParent ().setLeft (ancestorTree.leftRotate ());
  122. else
  123. ancestor.getParent ().setRight (ancestorTree.leftRotate ());
  124. ancestorTree.updateTreeHeights ();
  125. updateTreeHeightsAbove (ancestor);
  126.  
  127. for (TNode q = ancestor.getParent () ; q != null ; q = q.getParent ())
  128. {
  129. updateNodeHeight (q);
  130. }
  131. }
  132. }
  133. else if (rTreeBalanceFactor == 1 || rTreeBalanceFactor == 0)
  134. {
  135. ancestor.setRight (rTree.rightRotate ());
  136. rTree.updateTreeHeights ();
  137. if (ancestor == root)
  138. {
  139. root = ancestorTree.leftRotate ();
  140. this.updateTreeHeights ();
  141. }
  142. else
  143. { // determine if the ancestor is a left or a right child
  144.  
  145. if (ancestor.getParent ().getLeft () == ancestor)
  146. ancestor.getParent ().setLeft (ancestorTree.leftRotate ());
  147. else
  148. ancestor.getParent ().setRight (ancestorTree.leftRotate ());
  149. ancestorTree.updateTreeHeights ();
  150. updateTreeHeightsAbove (ancestor);
  151.  
  152. for (TNode q = ancestor.getParent () ; q != null ; q = q.getParent ())
  153. {
  154. updateNodeHeight (q);
  155. }
  156. }
  157. }
  158. }
  159. else if (ancestorTree.balanceFactor () == 2)
  160. {
  161. Tree lTree = new Tree (ancestorTree.root.getLeft ());
  162.  
  163. int lTreeBalanceFactor = lTree.balanceFactor ();
  164. if (lTreeBalanceFactor == 1 || lTreeBalanceFactor == 0)
  165. { // 0 this symmetrical case of 7a does not happen. it's here to make the method symmetric and possible future optimization
  166. if (ancestor == root)
  167. {
  168. root = ancestorTree.rightRotate ();
  169. this.updateTreeHeights ();
  170. }
  171. else
  172. { // determine if the ancestor is a left or a right child
  173.  
  174. if (ancestor.getParent ().getLeft () == ancestor)
  175. ancestor.getParent ().setLeft (ancestorTree.rightRotate ());
  176. else
  177. ancestor.getParent ().setRight (ancestorTree.rightRotate ());
  178. ancestorTree.updateTreeHeights ();
  179.  
  180. for (TNode q = ancestor.getParent () ; q != null ; q = q.getParent ())
  181. {
  182. updateNodeHeight (q);
  183. }
  184. }
  185. }
  186. else if (lTreeBalanceFactor == -1 || lTreeBalanceFactor == 0)
  187. {
  188. ancestor.setLeft (lTree.leftRotate ());
  189. lTree.updateTreeHeights ();
  190. if (ancestor == root)
  191. {
  192. root = ancestorTree.rightRotate ();
  193. this.updateTreeHeights ();
  194. }
  195. else
  196. { // determine if the ancestor is a left or a right child
  197. if (ancestor.getParent ().getLeft () == ancestor)
  198. ancestor.getParent ().setLeft (ancestorTree.rightRotate ());
  199. else
  200. ancestor.getParent ().setRight (ancestorTree.rightRotate ());
  201. ancestorTree.updateTreeHeights ();
  202.  
  203. for (TNode q = ancestor.getParent () ; q != null ; q = q.getParent ())
  204. {
  205. updateNodeHeight (q);
  206. }
  207. }
  208. }
  209. }
  210. ancestor = ancestor.getParent (); // ancestor may have changed in rotation. ancestor keeps moving up anyway and will reach the null of the root's parent
  211. }
  212. }
  213. }
  214.  
  215.  
  216. public void insertNodeRec (TNode p)
  217. {
  218. if (root == null)
  219. {
  220. root = p;
  221. }
  222. else if (p.getIdentification ().compareTo (root.getIdentification ()) < 0)
  223. {
  224. if (root.getLeft () == null)
  225. {
  226. root.setLeft (p);
  227. p.setParent (root);
  228. }
  229. else
  230. {
  231. Tree t = new Tree (root.getLeft ());
  232. t.insertNodeRec (p);
  233. }
  234. }
  235. else if (p.getIdentification ().compareTo (root.getIdentification ()) > 0)
  236. {
  237. if (root.getRight () == null)
  238. {
  239. root.setRight (p);
  240. p.setParent (root);
  241. }
  242. else
  243. {
  244. Tree t = new Tree (root.getRight ());
  245. t.insertNodeRec (p);
  246. }
  247. }
  248. else
  249. {
  250. System.out.println ("Error inserting a node. Id already exists");
  251. }
  252. updateNodeHeight (root);
  253. }
  254.  
  255.  
  256. public void insertNode (TNode p)
  257. {
  258. insertNodeRec (p);
  259. balance (p);
  260. }
  261.  
  262.  
  263. private void updateNodeHeight (TNode p)
  264. {
  265. int leftHeight = p.getLeft () != null ? p.getLeft ().getHeight ():
  266. 0;
  267. int rightHeight = p.getRight () != null ? p.getRight ().getHeight ():
  268. 0;
  269. p.setHeight (Math.max (leftHeight, rightHeight) + 1);
  270. }
  271.  
  272.  
  273. public void printTree ()
  274. {
  275. if (root != null)
  276. {
  277. Tree t = null;
  278.  
  279. t = new Tree (root.getLeft ());
  280. t.printTree ();
  281.  
  282. System.out.println (root);
  283.  
  284. t = new Tree (root.getRight ());
  285. t.printTree ();
  286. }
  287. }
  288.  
  289.  
  290. public void printTree (int level)
  291. {
  292. if (root != null)
  293. {
  294. Tree t = null;
  295.  
  296. t = new Tree (root.getLeft ());
  297. t.printTree (level + 1);
  298.  
  299. System.out.println (root + " in Level: " + level + " at Height: " + root.getHeight ());
  300.  
  301. t = new Tree (root.getRight ());
  302. t.printTree (level + 1);
  303. }
  304. }
  305.  
  306.  
  307. private TNode rightRotate ()
  308. {
  309. TNode p = root.getLeft ();
  310. p.setParent (root.getParent ());
  311.  
  312. root.setLeft (p.getRight ());
  313.  
  314. if (root.getLeft () != null)
  315. {
  316. root.getLeft ().setParent (root);
  317. }
  318. p.setRight (root);
  319. p.getRight ().setParent (p);
  320. return p;
  321. }
  322.  
  323.  
  324. private TNode leftRotate ()
  325. {
  326. TNode p = root.getRight ();
  327. p.setParent (root.getParent ());
  328.  
  329. root.setRight (p.getLeft ());
  330.  
  331. if (root.getRight () != null)
  332. {
  333. root.getRight ().setParent (root);
  334. }
  335. p.setLeft (root);
  336. p.getLeft ().setParent (p);
  337.  
  338. return p;
  339. }
  340.  
  341.  
  342. public void breadthFirstRetrieve (String fileName)
  343. {
  344. try
  345. {
  346. RandomAccessFile f = new RandomAccessFile (fileName, "rw");
  347.  
  348. int nodes = (int) (f.length () / (Globals.IDENTIFICATION_LEN + Globals.INT_LEN));
  349. TNode p = null;
  350. byte[] identification = new byte [Globals.IDENTIFICATION_LEN];
  351. String identificationString = Globals.STR_NULL;
  352.  
  353. for (int i = 0 ; i < nodes ; i++)
  354. {
  355. identificationString = Globals.STR_NULL;
  356. f.read (identification);
  357.  
  358. for (int j = 0 ; j < identification.length ; j++)
  359. {
  360. identificationString = identificationString + (char) identification [j];
  361. }
  362.  
  363. p = new TNode (identificationString, f.readInt (), null, null, null);
  364. this.insertNodeRec (p);
  365. }
  366. f.close ();
  367. }
  368. catch (IOException e)
  369. {
  370. System.out.println ("***Error: Unable to retrieve tree file " + fileName);
  371. }
  372. }
  373.  
  374.  
  375. public TNode findNode (String identification)
  376. {
  377. if (root == null)
  378. {
  379. return null;
  380. }
  381. else if (identification.equals (root.getIdentification ()))
  382. {
  383. return root;
  384. }
  385. else if (identification.compareTo (root.getIdentification ()) < 0)
  386. {
  387. Tree t = new Tree (root.getLeft ());
  388. return t.findNode (identification);
  389. }
  390. else if (identification.compareTo (root.getIdentification ()) > 0)
  391. {
  392. Tree t = new Tree (root.getRight ());
  393. return t.findNode (identification);
  394. }
  395. else
  396. {
  397. System.out.println ("Fatal error");
  398. return null;
  399. }
  400. }
  401.  
  402.  
  403. public void buildFromMessagesFile (int whatId)
  404. { // rebuild index depending on what index
  405. Record record = new Record ();
  406. for (int recordNumber = 0 ; recordNumber < Globals.totalRecordsInMessagesFile ; recordNumber++)
  407. {
  408. record.readFromMessagesFile (recordNumber);
  409. if (record.getData ().charAt (Globals.FIRST_RECORD_MARKER_POS) == Globals.FIRST_RECORD_MARKER)
  410. {
  411. Message message = new Message ();
  412. message.readFromMessagesFile (recordNumber);
  413.  
  414. String key = Globals.STR_NULL;
  415. if (whatId == Globals.SENDER_ID)
  416. {
  417. key = message.getIdSenderFirst ();
  418. }
  419. else if (whatId == Globals.RECEIVER_ID)
  420. {
  421. key = message.getIdReceiverFirst ();
  422. }
  423. else
  424. {
  425. System.out.println ("***invalid whatId parameter in buildFromMessagesFile()");
  426. }
  427. TNode p = new TNode (key, recordNumber, null, null, null);
  428. insertNodeRec (p);
  429. }
  430. }
  431. }
  432.  
  433.  
  434. public void breadthFirstSave (String fileName)
  435. {
  436. try
  437. {
  438. RandomAccessFile f = new RandomAccessFile (fileName, "rw");
  439. f.setLength (0);
  440.  
  441. for (int i = 0 ; i < height () ; i++)
  442. {
  443. writeLevel (i, f);
  444. }
  445. f.close ();
  446. }
  447. catch (IOException e)
  448. {
  449. System.out.println (e);
  450. }
  451. }
  452.  
  453.  
  454. public void writeLevel (int level, RandomAccessFile f)
  455. {
  456. if (level == 0)
  457. {
  458. try
  459. {
  460. if (root != null)
  461. {
  462. f.write (root.getIdentification ().getBytes ());
  463. f.writeInt (root.getRecordNumber ());
  464. }
  465. }
  466. catch (IOException e)
  467. {
  468. System.out.println (e);
  469. }
  470. }
  471. else if (root != null)
  472. {
  473. Tree tree = new Tree (root.getLeft ());
  474. tree.writeLevel (level - 1, f);
  475. tree = new Tree (root.getRight ());
  476. tree.writeLevel (level - 1, f);
  477. }
  478. }
  479.  
  480.  
  481. public TNode findNode (String partialKey, int where)
  482. {
  483. if (partialKey.length () == Globals.IDENTIFICATION_LEN)
  484. {
  485. return findNode (partialKey);
  486. }
  487. else if (root == null)
  488. {
  489. return null;
  490. }
  491. else
  492. {
  493. int n = partialKey.length ();
  494.  
  495. if (partialKey.compareTo (root.getIdentification ().substring (0, n)) < 0)
  496. {
  497. Tree t = new Tree (root.getLeft ());
  498. return t.findNode (partialKey, where);
  499. }
  500. else if (partialKey.compareTo (root.getIdentification ().substring (0, n)) > 0)
  501. {
  502. Tree t = new Tree (root.getRight ());
  503. return t.findNode (partialKey, where);
  504. }
  505. else
  506. {
  507. TNode p = new TNode (root.getIdentification (), root.getRecordNumber (), root.getLeft (), root.getRight (), root.getParent ());
  508. if (where == 0)
  509. {
  510. TNode q = p.getLeft ();
  511. while (q != null)
  512. {
  513. if (q.getIdentification ().substring (0, n).equals (partialKey))
  514. {
  515. p = q;
  516. q = q.getLeft ();
  517. }
  518. else
  519. {
  520. q = q.getRight ();
  521. }
  522. }
  523. }
  524. else
  525. {
  526. TNode q = p.getRight ();
  527. while (q != null)
  528. {
  529. if (q.getIdentification ().substring (0, n).equals (partialKey))
  530. {
  531. p = q;
  532. q = q.getRight ();
  533. }
  534. else
  535. {
  536. q = q.getLeft ();
  537. }
  538. }
  539. }
  540. return p;
  541. }
  542. }
  543. }
  544.  
  545.  
  546. private void setParentsChildLink (TNode p, TNode q)
  547. {
  548. if (p.getIdentification ().compareTo (p.getParent ().getIdentification ()) < 0)
  549. p.getParent ().setLeft (q);
  550. else if (p.getIdentification ().compareTo (p.getParent ().getIdentification ()) > 0)
  551. p.getParent ().setRight (q);
  552. else
  553. System.out.println ("Error deleting root setting a parent's child link");
  554. }
  555.  
  556.  
  557. public void deleteNode (TNode p)
  558. {
  559. if (p != null)
  560. {
  561. TNode q = null;
  562. TNode r = null;
  563. if (p.getLeft () == null && p.getRight () == null)
  564. {
  565. r = p.getParent ();
  566. if (p == root)
  567. root = null;
  568. else
  569. setParentsChildLink (p, null);
  570. }
  571. else if (p.getLeft () != null && p.getRight () == null || p.getLeft () == null && p.getRight () != null)
  572. {
  573. q = (p.getLeft () != null) ? p.getLeft ():
  574. p.getRight ();
  575.  
  576. if (p == root)
  577. root = q;
  578. else
  579. setParentsChildLink (p, q);
  580.  
  581. q.setParent (p.getParent ());
  582. r = q.getParent ();
  583. }
  584. else
  585. {
  586. q = p.getLeft ();
  587. if (p.getLeft ().getRight () == null)
  588. { //at this point it must have two children, thus it won't crash with p.getLeft (if null)
  589. if (p == root)
  590. root = q;
  591. else
  592. setParentsChildLink (p, q);
  593.  
  594. q.setParent (p.getParent ());
  595. q.setRight (p.getRight ());
  596. q.getRight ().setParent (q);
  597. r = q;
  598. }
  599. else
  600. {
  601. q = p.getLeft ();
  602. while (q.getRight () != null)
  603. {
  604. q = q.getRight ();
  605. }
  606. r = q.getParent ();
  607. q.getParent ().setRight (q.getLeft ());
  608.  
  609. if (q.getLeft () != null)
  610. q.getLeft ().setParent (q.getParent ());
  611.  
  612. if (p == root)
  613. root = q;
  614. else
  615. setParentsChildLink (p, q);
  616. q.setParent (p.getParent ());
  617. q.setLeft (p.getLeft ());
  618. p.getLeft ().setParent (q);
  619. q.setRight (p.getRight ());
  620. p.getRight ().setParent (q);
  621. }
  622. }
  623. Tree rTree = new Tree (r);
  624. rTree.updateTreeHeights ();
  625. updateTreeHeightsAbove (r);
  626. balance (r);
  627.  
  628.  
  629. p.setLeft (null); //all four lines are unnecssary -- when method ends, the variable is done
  630. p.setRight (null);
  631. p.setParent (null);
  632. p = null;
  633. }
  634.  
  635. }
  636.  
  637.  
  638. private void updateTreeHeightsAbove (TNode p)
  639. {
  640. if (p != null)
  641. {
  642. for (TNode q = p.getParent () ; q != null ; q = q.getParent ())
  643. {
  644. updateNodeHeight (q);
  645. }
  646. }
  647. }
  648.  
  649.  
  650. public String toString ()
  651. {
  652. if (root == null)
  653. {
  654. return "Empty tree";
  655. }
  656. else
  657. {
  658. return "Root Id: " + root.getIdentification ();
  659. }
  660. }
  661. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement