Realization and Analysis of C + + in red-black tree

Source: Internet
Author: User
The so-called red-black tree, is the balanced expansion of the binary search tree, red-black tree and AVL are the balanced version of BST, compared to the full balance of AVL, the red-black tree requires only local balance, so when the red and black trees to insert and delete nodes, the need to adjust less than AVL, statistical performance better than the AVL tree, C + + The variants of the red and black trees are applied to the map, set, Multimap, and Multiset in the STL. This paper mainly analyzes the node insertion and node deletion of red-black tree. This article will summarize a basic template for inserting nodes and deleting nodes.
First look at the characteristics of the red and black tree:
1, the red-black tree root node is black
2, the red-black tree expansion of the external nodes are black nodes
3, the red node of the two child nodes are black nodes, do not allow two consecutive red nodes

4. Each simple path of any node to the external node of its descendants contains the same number of black nodes

First, insert nodes into red and black trees         Because of the 4th feature of the red-black tree, the new node should be labeled red when you insert a new node into the red-black tree. Inserting a node into a red-black tree looks at the parent node and Uncle node of the inserted node.
        for the following discussion, our newly inserted node is node D or node E, which is red and which is our newly inserted node.
       1, when the parent node that inserts the new node is a black node, the insert ends
       2, When the parent node that is inserting the new node is a red node and the Uncle node that is inserting the node is a black node, there are four cases where 1, 2 and 4, 3 are symmetric respectively, so here we only discuss situations 1, 2
          In the Insert node, we extracted the basic template is the situation 1, for situation 1, we made adjustments as shown in the following illustration:
        for the adjustment, our principle is that the adjustment has no effect on the outside world, for the above example, b nodes should be the same color as the a node, which is black, so in order to keep the same number of black nodes in the left and right subtree of B, the a node should be turned red, so the adjustment of condition 1 ends.
        for conditions 2. Here we choose the situation 1 for the template means that when the situation 2 o'clock, first the situation 2 adjusted to 1, and then adjusted according to the situation 1 mode adjustment, the situation 1 adjusted to 2 of the way the following figure:
          As you can see from the diagram, we only need to adjust the Node B and node e position, without the need for color change, so the adjustment is relatively simple, and then adjust according to the situation 1.
          3, when the parent node of the Insert node is a red node and the Uncle node that is inserting the node is also a red node, we adjust the following:
   is to turn the parent Node B of the new inserted node D into black with Uncle Node C, and then turn the D's grandfather node A red so that a node is marked up as a newly inserted node for red-red adjustment.

Delete the nodes in the red-black tree for the delete node, if the node we want to delete is just a leaf node, delete it and then adjust it, if the node you want to delete is not a leaf node, then look for the maximum node m of the left subtree of the node that you want to delete, and then dump the maximum value to the node you want to delete. Then the node m is deleted, which means that the deletion is also the leaf node, so we discuss the adjustment of the red and black tree when removing the leaf node.
1, when the deletion of the leaf node is red node, the direct deletion is good, do not need to adjust
2, when the deleted node is a black node, the deletion node is replaced by the extended black node n, and in order to maintain the feature of the Red and black tree 4, the N node becomes a double black node, that is to say, the Black of N represents two times, can guarantee the characteristic of the red-black tree 4.
The node that deletes the red-black tree considers the sibling node of the double black node, and the child nodes of its sibling node.
Below we extract a basic template from the adjustment of the delete node, as shown in the following figure:
Where the node n is a double black node, the colorless node in the graph indicates whether it is red or black, and the graph on the right is the adjusted figure of the basic template on the left. For the adjustment, the basic requirements or the external has no effect, therefore, after the adjustment, B is the same color as a, so that node D should be black, as the original B-node supplement, a should also be black, so as to make this subtree relative to the external black node number unchanged, And the same number of black nodes in the left and right subtree of B in the new subtree.
And then we'll describe the other things:
(1) When the base template d is a black node, and C is a red node, as shown in the following figure:
From the above figure, we just need to make a simple adjustment of the subtree under the B branch, you can adjust to the form in the right image, that is, the situation in the basic template, and then follow the basic template processing methods.
(2) when both C and D are black in the base template, you only need to turn B red so that the black nodes in the left and right subtree of a are equal, but for the outside, the black node of the subtree below the a node is 1 less, so if a node is red, turn a into black, If a itself is black then set a as a double black node to continue to adjust upward.
(3) When the two-black node n brother Node B is red, adjust as shown below:
From the above figure, this will be adjusted to the two-black node of the sibling node as a black node situation, according to the above method adjustment can be.
One of the red-black tree implementations is as follows:

        #ifndef cm_rbtree_hpp #define CM_RBTREE_HPP #include "binarysearchtree.hpp" namespace CM
      	  {Template<typename t> class Rbtreenode;
      	  Template<typename t> class Rbtreeiterator;
      	
      	  Template<typename t> class Rbtree; Template<typename t> class Rbtreenode {public:typedef T value_ty
      	        PE;
      	
      	      Enum color_t {color_black, color_red};
      	            Public:explicit rbtreenode (const t& v=t (), color_t c=color_black): Value_ (v) 
      	      , Left_ (NIL), Right_ (NIL), Parent_ (NIL), Color_ (c)   {} rbtreenode<t>* Left () {return left_;  rbtreenode<t>* Right () {return right_; } Rbtreenode<t>* parent () {return parent_;}   Rbtreenode<t>* Left () const {return left_;  rbtreenode<t>* Right () const {return right_;
      	        rbtreenode<t>* parent () const {return Parent_}  Const t& Value () const {return value_;  } color_t Color () const {return color_;   } void Left (rbtreenode<t>* node) {left_ = node;  } void Right (rbtreenode<t>* node) {right_ = node;
      	        } void Parent (rbtreenode<t>* node) {parent_ = node;}
      	        void value (const t& value) {value_ = value;}      void color (color_t c) {color_ = C;
      	        } operator bool () const {return this!= NIL; } BOOL Operator!
     () const {return this = = NIL; 	        } public:static rbtreenode<t>* NIL;
      	        Private:t Value_;
      	        rbtreenode<t>* Left_;
      	        rbtreenode<t>* Right_;
      	        rbtreenode<t>* Parent_;
      	    color_t Color_; 
      	  };
      	
      	  Template<typename t> rbtreenode<t>* Rbtreenode<t>::nil (New rbtreenode<t> ());
      	  Template<typename t> class Rbtree:public binarysearchtree_t< rbtreenode<t> >
      	
      	    {public:typedef rbtreenode<t> Node;
      	      public:size_t BH () const {return this->bh (This->getroot ());
      	        } size_t BH (const node* node) const {node* n = node;
      	        size_t h =; while (n) {if (N->color () = Node::color_blaCK) {++h;
      	        } n = N->left ();
      	      return h;    } size_t Insert (const t& key) {node* z = new Node (key, node::color_red);    The node to insert node* y = node::nil;
      	        Y is the parent node of x = node* x = This->root ();
      	          while (x!= node::nil) {y = x;
      	          if (key = = X->value ()) {return 0;
      	          } if (Key < X->value ()) {x = X->left ();
      	          else {x = X->right ();
      	
      	        } z->parent (y);
      	          if (y = = node::nil) {this->root_ = Z;
      	        This->root_->parent (Node::nil);
     else {if (Key < Y->value ()) { 	            Y->left (z);
      	          else {y->right (z);
      	        } z->left (Node::nil);
       	          Z->right (Node::nil);
      	
      	        Insert_fixup (z);
      	        ++this->size_;
      	      return;
      	        } void Remove (node* z) {node* y = node::nil;
      	        node* x = Node::nil;
      	        if (z->left () = = Node::nil | | z->right () = = Node::nil) {y = Z;
      	          else {//y = This->successor (z);
      	          y = Z->right ();
      	          while (Y->left ()!= node::nil) {y = Y->left ();  }//X is the only child of Y if (Y->left ()!= node::nil) {x
      	        = Y->left (); else {x= Y->right ();
      	
      	        } x->parent (Y->parent ());
      	        if (y->parent () = = Node::nil) {this->root_ = x; else {if (y = = Y->parent ()->left ()) {y->parent ()->left (
      	          x);
      	          else {y->parent ()->right (x);
      	        } if (y!= z) {z->value (Y->value ());
      	        } if (y->color () = = Node::color_black) {this->delete_fixup (x);
      	        } Delete y;
      	      --this->size_;
      	        ///If key exists, delete and return, otherwise return size_t remove (const t& key) {
      	        node* node = this->find (key);
      	     if (node!= node::nil) {this->remove (node);     return;
      	      } return; } private:void Left_rotate (node* x) {node* y = x->right ()
      	
      	        ;
      	
      	        Turn the left number of y into the right subtree X->right (Y->left ()) of X;
      	        if (Y->left ()!= node::nil) {y->left ()->parent (x);
      	        } if (y!= node::nil) {y->parent (x->parent ());
      	        } if (x->parent () = = Node::nil) {this->root_ = y; else {if (x = = X->parent ()->left ()) {x->parent ()->left (
      	          y);
      	          else {x->parent ()->right (y);
      	        }///Turn X to the left sub node of y Y->left (x); if (x!= node::nil) {X->p arent (y);
      	         } void Right_rotate (node* x) {node* y = x->left ();
      	
      	        X->left (Y->right ());
      	        if (Y->right ()!= node::nil) {y->right ()->parent (x);
      	        } if (y!= node::nil) {y->parent (x->parent ());
      	        } if (x->parent () = = Node::nil) {this->root_ = y; else {if (x = = X->parent ()->left ()) {x->parent ()->left (
      	          y);
      	          else {x->parent ()->right (y);
      	        } y->right (x);
      	        if (x!= node::nil) {x->parent (y); } void Insert_fixup (node* z) {node* y = Node::nil; while (z!= this->root () && z->parent ()->color () = = node::color_red) {if z->parent (
      	            = = = Z->parent ()->parent ()->left ()) {y = Z->parent ()->parent ()->right ();
      	              if (y->color () = = node::color_red) {z->parent ()->color (node::color_black);
      	              Y->color (Node::color_black);
      	              Z->parent ()->parent ()->color () (node::color_red);
      	            z = z->parent ()->parent (); else {if (z = = Z->parent ()->right ()) {z = z->p
      	                Arent ();
      	              This->left_rotate (z);
      	              } z->parent ()->color (node::color_black);
      	              Z->parent ()->parent ()->color () (node::color_red); This->right_rotate (Z->parent ()->parent ());
      	            } else {y = z->parent ()->parent ()->left ();
      	              if (y->color () = = node::color_red) {z->parent ()->color (node::color_black);
      	              Y->color (Node::color_black);
      	              Z->parent ()->parent ()->color () (node::color_red);
      	            z = z->parent ()->parent (); else {if (z = = Z->parent ()->left ()) {z = Z->pa
      	                rent ();
      	              This->right_rotate (z);
      	              } z->parent ()->color (node::color_black);
      	              Z->parent ()->parent ()->color () (node::color_red);
      	            This->left_rotate (Z->parent ()->parent ()); }} this->root ()->coloR (Node::color_black);
      	        } void Delete_fixup (node* x) {node* w = node::nil; while (x!= this->root () && x->color () = = Node::color_black) {if (x = = X->parent ()->
      	            Left ()) {w = x->parent ()->right ();
      	              if (w->color () = = node::color_red) {w->color (node::color_black);
      	              X->parent ()->color (node::color_red);
      	              This->left_rotate (X->parent ());
      	            W = x->parent ()->right (); if (W->left ()->color () = = Node::color_black && w->right ()->color () = = Node::color
      	              _black) {w->color (node::color_red);
      	            x = X->parent (); else {if (W->right ()->color () = = Node::color_black) {W->lefT ()->color (node::color_black);
      	                W->color (node::color_red);
      	                Right_rotate (w);
      	              W = x->parent ()->right ();
      	              } w->color (X->parent ()->color ());
      	              X->parent ()->color (node::color_black);
      	              W->right ()->color (node::color_black);
      	              Left_rotate (X->parent ());
      	            x = This->root ();
      	            } else {w = x->parent ()->left ();
      	              if (w->color () = = node::color_red) {w->color (node::color_black);
      	              X->parent ()->color (node::color_red);
      	              Right_rotate (X->parent ());
      	            W = x->parent ()->left (); } if (W->right ()->color () = = Node::color_black && w->left ()->color () = Node:: Color_black) {w->color (node::color_red);
      	            x = X->parent (); else {if (W->left ()->color () = = Node::color_black) {w->right ()-&G
      	                T;color (Node::color_black);
      	                W->color (node::color_red);
      	                Left_rotate (w);
      	              W = x->parent ()->left ();
      	              } w->color (X->parent ()->color ());
      	              X->parent ()->color (node::color_black);
      	              W->left ()->color (node::color_black);
      	              Right_rotate (X->parent ());
      	            x = This->root ();
      	      }} x->color (Node::color_black);
      	
      	  }
      	  }; Template<typename t> class Rbtreeiterator {PUBLIC:RBTREeiterator (): Tree_ (Rbtreenode<t>::nil), Current_ (Rbtreenode<t>::nil) {
      	          } rbtreeiterator (rbtree<t>&, TypeName rbtree<t>::node* current) : Tree_ (tree), Current_ (current) {} const t& Operat
      	        or* () const {return current_->value ();
      	        } t* operator-> () {return current_; BOOL operator== (const rbtreeiterator& RHS) Const {return cur
      	        Rent_ = = Rhs.current_; BOOL Operator!= (const rbtreeiterator& RHS) Const {return cur
      	        Rent_!= Rhs.current_; } rbtreeiterator& operator++ () {Current_ = Tree_.successor (curRENT_);
      	        return *this;
      	        } private:rbtree<t>& Tree_;
      	    TypeName rbtree<t>::node* Current_;
      	
      	
      	}; }//End namespace cm #endif//CM_RBTREE_HPP

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.