Advertisement
Guest User

Untitled

a guest
Mar 1st, 2015
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.93 KB | None | 0 0
  1. #include <fstream>
  2. #include <iostream>
  3. #include <ctime>
  4.  
  5.  
  6. const int C_NULL = -1;
  7.  
  8. struct node
  9. {
  10. node ( ) : value ( C_NULL ), left ( C_NULL ), right ( C_NULL ),
  11. height ( C_NULL ), parent ( C_NULL ), location ( C_NULL ) { };
  12.  
  13. node ( int v, int l, int r, int h, int p, int loc )
  14. : value ( v ), left ( l ), right ( r ),
  15. height ( h ), parent ( p ), location ( loc ) { };
  16.  
  17. node ( std::fstream & file, const int loc ) { read ( file, loc ); };
  18.  
  19. int value, left, right, height, parent, location;
  20.  
  21. void read ( std::fstream & file, const int loc );
  22.  
  23. void write ( std::fstream & file );
  24.  
  25. void print ( )
  26. {
  27. std::cout.width ( 10 );
  28. std::cout << value;
  29. std::cout.width ( 10 );
  30. std::cout << left;
  31. std::cout.width ( 10 );
  32. std::cout << right;
  33. std::cout.width ( 10 );
  34. std::cout << parent;
  35. std::cout.width ( 10 );
  36. std::cout << height;
  37. std::cout.width ( 10 );
  38. std::cout << location << 'n';
  39. }
  40. };
  41.  
  42. const int C_NODE_SIZE = sizeof ( node );
  43.  
  44. void node::read ( std::fstream & file, const int loc )
  45. {
  46. if ( loc != C_NULL )
  47. {
  48. file.seekg ( loc * C_NODE_SIZE );
  49.  
  50. file.read ( (char*) this, C_NODE_SIZE );
  51. }
  52.  
  53. else * this = node ( );
  54. }
  55.  
  56. void node::write ( std::fstream & file )
  57. {
  58. if ( location != C_NULL )
  59. {
  60. file.seekp ( location * C_NODE_SIZE );
  61.  
  62. file.write ( (char*) this, C_NODE_SIZE );
  63. }
  64. }
  65.  
  66.  
  67. node seedTree ( std::ifstream & input, std::fstream & output );
  68.  
  69. bool insertValue ( std::fstream & file, const int value, const int numNodes, node & root, node & newNode );
  70.  
  71. void UpdateHeightAndCheckBalance ( std::fstream & file, node & parent, node & child, const int height );
  72.  
  73. void rebalanceLeft ( std::fstream & file, node & left, node & parent, const node & right );
  74.  
  75. void rebalanceRight ( std::fstream & file, const node & left, node & parent, node & right );
  76.  
  77. void fixRootLocation ( std::fstream & file, node & root );
  78.  
  79. void getSelectValues ( std::fstream & file, int & smallest, int & biggest );
  80.  
  81. void printNodes ( std::fstream & file );
  82.  
  83.  
  84. int main ( int argc, char * argv[] )
  85. {
  86. if ( argc < 3 ) return 0;
  87.  
  88.  
  89. std::ifstream input ( argv[1] );
  90.  
  91. std::fstream output ( argv[2], std::fstream::in | std::fstream::out |
  92. std::fstream::trunc | std::fstream::binary );
  93.  
  94.  
  95. if ( !input || !output ) return 0; // file open fail
  96.  
  97.  
  98. // insert first two numbers to get things started
  99. node root = seedTree ( input, output ), child;
  100.  
  101.  
  102. if ( root.height > 0 )
  103. {
  104. int value, nodes = root.height + 1;
  105.  
  106.  
  107. while ( input >> value )
  108. {
  109. if ( insertValue ( output, value, nodes++, root, child ) )
  110. UpdateHeightAndCheckBalance ( output, root, child, 2 );
  111.  
  112. fixRootLocation ( output, root );
  113. }
  114. }
  115.  
  116.  
  117. int smallest, biggest;
  118.  
  119. getSelectValues ( output, smallest, biggest );
  120.  
  121. std::cout << "Height: " << root.height
  122. << "nRoot Value: " << root.value
  123. << "nSmallest Leaf Value: " << smallest
  124. << "nBiggest Leaf Value: " << biggest
  125. << "nTime: " << clock ( ) / CLOCKS_PER_SEC;
  126.  
  127. printNodes ( output );
  128.  
  129. std::cin.ignore ( );
  130. }
  131.  
  132.  
  133. node seedTree ( std::ifstream & input, std::fstream & output )
  134. {
  135. node root ( C_NULL, C_NULL, C_NULL, 0, C_NULL, 0 );
  136.  
  137. input >> root.value;
  138.  
  139.  
  140. if ( input ) // if there is at least one number in the file
  141. {
  142. node child ( C_NULL, C_NULL, C_NULL, 0, 0, 1 );
  143.  
  144. input >> child.value;
  145.  
  146.  
  147. if ( input ) // if there is a second number
  148. {
  149. root.height = 1;
  150.  
  151.  
  152. if ( root.value < child.value ) // second = right child of first
  153. root.right = 1;
  154.  
  155. else // second = left child of first
  156. root.left = 1;
  157.  
  158.  
  159. child.write ( output );
  160. }
  161.  
  162.  
  163. root.write ( output );
  164. }
  165.  
  166.  
  167. return root;
  168. }
  169.  
  170.  
  171. bool insertValue ( std::fstream & file, const int value, const int numNodes, node & root, node & newNode )
  172. {
  173. newNode = node ( value, C_NULL, C_NULL, 0, C_NULL, numNodes );
  174.  
  175. bool balanceIssue = true;
  176.  
  177.  
  178. while ( true )
  179. {
  180. if ( root.value < newNode.value ) // move right
  181. {
  182. if ( root.right == C_NULL ) // write new node
  183. {
  184. if ( root.height == 0 ) root.height = 1;
  185.  
  186. else balanceIssue = false; // if the parent height isn't updated, the tree will not become unbalanced
  187.  
  188. root.right = numNodes;
  189.  
  190. root.write ( file );
  191.  
  192.  
  193. newNode.parent = root.location;
  194.  
  195. newNode.write ( file );
  196.  
  197.  
  198. break;
  199. }
  200.  
  201. else root.read ( file, root.right ); // move down tree
  202. }
  203.  
  204. else // move left
  205. {
  206. if ( root.left == C_NULL ) // write new node
  207. {
  208. if ( root.height == 0 ) root.height = 1;
  209.  
  210. else balanceIssue = false; // if the parent height isn't updated, the tree will not become unbalanced
  211.  
  212. root.left = numNodes;
  213.  
  214. root.write ( file );
  215.  
  216.  
  217. newNode.parent = root.location;
  218.  
  219. newNode.write ( file );
  220.  
  221.  
  222. break;
  223. }
  224.  
  225. else root.read ( file, root.left ); // move down tree
  226. }
  227. }
  228.  
  229.  
  230. if ( balanceIssue )
  231. {
  232. newNode = root;
  233.  
  234. root.read ( file, root.parent );
  235. }
  236.  
  237. return balanceIssue;
  238. }
  239.  
  240. void UpdateHeightAndCheckBalance ( std::fstream & file, node & parent, node & child, const int height )
  241. {
  242. if ( parent.height < height )
  243. {
  244. parent.height = height; // update parent height
  245.  
  246. parent.write ( file ); // write parent to file
  247. }
  248.  
  249. else return;
  250.  
  251.  
  252. { // check balance
  253. node left, right;
  254.  
  255. if ( parent.left == child.location )
  256. {
  257. left = child;
  258.  
  259. right.read ( file, parent.right );
  260. }
  261.  
  262. else
  263. {
  264. left.read ( file, parent.left );
  265.  
  266. right = child;
  267. }
  268.  
  269.  
  270. const int balance = left.height - right.height;
  271.  
  272.  
  273. if ( balance > 1 ) // left heavy
  274. return rebalanceLeft ( file, left, parent, right );
  275.  
  276. else if ( balance < -1 ) // right heavy
  277. return rebalanceRight ( file, left, parent, right );
  278. }
  279.  
  280.  
  281. if ( parent.parent == C_NULL ) return;
  282.  
  283.  
  284. child = parent;
  285.  
  286. parent.read ( file, parent.parent );
  287.  
  288. UpdateHeightAndCheckBalance ( file, parent, child, height + 1 );
  289. }
  290.  
  291.  
  292. void rebalanceLeft ( std::fstream & file, node & left, node & parent, const node & right )
  293. {
  294. node grandparent ( file, parent.parent );
  295.  
  296. const node leftleft ( file, left.left );
  297.  
  298. node leftright ( file, left.right );
  299.  
  300.  
  301. if ( node ( file, left.left ).height < leftright.height ) // left right case
  302. {
  303. if ( grandparent.left == parent.location )
  304. grandparent.left = leftright.location;
  305.  
  306. else grandparent.right = leftright.location;
  307.  
  308.  
  309. parent.parent = leftright.location;
  310.  
  311. parent.left = leftright.right;
  312.  
  313.  
  314. left.parent = leftright.location;
  315.  
  316. left.right = leftright.left;
  317.  
  318.  
  319. leftright.parent = grandparent.location;
  320.  
  321. leftright.left = left.location;
  322.  
  323. leftright.right = parent.location;
  324.  
  325.  
  326.  
  327. { // set 'left' height and left.right.parent
  328. node newleftright ( file, left.right );
  329.  
  330. newleftright.parent = left.location;
  331.  
  332. newleftright.write ( file );
  333.  
  334. if ( leftleft.height > newleftright.height ) left.height = leftleft.height + 1;
  335.  
  336. else left.height = newleftright.height + 1;
  337. }
  338.  
  339. { // set 'parent' height and parent.left.parent
  340. node newrightleft ( file, parent.left );
  341.  
  342. newrightleft.parent = parent.location;
  343.  
  344. newrightleft.write ( file );
  345.  
  346. if ( newrightleft.height > right.height ) parent.height = newrightleft.height + 1;
  347.  
  348. else parent.height = right.height + 1;
  349. }
  350.  
  351.  
  352. if ( left.height < parent.height ) leftright.height = parent.height + 1;
  353.  
  354. else leftright.height = left.height + 1;
  355. }
  356.  
  357. else // left left case
  358. {
  359. if ( grandparent.left == parent.location )
  360. grandparent.left = left.location;
  361.  
  362. else grandparent.right = left.location;
  363.  
  364.  
  365. parent.parent = left.location;
  366.  
  367. parent.left = left.right;
  368.  
  369.  
  370. left.parent = grandparent.location;
  371.  
  372. left.right = parent.left;
  373.  
  374.  
  375. leftright.parent = parent.location;
  376.  
  377.  
  378. // set 'parent' height
  379. if ( leftright.height > right.height ) parent.height = leftright.height + 1;
  380. else parent.height = right.height + 1;
  381.  
  382. // set 'left' height
  383. if ( leftleft.height > parent.height ) left.height = leftleft.height + 1;
  384. else left.height = parent.height + 1;
  385. }
  386.  
  387.  
  388. grandparent.write ( file );
  389.  
  390. parent.write ( file );
  391.  
  392. left.write ( file );
  393.  
  394. leftright.write ( file );
  395. }
  396.  
  397. void rebalanceRight ( std::fstream & file, const node & left, node & parent, node & right )
  398. {
  399. node grandparent ( file, parent.parent );
  400.  
  401. node rightleft ( file, right.left );
  402.  
  403. const node rightright ( file, right.right );
  404.  
  405.  
  406. if ( rightleft.height > node ( file, right.right ).height ) // right left case
  407. {
  408. if ( grandparent.left == parent.location )
  409. grandparent.left = rightleft.location;
  410.  
  411. else grandparent.right = rightleft.location;
  412.  
  413.  
  414. parent.parent = rightleft.location;
  415.  
  416. parent.right = rightleft.left;
  417.  
  418.  
  419. right.parent = rightleft.location;
  420.  
  421. right.left = rightleft.right;
  422.  
  423.  
  424. rightleft.parent = grandparent.location;
  425.  
  426. rightleft.left = parent.location;
  427.  
  428. rightleft.right = right.location;
  429.  
  430.  
  431. { // set 'parent' height and parent.right.parent
  432. node newleftright ( file, parent.right );
  433.  
  434. newleftright.parent = parent.location;
  435.  
  436. newleftright.write ( file );
  437.  
  438. if ( left.height > newleftright.height ) parent.height = left.height + 1;
  439.  
  440. else parent.height = newleftright.height + 1;
  441. }
  442.  
  443. { // set 'right' height and right.left.parent
  444. node newrightleft ( file, right.left );
  445.  
  446. newrightleft.parent = right.location;
  447.  
  448. newrightleft.write ( file );
  449.  
  450. if ( newrightleft.height > rightright.height ) right.height = newrightleft.height + 1;
  451.  
  452. else right.height = rightright.height + 1;
  453. }
  454.  
  455.  
  456. if ( parent.height < right.height ) rightleft.height = right.height + 1;
  457.  
  458. else rightleft.height = parent.height + 1;
  459. }
  460.  
  461. else // right right case
  462. {
  463. if ( grandparent.left == parent.location )
  464. grandparent.left = right.location;
  465.  
  466. else grandparent.right = right.location;
  467.  
  468.  
  469. parent.parent = right.location;
  470.  
  471. parent.right = right.left;
  472.  
  473.  
  474. right.parent = grandparent.location;
  475.  
  476. right.left = parent.location;
  477.  
  478.  
  479. rightleft.parent = parent.location;
  480.  
  481.  
  482. // set 'parent' height
  483. if ( left.height > rightleft.height ) parent.height = left.height + 1;
  484. else parent.height = rightleft.height + 1;
  485.  
  486. // set 'right' height
  487. if ( parent.height > rightright.height ) right.height = parent.height + 1;
  488. else right.height = rightright.height + 1;
  489. }
  490.  
  491.  
  492. grandparent.write ( file );
  493.  
  494. parent.write ( file );
  495.  
  496. right.write ( file );
  497.  
  498. rightleft.write ( file );
  499. }
  500.  
  501.  
  502. void fixRootLocation ( std::fstream & file, node & root )
  503. {
  504. root.read ( file, 0 );
  505.  
  506.  
  507. if ( root.parent != C_NULL )
  508. {
  509. node newRoot ( file, root.parent );
  510.  
  511. root.location = newRoot.location;
  512.  
  513. newRoot.location = 0;
  514.  
  515. root.parent = 0;
  516.  
  517. if ( newRoot.left == 0 )
  518. {
  519. newRoot.left = root.location;
  520.  
  521. node temp ( file, newRoot.right );
  522.  
  523. temp.parent = 0;
  524.  
  525. temp.write ( file );
  526. }
  527.  
  528. else
  529. {
  530. newRoot.right = root.location;
  531.  
  532. node temp ( file, newRoot.left );
  533.  
  534. temp.parent = 0;
  535.  
  536. temp.write ( file );
  537. }
  538.  
  539. root.write ( file );
  540.  
  541. newRoot.write ( file );
  542.  
  543.  
  544. if ( root.left != C_NULL )
  545. {
  546. node temp ( file, root.left );
  547.  
  548. temp.parent = root.location;
  549.  
  550. temp.write ( file );
  551. }
  552.  
  553. if ( root.right != C_NULL )
  554. {
  555. node temp ( file, root.right );
  556.  
  557. temp.parent = root.location;
  558.  
  559. temp.write ( file );
  560. }
  561.  
  562.  
  563. root = newRoot;
  564. }
  565. }
  566.  
  567.  
  568. void getSelectValues ( std::fstream & file, int & smallest, int & biggest )
  569. {
  570. // set starting values
  571. smallest = INT_MAX;
  572. biggest = INT_MIN;
  573.  
  574.  
  575. file.seekg ( 0, std::fstream::end ); // seek to end of file
  576.  
  577. int fSize = int ( file.tellg ( ) ); // get file size
  578.  
  579.  
  580. if ( fSize > C_NODE_SIZE ) // check that file has more than one node
  581. {
  582. node temp ( file, 1 ); // start at first node after root
  583.  
  584.  
  585. while ( file.tellg ( ) < fSize )
  586. {
  587. temp.read ( file, int ( file.tellg ( ) ) / C_NODE_SIZE );
  588.  
  589.  
  590. if ( temp.height == 0 )
  591. {
  592. if ( temp.value < smallest ) smallest = temp.value;
  593.  
  594. if ( temp.value > biggest ) biggest = temp.value;
  595. }
  596. }
  597. }
  598.  
  599. else
  600. {
  601. node root ( file, 0 );
  602.  
  603. smallest = root.value;
  604.  
  605. biggest = root.value;
  606. }
  607. }
  608.  
  609.  
  610. void printNodes ( std::fstream & file )
  611. {
  612. // print header
  613. std::cout << 'n';
  614. std::cout.width ( 10 );
  615. std::cout << "Value";
  616. std::cout.width ( 10 );
  617. std::cout << "Left";
  618. std::cout.width ( 10 );
  619. std::cout << "Right";
  620. std::cout.width ( 10 );
  621. std::cout << "Parent";
  622. std::cout.width ( 10 );
  623. std::cout << "Height";
  624. std::cout.width ( 10 );
  625. std::cout << "Location" << 'n';
  626.  
  627.  
  628. file.seekg ( 0, std::ios_base::end ); // seek to end of file
  629.  
  630. int fSize = int ( file.tellg ( ) ); // get file size
  631.  
  632. file.seekg ( 0 ); // seek to start of file
  633.  
  634. // print nodes
  635. while ( file.tellg ( ) < fSize ) node ( file, int ( file.tellg ( ) ) / C_NODE_SIZE ).print ( );
  636. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement