I was a little dizzy when I looked at the introduction to algorithms. The Code indentation made me crazy. I found a more reliable solution on the Internet.
The insert operation is analyzed as follows:
1. First, if the father's day node is a black node, it does not need to be processed. A red node does not have any impact.
2. If the Father's Day is red and the uncle node is red, the father and uncle nodes are changed to black at the same time, the grandfather is changed to red, and then recursively passed up.
3. If the Father's Day is red, and the uncle node is black, the back part will be a bit harsh. The father is the grandfather's left child.
(1) If you are the father's left
Child, change father to black, grandfather to red, then turn grandfather
(2) If you are the father's right
Child, point yourself to your father first, then turn yourself left, and execute (1 ).
4. If the father is a grandfather's right child
(1) If you are the father's right
Child, then change father to black, grandfather to red, then turn left grandfather
(2) If you are the father's left
Child, point yourself to your father first, then turn yourself right, and execute (1 ).
(From above
The preceding webpage is modified based on the code in the webpage ).
The corresponding code is as follows:
Template <class T> <br/> void rbtree <t>: rbinsert (rbtreenode <t> * node) <br/> {<br/> rbtreenode <t> * Y = rbtreenode <t>: nil, <br/> * x = root; <br/> while (X! = Rbtreenode <t >:: nil) <br/>{< br/> Y = x; <br/> If (Y-> value = node-> value) <br/> return; <br/> If (Y-> value> node-> value) <br/> X = x-> left; <br/> else x = x-> right; <br/>}< br/> node-> father = y; <br/> If (y = rbtreenode <t>: nil) // The node is root. <br/> root = node; <br/> else if (node-> value <Y-> value) // left child <br/> Y-> left = node; <br/> else y-> right = node; <br/> node-> left = node-> right = rbtreenode <t >:: nil; <br /> Node-> color = Red; <br/> rbinsertfixup (node ); <br/>}< br/> template <class T> <br/> void rbtree <t>: rbinsertfixup (rbtreenode <t> * node) <br/>{< br/> while (node! = Root & node-> father-> color = red) <br/> {<br/> rbtreenode <t> * puncle = getuncle (node ), <br/> * pgrandfather = getgrandfather (node); <br/> If (puncle! = Rbtreenode <t >:: nil & puncle-> color = red) <br/>{< br/> node-> father-> color = black; <br/> puncle-> color = black; <br/> pgrandfather-> color = Red; <br/> node = pgrandfather; <br/>}< br/> else <br/> {// if Uncle = black <br/> If (node-> father = pgrandfather-> left) <br/> {// father is left child <br/> If (node = node-> father-> right) <br/> {// right child <br/> node = node-> father; <br/> leftrotate (node ); <br/>}< br/> node-> father-> color = black; <br/> pgrandfather-> color = Red; <br/> rightrotate (pgrandfather ); <br/>}< br/> else <br/> {// father is right child <br/> If (node = node-> father-> left) <br/> {// left child <br/> node = node-> father; <br/> rightrotate (node ); <br/>}< br/> node-> father-> color = black; <br/> pgrandfather-> color = Red; <br/> leftrotate (pgrandfather ); <br/>}< br/> root-> color = black; <br/>}
Now let's take a look at the delete operation of the red/black tree:
Now, let's take a look at the subsequent operations on node X in the tree:
1. If X contains the right child, the minimum value of the right child is returned (the left branch of the right child is continuously traversed)
2. If there is no right child, set the parent node of X to Y. If X is the left child of Y, return y directly.
3. If X is the right child of Y, iteration {x = y; y = Y-> father;} until y is null or X is the right child of Y.
The Code is as follows:
Template <class T> <br/> const treenode <t> * tree <t>: treesuccessor (const treenode <t> * const node) <br/>{< br/> If (! Node) <br/> return NULL; <br/> If (node-> right) <br/>{< br/> treenode <t> * minnode = node; <br/> while (minnode-> left) <br/> minnode = minnode-> left; <br/> return minnode; <br/>}< br/> treenode <t> * temp = node-> father; <br/> const treenode <t> * tempf = node; <br/> while (temp & tempf = temp-> right) <br/>{< br/> tempf = temp; <br/> temp = temp-> father; <br/>}< br/> return temp; <br/>}
In addition, it is easy to prove the theorem of having no left child after the node of a binary tree node:
Proof Method:
Assume that the successor of node has left sub-left:
1. If node. value <left. Value
The node is followed by left instead of successor.
2. If node. value> left. Value
Left cannot be the left subtree of successor (because if left value is smaller than node, left must be in the left subtree of node, and the successor of node must be greater than node, it must not be in the left subtree of node)
Conflict. Therefore, the theorem is true.
Now let's analyze the delete operation of the red/black tree. For the sake of simplicity, F indicates the parent node, s indicates the sibling node, and X indicates the current node:
1. If X is not the root and X is black, run 2. Otherwise, run 6.
2. If X is the right child, execute 5. otherwise:
If S is black, execute 3. otherwise:
Set S to black, F to red, left-hand F, and update s to the right child of F.
3. If both the child of S are black, set S to red, update X to F, and execute 1;
Otherwise, execute 4.
4. There are two situations:
4.1 If the right child of S is black, the left child of S is also black, S is red, and S is updated to the right child of F; otherwise, 4.2 is executed directly.
Set 4.2 s to F, F to black, s to black, left f, x to root, and execute 6
5. symmetric with 2-4. You only need to change left to right.
6. set X to Black (X to the root or X to red)
In fact, deleting a red node does not affect the red and black properties of the tree. However, deleting a black node affects the following three points:
1 is of the same black and high nature
2 If X is deleted, and X's child and father are both red, it violates the red node and can only have black children.
3. If X has only one red child, X is the root. Deleting X will destroy the black nature of the root.
According to the above discussion, check the children of the deleted node.
All the code is as follows:
# Ifndef hit_rb_tree <br/> # define hit_rb_tree <br/> Using STD: cout; <br/> Using STD: Endl; <br/> namespace hitrb_tree <br/> {<br/> Enum color {black = 0, red}; <br/> // Enum void {succeed = 0, notfound, nullnode, duplicatenode }; <br/> template <class T> <br/> struct rbtreenode <br/>{< br/> T value; <br/> rbtreenode <t> * father; <br/> rbtreenode <t> * left; <br/> rbtreenode <t> * right; <br/> color; </P> <p> rbtreenode (): Value (static_cast <t> (0), Father (null), left (null), right (null), <br/> color (black) {}< br/> rbtreenode (T Va, rbtreenode <t> * f = NULL, rbtreenode <t> * l = NULL, <br/> rbtreenode <t> * r = NULL, color Col = black) <br/>: Value (VA), Father (F), left (L ), right (R), color (COL) {}< br/> }; <br/> template <class T> <br/> class rbtree <br/> {<br/> Public: <br/> rbtree () <br/>{< br/> pguard = new rbtreenode <t>; <br/> pguard-> father = PG Uard-> left = pguard-> right = pguard; <br/> root = pguard; <br/>}< br/> ~ Rbtree () <br/>{< br/> distroytree (Root); <br/> Delete pguard; <br/> pguard = NULL; <br/>}< br/> void rbinsert (rbtreenode <t> * node); <br/> void rbinsert (const T & VA ); <br/> void remove (const T & VA); <br/> void remove (rbtreenode <t> * pnode ); <br/> rbtreenode <t> * rbsearch (const T &); <br/> void distroytree (rbtreenode <t> * pnode ); <br/> const rbtreenode <t> * successor (const rbtreenode <t> * node); <br/> const rbtreenode <t> * Maxnode (const rbtreenode <t> * node); <br/> const rbtreenode <t> * const getguardnode () const {return pguard;} <br/> protected: <br/> PRIVATE: <br/> void leftrotate (rbtreenode <t> * node); <br/> void rightrotate (rbtreenode <t> * node ); <br/> void rbinsertfixup (rbtreenode <t> * node); <br/> void rbremovefixup (rbtreenode <t> * pnode ); <br/> rbtreenode <t> * newnode (const T & Value) <br/>{< br/> rbtreenode <t> * pnode = <br/> New Rbtreenode <t> (value, pguard); <br/> return pnode; <br/>}</P> <p> rbtreenode <t> * getgrandfather (const rbtreenode <t> * node) const <br/>{< br/> If (node! = Pguard & node-> father! = Pguard) <br/> return node-> father; <br/> else return pguard; <br/>}< br/> rbtreenode <t> * getuncle (const rbtreenode <t> * node) const <br/>{< br/> rbtreenode <t> * ptemp = getgrandfather (node); <br/> If (ptemp = pguard) <br/> return pguard; <br/> If (node-> father = ptemp-> left) <br/> return ptemp-> right; <br/> else return ptemp-> left; <br/>}< br/> rbtreenode <t> * getsibling (const rbtreenode <t> * node) const <br />{< Br/> If (node = node-> father-> left) <br/> return node-> father-> right; <br/> else return node-> father-> left; <br/>}< br/> rbtreenode <t> * root; <br/> rbtreenode <t> * pguard; <br/> }; <br/> // Function Definition <br/> template <class T> <br/> void rbtree <t>: distroytree (rbtreenode <t> * pnode) <br/>{< br/> If (pnode! = Pguard) <br/>{< br/> distroytree (pnode-> left); <br/> distroytree (pnode-> right); <br/> Delete pnode; <br/> pnode = NULL; <br/>}< br/> template <class T> <br/> void rbtree <t> :: leftrotate (rbtreenode <t> * node) <br/> {<br/> If (node-> right = pguard) <br/> {<br/> cout <"[Warning + 1000] node [" <node-> value <"] does not have any right node, cant be "<br/> <" Left rotate! "<Endl; <br/> return; <br/>}< br/> // The right child of node Y <br/> rbtreenode <t> * Y = node-> right; <br/> // update the right child of a node to the left child of its right child <br/> node-> right = Y-> left; <br/> // process the updated data. If the left child of the right child is not empty, the parent node is changed to node. <br/> If (Y-> left! = Pguard) <br/> Y-> left-> father = node; <br/> // update the parent node of Y to the parent node of node <br/> Y-> father = node-> father; <br/> // If the node is root <br/> If (node-> father = pguard) <br/> root = y; <br/> // link Y to the correct position of the node's parent node (left or right) <br/> else if (node = node-> father-> left) <br/> node-> father-> left = y; <br/> else node-> father-> right = y; <br/> // update the link between Y and node <br/> Y-> left = node; <br/> node-> father = y; <br/>}< br/> template <class T> <br/> Void rbtree <t >:: rightrotate (rbtreenode <t> * node) <br/>{< br/> If (node-> left = pguard) <br/> {<br/> cout <"[Warning + 1000] node [" <node-> value <"] does not have any left node, cant be "<br/> <" right rotate! "<Endl; <br/> return; <br/>}< br/> // The left child of node Y <br/> rbtreenode <t> * Y = node-> left; <br/> // update the left child of a node to the right child of the left child <br/> node-> left = Y-> right; <br/> // process the updated data. If the right child of the left child is not empty, the parent node is changed to node. <br/> If (Y-> right! = Pguard) <br/> Y-> right-> father = node; <br/> // update the parent node of Y to the parent node of node <br/> Y-> father = node-> father; <br/> // If the node is root <br/> If (node-> father = pguard) <br/> root = y; <br/> // link Y to the correct position of the node's parent node (left or right) <br/> else if (node = node-> father-> left) <br/> node-> father-> left = y; <br/> else node-> father-> right = y; <br/> // update the link between Y and node <br/> Y-> right = node; <br/> node-> father = y; <br/>}< br/> template <class T> <B R/> void rbtree <t>: rbinsert (rbtreenode <t> * node) <br/>{< br/> rbtreenode <t> * Y = pguard, <br/> * x = root; <br/> while (X! = Pguard) <br/>{< br/> Y = x; <br/> If (Y-> value = node-> value) <br/> return; // duplicatenode; <br/> If (Y-> value> node-> value) <br/> X = x-> left; <br/> else x = x-> right; <br/>}< br/> node-> father = y; <br/> If (y = pguard) // The node is root <br/> root = node; <br/> else if (node-> value <Y-> value) // left child <br/> Y-> left = node; <br/> else y-> right = node; <br/> node-> left = node-> right = pguard; <br/> node-> color = Re D; <br/> rbinsertfixup (node); <br/> return; // succeed; <br/>}< br/> template <class T> <br/> void rbtree <t>: rbinsertfixup (rbtreenode <t> * node) <br/>{< br/> while (node-> father-> color = red) <br/> {<br/> rbtreenode <t> * puncle = getuncle (node), <br/> * pgrandfather = getgrandfather (node ); <br/> If (puncle-> color = red) <br/> {<br/> node-> father-> color = black; <br/> puncle-> color = black; <br/> pgrandfather-> C Olor = red; <br/> node = pgrandfather; <br/>}< br/> else <br/> {// if Uncle = black <br/> If (node-> father = pgrandfather-> left) <br/> {// father is left child <br/> If (node = node-> father-> right) <br/> {// right child <br/> node = node-> father; <br/> leftrotate (node ); <br/>}< br/> node-> father-> color = black; <br/> pgrandfather-> color = Red; <br/> rightrotate (pgrandfather ); <br/>}< br/> else <br/> {// father is Right child <br/> If (node = node-> father-> left) <br/> {// left child <br/> node = node-> father; <br/> rightrotate (node); <br/>}< br/> node-> father-> color = black; <br/> pgrandfather-> color = Red; <br/> leftrotate (pgrandfather); <br/>}< br/> root-> color = black; <br/>}< br/> template <class T> <br/> void rbtree <t>: rbinsert (const T & VA) <br/>{< br/> rbinsert (newnode (VA); <br/> return; // succeed; <BR/>}< br/> template <class T> <br/> const rbtreenode <t> * rbtree <t>: successor (const rbtreenode <t> * node) <br/> {// check whether the node is a maxnode between calls. <br/> If (node = pguard) <br/> return pguard; <br/> const rbtreenode <t> * ptemp = node; <br/> If (ptemp-> right! = Pguard) <br/>{// find the minim element in right sub-tree <br/> while (ptemp-> left! = Pguard) <br/>{< br/> ptemp = ptemp-> left; <br/>}< br/> return ptemp; <br/>}< br/> rbtreenode <t> * ptempfather = node-> father; <br/> while (ptempfather! = Pguard & <br/> node = ptempfather-> right) <br/>{< br/> ptemp = ptempfather; <br/> ptempfather = ptempfather-> father; <br/>}< br/> return ptempfather; <br/>}< br/> template <class T> <br/> const rbtreenode <t> * rbtree <t>: maxnode (const rbtreenode <t> * node) <br/>{< br/> If (node = NULL) <br/> node = root; <br/> const rbtreenode <t> * ptemp = node; <br/> while (ptemp-> right! = Pguard) <br/> ptemp = ptemp-> right; <br/> return ptemp; <br/>}< br/> template <class T> <br/> void rbtree <t>: Remove (rbtreenode <t> * pnode) <br/> {<br/> // null node <br/> If (pnode = NULL | pnode = pguard) <br/> return; // nullnode; </P> <p> // temp point definition <br/> rbtreenode <t> * ptemp = pguard, <br/> * ptempnode = pguard; <br/> If (pnode-> left = pguard | <br/> pnode-> right = pguard) <br/> ptempnode = pnode; <Br/> else ptempnode = const_cast <rbtreenode <t> *> (successor (pnode); <br/> If (ptempnode-> left! = Pguard) <br/> ptemp = ptempnode-> left; // maybe nil <br/> else ptemp = ptempnode-> right; // maybe successor's right node! <Br/> ptemp-> father = ptempnode-> father; // different form BST, need not check <br/> If (ptempnode-> father = pguard) <br/> root = ptemp; // set the root to nil <br/> else if (ptempnode = ptempnode-> father-> left) <br/> ptempnode-> father-> left = ptemp; <br/> else ptempnode-> father-> right = ptemp; <br/> If (pnode! = Ptempnode) <br/> {// has two children, and the ptempnode is pointing to successor. <br/> // now need to copy the successor's data to node <br/> pnode-> color = ptempnode-> color; <br/> pnode-> father = ptempnode-> father; <br/> pnode-> left = ptempnode-> left; <br/> pnode-> right = ptempnode-> right; <br/> pnode-> value = ptempnode-> value; <br/>}</P> <p> If (ptempnode-> color = black) // change the black height, So Nee D to fix up! <Br/> rbremovefixup (ptemp); <br/> Delete ptempnode; <br/> ptempnode = NULL; <br/> return; // succeed; <br/>}< br/> template <class T> <br/> void rbtree <t>: rbremovefixup (rbtreenode <t> * pnode) <br/>{< br/> while (pnode! = Root & pnode-> color = black) <br/>{< br/> rbtreenode <t> * pfather = pnode-> father; <br/> rbtreenode <t> * psibling = pfather-> right; <br/> If (pnode = pnode-> father-> left) <br/>{< br/> If (psibling-> color = red) <br/>{< br/> psibling-> color = black; <br/> pfather-> color = Red; <br/> leftrotate (pfather); <br/> psibling = pfather-> right; <br/>}< br/> If (psibling-> left-> color = Black & <br/> psibling-> rig Ht-> color = black) <br/>{< br/> psibling-> color = Red; <br/> pnode = pfather; <br/>}< br/> else <br/> {<br/> If (psibling-> right-> color = black) // sibling's left is red <br/>{< br/> psibling-> left-> color = black; <br/> psibling-> color = Red; <br/> rightrotate (psibling); <br/> psibling = pfather-> right; <br/>}< br/> // right is red, left is unsure <br/> psibling-> color = pfather-> color; <br/> pfather-> color = Black; <br/> psibling-> right-> color = black; <br/> leftrotate (pfather); <br/> pnode = root; <br/>}< br/> else <br/> {<br/> If (psibling-> color = red) <br/>{< br/> psibling-> color = black; <br/> pfather-> color = Red; <br/> rightrotate (pfather ); <br/> psibling = pfather-> left; <br/>}< br/> If (psibling-> left-> color = Black & <br/> psibling-> right-> color = black) <br/>{< br/> psibling-> color = Red; <B R/> pnode = pfather; <br/>}< br/> else <br/> {<br/> If (psibling-> left-> color = black) // sibling's left is red <br/>{< br/> psibling-> right-> color = black; <br/> psibling-> color = Red; <br/> leftrotate (psibling); <br/> psibling = pfather-> left; <br/>}< br/> // two children of sibling are both red <br/> psibling-> color = pfather-> color; <br/> pfather-> color = black; <br/> psibling-> left-> color = black; <br/> r Ightrotate (pfather); <br/> pnode = root; <br/>}< br/> pnode-> color = black; <br/>}< br/> template <class T> <br/> void rbtree <t>: Remove (const T & value) <br/> {<br/> // temp point definition <br/> rbtreenode <t> * ptemp = pguard, <br/> * ptempnode = pguard, <br/> * pnode = root; <br/> // find the right position <br/> rbsearch (value); <br/> If (pnode = pguard) <br/> return; // notfound; <br/> If (pnode-> lef T = pguard | <br/> pnode-> right = pguard) <br/> ptempnode = pnode; <br/> else ptempnode = const_cast <rbtreenode <t> *> (successor (pnode); <br/> If (ptempnode-> left! = Pguard) <br/> ptemp = ptempnode-> left; // maybe nil <br/> else ptemp = ptempnode-> right; // maybe successor's right node! <Br/> ptemp-> father = ptempnode-> father; // different form BST, need not check <br/> If (ptempnode-> father = pguard) <br/> root = ptemp; // set the root to nil <br/> else if (ptempnode = ptempnode-> father-> left) <br/> ptempnode-> father-> left = ptemp; <br/> else ptempnode-> father-> right = ptemp; <br/> If (pnode! = Ptempnode) <br/> {// has two children, and the ptempnode is pointing to successor. <br/> // now need to copy the successor's data to node <br/> pnode-> color = ptempnode-> color; <br/> pnode-> father = ptempnode-> father; <br/> pnode-> left = ptempnode-> left; <br/> pnode-> right = ptempnode-> right; <br/> pnode-> value = ptempnode-> value; <br/>}< br/> If (ptempnode-> color = black) // change the black height, so need To fix up! <Br/> rbremovefixup (ptemp); <br/> Delete ptempnode; <br/> ptempnode = NULL; <br/> return; // succeed; <br/>}< br/> template <class T> <br/> rbtreenode <t> * rbtree <t>: rbsearch (const T & value) <br/> {<br/> rbtreenode <t> * pnode = root; <br/> while (pnode! = Pguard) <br/>{< br/> If (pnode-> value) <br/> pnode = pnode-> left; <br/> else if (pnode-> value <value) <br/> pnode = pnode-> right; <br/> else if (pnode-> value = value) <br/> break; <br/>}< br/> return pnode; // maybe nil <br/>}< br/>}// end of namespace <br/> # endif