Advertisement
HimikoWerckmeister

RedBlackTree.cpp

Jul 8th, 2014
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.21 KB | None | 0 0
  1. #include <iostream>
  2. #include "RedBlackTree.h"
  3. using namespace std;
  4.  
  5. /*
  6.     Start of Node constructors
  7. */
  8.  
  9. Node::Node(int Tdata)
  10. {
  11.     data = Tdata;
  12.     parent = NULL;
  13.     left = NULL;
  14.     right = NULL;
  15.     isBlack = false;
  16. }
  17.  
  18. Node::Node(int Tdata, Node* pL, Node *pR, Node* pParent)
  19. {
  20.     data = Tdata;
  21.     parent = pParent;
  22.     left = pL;
  23.     right = pR;
  24.     isBlack = false;
  25. }
  26.  
  27. Node::Node(int Tdata, Node *pL, Node* pR, Node *pParent, bool bColour)
  28. {
  29.     data = Tdata;
  30.     parent = pParent;
  31.     left = pL;
  32.     right = pR;
  33.     parent = pParent;
  34.     isBlack = bColour;
  35. }
  36. Node::Node(int Tdata, Node *pL, Node* pR, bool bColour)
  37. {
  38.     data = Tdata;
  39.     parent = NULL;
  40.     left = pL;
  41.     right = pR;
  42.     isBlack = bColour;
  43. }
  44.  
  45. /*
  46.     End of Node class constructors,
  47.  
  48.     Red Black tree constructor is below, initialzing the root ptr to NULL
  49.    
  50. */
  51. RedBlackTree::RedBlackTree()
  52. {
  53.     root = NULL;
  54. }
  55. /*
  56.     RB Copy constructor which uses an internal helper function to make a deep copy of the tree
  57. */
  58. RedBlackTree::RedBlackTree(const RedBlackTree &rhs)
  59. {
  60.     root = CloneTree(rhs.root);
  61. }
  62.  
  63. /*
  64.     Overloaded assignment operator which returns a pointer to a RB [Red Black] Tree object,
  65.         Logic:
  66.             1. Run alias test
  67.             2. Deallocate memory for calling object
  68.             3. Make deep copy of target
  69.  
  70. */
  71. RedBlackTree & RedBlackTree::operator=(const RedBlackTree &rhs)
  72. {
  73.     if(this != &rhs)
  74.     {
  75.         // deallocate memory for the calling object
  76.        
  77.         removeAll();
  78.         // make a deep copy of its target
  79.         root = CloneTree(rhs.root);
  80.     }
  81.     return *this;
  82.  
  83. }
  84. /*
  85.     Destructor for RB tree,
  86.     uses a helper function to deallocate all nodes allocated on the heap to build the tree
  87. */
  88.  
  89. RedBlackTree::~RedBlackTree()
  90. {
  91.     removeAll();
  92. }
  93.  
  94. /*
  95.     Internal private helper function that gets called by the public insert method
  96.         Takes in a pointer to a node as a parameter
  97.         Returns true if the insert is succesful false if the client attempts to insert duplicate items into the tree
  98.    
  99. */
  100.  
  101. bool RedBlackTree::bInsert(Node* pNode)
  102. {
  103.     Node *y = NULL;
  104.     Node *x = root;
  105.     bool bIns = false; // return value
  106.     bool bFound = false;
  107.     bool bEmpty = false;
  108.     bEmpty = (root == NULL);
  109.     // false to indicate that the value is not already in the tree, true to denote that the value is already there
  110.     if(bPrivSearch(pNode->data, root) == true)
  111.     {
  112.         bIns = false;
  113.         bFound = true;
  114.     }
  115.     if(bFound == false)
  116.     {
  117.         while(x != NULL)
  118.         {
  119.             y = x;
  120.             if(pNode->data < x->data)
  121.             {
  122.                 x = x->left;
  123.  
  124.             }
  125.             else
  126.             {
  127.                 x = x->right;
  128.            
  129.             }
  130.         }  // while loop
  131.         pNode->parent = y;
  132.         if(y == NULL)
  133.         {
  134.             root = pNode;
  135.         }
  136.         else if(pNode->data < y->data)
  137.         {
  138.             y->left = pNode;
  139.         }
  140.             else
  141.         {
  142.             y->right = pNode;
  143.         }
  144.         pNode->left = NULL;
  145.         pNode->right = NULL;
  146.         pNode->isBlack = false;
  147.         vInsertFixViolation(pNode);
  148.         bIns = true;
  149.     }
  150.              
  151.     return bIns;
  152. }
  153.  
  154.    
  155.  
  156.  
  157. /*
  158.     Helper function that allows us to fix any violations that we may have when inserting into the tree
  159.         Returns nothing since the function is void, takes in a node pointer as a parameter
  160.  
  161.         Violations that can occur when inserting a node into an RB tree
  162.             1.  the node's left uncle is red
  163.             2.  the node's uncle is black and the node is a right child
  164.             3.  the node's uncle is black and the node is a left child
  165.             =========================================================
  166.             Symmetric cases
  167.             =========================================================
  168.             4.  the node's right uncle is red
  169.             5.  the node's uncle is black and the node is a left child
  170.             6.  the node's uncle is black and the node is a right child
  171.         How to fix these issues, note case 1,2, and 3 and 4,5,6 are symmetrical siblings
  172.             To fix case one we just perform colour changes by making the node's parent black and its uncle also black
  173.             To fix case two, we just simply make case 2 fall into case 3 since the two cases are not mutually exclusive
  174.                 To enter case 2 via 3 we immediatly perform a left rotation about the node we have just inserted
  175.                 Afterwards we can fix case 3 by performing colour changes and a right rotation about that node's grandparent
  176.            
  177. */
  178.  
  179. void RedBlackTree::vInsertFixViolation(Node *pNode)
  180. {
  181.     Node *y;
  182.     while((pNode != root)&&(pNode->parent->isBlack == false))// start of while
  183.     {
  184.         //start if
  185.         if((pNode->parent != NULL )&&(pNode->parent == pNode->parent->parent->left))
  186.         {
  187.             y = pNode->parent->parent->right; // the right uncle of y
  188.             if((y!=NULL)&&(y->isBlack == false))
  189.             {
  190.                 pNode->parent->isBlack = true;
  191.                 y->isBlack = true;
  192.                 pNode->parent->parent->isBlack = false;
  193.                 pNode = pNode->parent->parent;
  194.             }
  195.             else
  196.             {
  197.                 if(pNode == pNode->parent->right)
  198.                 {
  199.                     pNode = pNode->parent;
  200.                     LeftRotation(pNode);
  201.                 }
  202.                 if(pNode->parent != NULL)
  203.                 {
  204.                     pNode->parent->isBlack = true;
  205.                     if(pNode->parent->parent != NULL)
  206.                     {
  207.                         pNode->parent->parent->isBlack = false;//
  208.                         RightRotation(pNode->parent->parent);
  209.                     }
  210.                    
  211.                 }
  212.                
  213.             }
  214.         }// end if
  215.         else
  216.         {//
  217.         /*start of else*/
  218.             if(pNode->parent == pNode->parent->parent->right)
  219.             {
  220.                 y = pNode->parent->parent->left; // uncle of node pNode on the left side;
  221.                 if((y!= NULL)&&(y->isBlack == false))
  222.                 {
  223.                     pNode->parent->isBlack = true;
  224.                     y->isBlack = true;
  225.                     pNode->parent->parent->isBlack = false;
  226.                     pNode = pNode->parent->parent;
  227.                 }
  228.                 else
  229.                 {
  230.                     if(pNode == pNode->parent->left)
  231.                     {
  232.                         pNode = pNode->parent;
  233.                         RightRotation(pNode);
  234.                     }
  235.                     if(pNode->parent != NULL)
  236.                     {
  237.                         pNode->parent->isBlack = true;
  238.                         if(pNode->parent->parent != NULL)
  239.                         {
  240.                             pNode->parent->parent->isBlack = false;
  241.                             LeftRotation(pNode->parent->parent);
  242.                         }
  243.                     }
  244.                
  245.                 }
  246.             }              
  247.         }// end of else
  248.     }// end of while
  249.     root->isBlack = true;
  250. }
  251. /*
  252.     A private helper function that will enable us to return a pointer to a node in a tree,
  253.     if it doesn't exist we just simply return NULL
  254.     else we keep searching the right or left subtrees as needed until we reach the appropiate spot in the
  255.     tree in which its node countains the appropiate datum that we are trying to find.
  256.     Takes in two parameters: the data we would like to search for and a node pointer indicating where we would
  257.     like to start the recursion
  258.     Return: a pointer to the node indicating where in the tree our data is countained in, if it doesn't exist it simply returns NULL
  259. */
  260.  
  261. Node* RedBlackTree::pSearchPriv(int dataS, Node *pTr)
  262. {
  263.     if(pTr == NULL)
  264.     {
  265.         return NULL;
  266.     }
  267.     else if(dataS < pTr->data)
  268.     {
  269.         return pSearchPriv(dataS,pTr->left);
  270.     }
  271.     else if(pTr->data < dataS)
  272.     {
  273.         return pSearchPriv(dataS,pTr->right);
  274.     }
  275.     else
  276.     {
  277.         return pTr;
  278.     }
  279.  
  280. }
  281. /*
  282.     Public search function:
  283.     Takes in the data we would like to find as a parameter
  284.     Returns true or false depending if we find that specific data or not.
  285. */
  286. bool RedBlackTree::search(int data) const
  287. {
  288.     return bPrivSearch(data,root);
  289. }
  290. /*
  291.     Follows the same structure as the other privateSearch function
  292. */
  293. bool RedBlackTree::bPrivSearch(int dataS, Node *pTr) const
  294. {//
  295.     if((pTr == NULL))
  296.     {
  297.         return false;
  298.     }
  299.     else if(dataS < pTr->data)
  300.     {
  301.         return bPrivSearch(dataS,pTr->left);
  302.     }
  303.     else if(pTr->data < dataS)
  304.     {
  305.         return bPrivSearch(dataS, pTr->right);
  306.     }
  307.     else
  308.     {
  309.         return true;
  310.     }
  311. }
  312.  
  313. void RedBlackTree:: LeftRotation(Node *pNode)
  314. {
  315.     Node *y = pNode->right; // y is pNode's right child
  316.     pNode->right = y->left;
  317.    
  318.     if(y->left != NULL)
  319.     {
  320.         y->left->parent = pNode;
  321.     }
  322.     y->parent = pNode->parent;
  323.     if(pNode->parent == NULL)
  324.     {
  325.         root = y;
  326.     }
  327.     else
  328.     {
  329.         if(pNode == pNode->parent->left)
  330.         {
  331.             pNode->parent->left = y;
  332.         }
  333.         else
  334.         {
  335.             pNode->parent->right = y;
  336.         }
  337.     }
  338.     /*else if (pNode == pNode->parent->left)
  339.     {
  340.         pNode->parent->left = y;
  341.     }
  342.     else
  343.     {
  344.         pNode->parent->right = y;
  345.     }*/
  346.     y->left = pNode;
  347.     pNode->parent = y;
  348. }
  349.  
  350. void RedBlackTree::RightRotation(Node *pNode)
  351. {
  352.     Node *y = pNode->left; // y is pNode's left child
  353.     pNode->left = y->right;
  354.     if(y->right != NULL)
  355.     {
  356.         y->right->parent = pNode;
  357.     }
  358.     y->parent = pNode->parent;
  359.     if(pNode->parent == NULL)
  360.     {
  361.         root = y;
  362.     }
  363.     else
  364.     {
  365.         if(pNode == pNode->parent->right)
  366.         {
  367.             pNode->parent->right = y;
  368.         }
  369.         else
  370.         {
  371.             pNode->parent->left = y;
  372.         }
  373.     }
  374.     /*else if(pNode == pNode->parent->right)
  375.     {
  376.         pNode->parent->right = y;
  377.     }
  378.     else
  379.     {
  380.         pNode->parent->left = y;
  381.     }*/
  382.     y->right = pNode;
  383.     pNode->parent = y;
  384. }
  385.  
  386. // Helper function
  387. void RedBlackTree::PrintRecurse(Node *pTr)
  388. {
  389.     int i = 0;
  390.     if(pTr != NULL)
  391.     {
  392.         //i++;
  393.         PrintRecurse(pTr->left);
  394.         cout << pTr->data << "";
  395.         //i++;
  396.         cout << "[" ;
  397.         if(pTr->isBlack == true)
  398.         {
  399.             cout << "Black" << " ";
  400.         }
  401.         else
  402.         {
  403.             cout << "Red" << " ";
  404.         }
  405.         cout << "]";
  406.         if(pTr->parent != NULL)
  407.         {
  408.             cout<< "(" << "parent is " << pTr->parent->data << ")" <<endl;
  409.         }
  410.         else
  411.         {
  412.             cout << endl;
  413.         }
  414.         PrintRecurse(pTr->right);
  415.         //i++;
  416.        
  417.     }
  418.     return;
  419. }
  420.  
  421. void RedBlackTree::Print()
  422. {
  423.     PrintRecurse(root);
  424. }
  425.  
  426. bool RedBlackTree::insert(int datum)
  427. {
  428.     Node *pNewNode = new Node(datum);
  429.     pNewNode->isBlack = true;
  430.     pNewNode->parent = NULL;
  431.     pNewNode->left = NULL;
  432.     pNewNode->right = NULL;
  433.     return bInsert(pNewNode);
  434. }
  435.  
  436. // Helper function that allows us to find the successor node in the Red-Black tree
  437.  
  438. Node* RedBlackTree::findMinPriv(Node *pNode)
  439. {
  440.     if(pNode == NULL)
  441.     {
  442.         return NULL;
  443.     }
  444.     if(pNode->left == NULL)
  445.     {
  446.         return pNode;
  447.     }
  448.     return findMinPriv(pNode->left);
  449. }
  450.  
  451. int RedBlackTree::findMin()
  452. {
  453.     Node *pTr = findMinPriv(root);
  454.    
  455.     int iMin = 0;
  456.     if(pTr != NULL)
  457.     {
  458.         iMin = pTr->data;
  459.     }
  460.     return iMin;
  461. }
  462.  
  463. bool RedBlackTree::remove(int data)
  464. {
  465.     bool bRmv = false;
  466.     Node* pNodetoRemove = pSearchPriv(data,root);
  467.     if(pNodetoRemove!= NULL)
  468.         bRmv = bRemove(pNodetoRemove);
  469.     else
  470.     {
  471.         bRmv = false;
  472.     }
  473.     return bRmv;
  474. }
  475.  
  476. bool RedBlackTree::bRemove(Node *pNode)
  477. {
  478.     Node *y;
  479.     Node *x;
  480.     bool bYOrigColour = false;
  481.     bool bFound = false;
  482.     bool bDel = false;
  483.  
  484.     if ((pNode != NULL)&&(bPrivSearch(pNode->data,root) == true))
  485.     {
  486.         bDel = false;
  487.         bFound = true;
  488.  
  489.     }
  490. #ifdef _oldcode
  491.     if((pNode != NULL)&&(bFound == true))
  492.     {
  493.  
  494.         if((pNode->left == NULL) || (pNode->right == NULL)) // case of one child
  495.         {
  496.             y = pNode;
  497.         }
  498.         else
  499.         {
  500.             y = findMinPriv(pNode->right); // case that there are two children;
  501.         }
  502.         if(y->left == NULL)
  503.         {
  504.             x = y->right;
  505.         }
  506.         else
  507.         {
  508.             x = y->left;
  509.         }
  510.         if((x!= NULL) && (y!= NULL))
  511.         {
  512.             x->parent = y->parent;
  513.         }
  514.         if(root == (x->parent = y->parent))
  515.         {  
  516.             root->left = x;
  517.         }
  518.         else
  519.         {
  520.             if((y!= NULL) && (y == y->parent->left))
  521.             {
  522.                 y->parent->left = x;
  523.             }
  524.             else
  525.             {
  526.                 if( y != NULL)
  527.                 {
  528.                     y->parent->right = x;
  529.                 }
  530.                
  531.             }
  532.         }
  533.         if((y!= NULL) && (y != pNode))
  534.         {
  535.             y->left = pNode->left;
  536.             y->right = pNode->right;
  537.             y->parent = pNode->parent;
  538.             pNode->left->parent = pNode->right->parent = y;
  539.             if(pNode == pNode->parent->left)
  540.             {
  541.                 pNode->parent->left = y;
  542.             }
  543.             else
  544.             {
  545.                 pNode->parent->right = y;
  546.             }
  547.             if((y!= NULL)&&(y->isBlack == true))
  548.             {
  549.                 y->isBlack = pNode->isBlack;
  550.                 vPrivDeleteFix(x);
  551.  
  552.             }
  553.             else
  554.             {
  555.                 y->isBlack = pNode->isBlack;
  556.  
  557.             }
  558.             delete pNode;
  559.  
  560.         }
  561.         else
  562.         {
  563.             if((y!= NULL)&&(y->isBlack == true))
  564.             {
  565.                 vPrivDeleteFix(x);
  566.                 delete y;
  567.             }
  568.         }
  569.  
  570.     }
  571. #else
  572. #ifdef _oldcode2
  573.   bool bCont = true;
  574.   y= ((pNode->left == NULL) || (pNode->right == NULL)) ? pNode : findMinPriv(pNode->right); // case that z has one or no children else z has two children
  575.   x= (y->left == NULL) ? y->right : y->left;
  576.   if(pNode == root)
  577.   {
  578.       if((pNode->left == NULL) && (pNode->right == NULL))
  579.       {
  580.           delete root;
  581.           root = NULL;
  582.           bCont = false;
  583.       }
  584.   }
  585.   if(bCont)
  586.   {
  587.       // tries to identify if y's only child is right or left
  588.  
  589.      /* if (root == (x->parent = y->parent))*/ //{ /* assignment of y->p to x->p is intentional */
  590.       if(y->parent == NULL)
  591.         root = x;
  592.       } else {
  593.         if (y == y->parent->left) {
  594.           y->parent->left=x;
  595.         } else {
  596.           y->parent->right=x;
  597.         }
  598.       }
  599.       if (y != pNode) { /* y should not be nil in this case */
  600.  
  601.     #ifdef DEBUG_ASSERT
  602.         Assert( (y!=nil),"y is nil in DeleteNode \n");
  603.     #endif
  604.         /* y is the node to splice out and x is its child */
  605.  
  606.         y->left=pNode->left;
  607.         y->right=pNode->right;
  608.         y->parent=pNode->parent;
  609.         pNode->left->parent=pNode->right->parent=y;
  610.         if (pNode == pNode->parent->left) {
  611.           pNode->parent->left=y;
  612.         } else {
  613.           pNode->parent->right=y;
  614.         }
  615.         if ((x!= NULL)&&(y->isBlack == false)) {
  616.             y->isBlack = pNode->isBlack;
  617.           //DeleteFixUp(x);
  618.             vPrivDeleteFix(x);
  619.         } else
  620.           y->isBlack = pNode->isBlack;
  621.         delete pNode;
  622.     #ifdef CHECK_RB_TREE_ASSUMPTIONS
  623.         CheckAssumptions();
  624.     #elif defined(DEBUG_ASSERT)
  625.         Assert(!nil->red,"nil not black in RedBlackTree::Delete");
  626.     #endif
  627.       } else {
  628.         if ((x != NULL)&&(y->isBlack== false)) vPrivDeleteFix(x);
  629.         delete y;
  630.     #ifdef CHECK_RB_TREE_ASSUMPTIONS
  631.         CheckAssumptions();
  632.     #elif defined(DEBUG_ASSERT)
  633.         Assert(!nil->red,"nil not black in RedBlackTree::Delete");
  634.     #endif
  635.       }
  636.   }
  637. #else
  638. #ifdef conceptcode_
  639.     y = ((pNode->left == NULL)) || ((pNode->right == NULL)) ?
  640.     pNode:
  641.     findMinPriv(pNode->right);
  642.     x =  (y->left != NULL)?
  643.     y->left:
  644.     y->right;
  645.     /*if(pNode->left == NULL || pNode->right == NULL)
  646.     {
  647.         y = pNode;
  648.     }
  649.     else
  650.     {
  651.         y = findMinPriv(pNode->right);
  652.     }*/
  653.     /*if(y->left != NULL)
  654.     {
  655.         x = y->left;
  656.     }
  657.     else
  658.     {
  659.         x = y->right;
  660.     }*/
  661.     if(x != NULL)
  662.     {
  663.         x->parent = y->parent;
  664.     }
  665.     if(y->parent == NULL)
  666.     {
  667.         root = x;
  668.     }
  669.     else
  670.     {
  671.         if( y == y->parent->left)
  672.         {
  673.             y->parent->left = x;
  674.         }
  675.         else
  676.         {
  677.             y->parent->right = x;
  678.         }
  679.  
  680.     }
  681.     if( y!= pNode)
  682.     {
  683.         pNode->data = y->data;
  684.     }
  685.     if( (x!= NULL)&& (y->isBlack == true))
  686.     {
  687.         vPrivDeleteFix(x);
  688.     }
  689.     delete y;
  690.     y = NULL;
  691.     bDel = true;
  692. #else
  693. {
  694.     // Case 1: node has no children = remove
  695.     // Case 2: node has 1 children = move right or left, ignore node
  696.     // Case 3: node has 2 children = find the successor and swap content
  697.        Node *y = NULL;
  698.        Node *x = NULL;
  699.        bool   bRoot = false;
  700.  
  701.        if (pNode->left && pNode->right)
  702.              y = findMinPriv (pNode->right);         // get the successor
  703.        else
  704.              y = pNode;
  705.  
  706.        // Case 2, check for right or left node
  707.        if(y->left != NULL)
  708.              x = y->left;
  709.        else
  710.              x = y->right;
  711.  
  712.        // Case 1 & 2: ignore node
  713.        // Case 3: ignore successor
  714.        if(x != NULL)
  715.              x->parent = y->parent;
  716.  
  717.        if(y->parent == NULL)
  718.        {
  719.              // this means this is the root node DELETION!!
  720.              root = y;
  721.              bRoot = true;
  722.        }
  723.        else
  724.        {
  725.              // now change the y's parent node left & right pointers
  726.              if( y == y->parent->left)
  727.              {
  728.                     // y is the left node of parent then
  729.                     y->parent->left = x;
  730.              }
  731.              else
  732.                     y->parent->right = x;
  733.        }
  734.  
  735.        // Case 1 & Case 2: y is always equal to node
  736.        // Case 3: y = successor(node)
  737.        // Case 3: pending thing, swap content between node & y
  738.        if (y != pNode)
  739.        {
  740.              pNode->data = y->data;
  741.              // we can ignore left, right, parent
  742.              // as successor is greater than left and lesser than right
  743.        }
  744.         /*
  745.             This is to ensure that our delete fix-up private function gets called
  746.         */
  747.        if (y->isBlack && !bRoot)
  748.        {
  749.              if (x && x->parent)
  750.                     vPrivDeleteFix(x->parent);
  751.              else if (pNode->parent->parent)
  752.                     vPrivDeleteFix(pNode->parent->parent);
  753.              else
  754.                     vPrivDeleteFix(pNode->parent);
  755.        }
  756.  
  757.        delete (y);
  758.  
  759.        // Reset the root to NULL if indeed the real root node has been deleted:
  760.        if (bRoot)
  761.              root = NULL;
  762.  
  763.        return (true);
  764. }
  765. #endif
  766. #endif
  767. #endif
  768.     return bDel;
  769. }
  770.  
  771.  
  772. void RedBlackTree::vPrivDeleteFix(Node *pNode)
  773. {
  774.     //Node *rootChild = root->left;
  775.     Node *w; // pointer to allow us to find pNode's sibling which will take y's place in the tree
  776.     while(((pNode != root)) && ((pNode!= NULL))&&((pNode->isBlack == true)))
  777.     {
  778.         if(pNode == pNode->parent->left)
  779.         {
  780.             w = pNode->parent->right;
  781.             if((w!= NULL)&&(w->isBlack == false))// case 1
  782.             {
  783.                 w->isBlack = true;
  784.                 pNode->parent->isBlack = false;
  785.                 LeftRotation(pNode->parent);
  786.                 w = pNode->parent->right;
  787.             }
  788.             if((w != NULL)&&(w->left->isBlack == true) && (w->right->isBlack == true))
  789.             {
  790.                 w->isBlack = false;
  791.                 pNode = pNode->parent;
  792.             }
  793.             else
  794.             {
  795.                 if((w != NULL)&&(w->right->isBlack == true))
  796.                 {
  797.                     w->left->isBlack = true;
  798.                     w->isBlack = false;
  799.                     RightRotation(w);
  800.                     w = pNode->parent->right;
  801.                 }
  802.                 if((w!= NULL) && (pNode->parent != NULL))
  803.                 {
  804.                     w->isBlack = pNode->parent->isBlack;
  805.                 }
  806.                 if(pNode->parent != NULL)
  807.                 {
  808.                     pNode->parent->isBlack = true;
  809.                 }
  810.                 if( (w != NULL) && (w->right != NULL))
  811.                 {
  812.                     w->right->isBlack = true;
  813.                 }
  814.                 if(pNode->parent != NULL)
  815.                 {
  816.                     LeftRotation(pNode->parent);
  817.                 }
  818.                 pNode = root;
  819.             }
  820.         }
  821.         else
  822.         {
  823.             if(pNode == pNode->parent->right)
  824.             {
  825.                 w = pNode->parent->left;
  826.                 if( (w!= NULL) && (w->isBlack == false))
  827.                 {
  828.                     w->isBlack = true;
  829.                     pNode->parent->isBlack = false;
  830.                     if(pNode->parent != NULL)
  831.                     {
  832.                         RightRotation(pNode->parent);
  833.                         w = pNode->parent->left;
  834.                     }
  835.                    
  836.                 }
  837.                 if( (w != NULL) && (w->right->isBlack == true) && (w->left->isBlack == true))
  838.                 {
  839.                     w->isBlack = false;
  840.                     pNode = pNode->parent;
  841.                 }
  842.                 else
  843.                 {
  844.                     if((w != NULL)&&(w->left->isBlack == true))
  845.                     {
  846.                         w->right->isBlack = true;
  847.                         w->isBlack = false;
  848.                         LeftRotation(w);
  849.                         w = pNode->left;
  850.                     }
  851.                     if((w!= NULL) && (pNode->parent != NULL))
  852.                     {
  853.                         w->isBlack = pNode->parent->isBlack;
  854.                     }
  855.                     if(pNode->parent != NULL)
  856.                     {
  857.                         pNode->parent->isBlack = true;
  858.                     }
  859.                     if( (w != NULL) && (w->left != NULL))
  860.                     {
  861.                         w->left->isBlack = true;
  862.                     }
  863.                     if(pNode->parent != NULL)
  864.                     {
  865.                         RightRotation(pNode->parent);
  866.                     }
  867.                     pNode = root;
  868.                 }
  869.             }
  870.         }
  871.     }
  872.     if(pNode != NULL)
  873.     {
  874.         pNode->isBlack = true;
  875.     }
  876.      
  877. }
  878.  
  879. void RedBlackTree::TransplantRB(Node *pNodeU, Node *pNodeV)
  880. {
  881.     if(pNodeU->parent == NULL)
  882.     {
  883.         root = pNodeV;
  884.     }
  885.     else if(pNodeU == pNodeU->parent->left)
  886.     {
  887.         pNodeU->parent->left = pNodeV;
  888.     }
  889.     else
  890.     {
  891.         pNodeU->parent->right = pNodeV;
  892.     }
  893.     if(pNodeV != NULL)
  894.     {
  895.         pNodeV->parent = pNodeU->parent;
  896.     }
  897.      
  898. }
  899.  
  900. int RedBlackTree:: heightHelper(Node *pNode) const
  901. {
  902.     int iHeight = 0;
  903.     if(pNode == NULL)
  904.     {
  905.         iHeight = 0;
  906.     }
  907.     else
  908.     {
  909.         iHeight = 1+ max(heightHelper(pNode->right),heightHelper(pNode->left));
  910.     }
  911.     return iHeight;
  912. }
  913.  
  914. int RedBlackTree::sizeHelper(Node *pNode) const
  915. {
  916.     if(pNode == NULL)
  917.     {
  918.         return 0;
  919.     }
  920.     else
  921.     {
  922.         return (sizeHelper(pNode->left)+ sizeHelper(pNode->right))+1;
  923.     }
  924. }
  925.  
  926. int RedBlackTree::height() const
  927. {
  928.     return heightHelper(root);
  929. }
  930.  
  931. int RedBlackTree::size() const
  932. {
  933.      return sizeHelper(root);
  934. }
  935.  
  936. void RedBlackTree:: DeleteTreePrivate(Node* pNode)
  937. {
  938.     if(pNode != NULL)
  939.     {
  940.         DeleteTreePrivate(pNode->left);
  941.         DeleteTreePrivate(pNode->right);
  942.         delete pNode;
  943.     }
  944.     pNode = NULL;
  945. }
  946.  
  947. void RedBlackTree::removeAll()
  948. {
  949.     DeleteTreePrivate(root);
  950. }
  951.  
  952. Node *RedBlackTree::CloneTree(const Node* pTr)
  953. {
  954.     Node *pNewRB = NULL;
  955.     if(pTr != NULL)
  956.     {
  957.         pNewRB = new Node(pTr->data,NULL,NULL, NULL,pTr->isBlack);
  958.         pNewRB->left = CloneTree(pTr->left);
  959.         pNewRB->right = CloneTree(pTr->right);
  960.  
  961.     }
  962.     return pNewRB;
  963.  
  964. }
  965.  
  966. Node* RedBlackTree:: getRoot()
  967. {
  968.     return root;
  969. }
  970.  
  971. int* RedBlackTree::dump(int& iSize)
  972. {
  973.     //int iStart = 0;
  974.     return dumpPrivate(root,iSize);
  975. }
  976.  
  977. int *RedBlackTree::dumpPrivate(Node *pNode, int& iSize)
  978. {
  979.     int iNumElements = size();
  980.     int *pNewArr = new int[iNumElements];
  981.     int iStart = 0;
  982.     int iData = 0;
  983.     if(pNode != NULL)
  984.     {
  985.         //iSize++;
  986.         iStart++;
  987.         dumpPrivate(pNode->left,iSize);
  988.         //iData = pNode->data;
  989.         // stuck on where to put the incrementer
  990.         pNewArr[iSize] = pNode->data;
  991.         iSize++;
  992.         dumpPrivate(pNode->right,iSize);
  993.         //iSize++;
  994.     }  
  995.        
  996.     return pNewArr;
  997. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement