A brief analysis of red and black trees

Source: Internet
Author: User

What is a red and black tree??? The red and black tree is first a search binary tree, each node in the tree color is not black or red. It has the following characteristics:1, the root node is black2. Each knot is either black or red.3. Cannot have two consecutive red nodes .4, starting from any node, to the path of the next generation of the hollow pointer, all contain the same number of black nodes. For example:
  
Why should there be red and black trees??? at first we learned to search the binary tree, but finally we found that the search binary tree was defective, and then we introduced the AVL tree. The AVL tree is a highly balanced two-fork search tree that satisfies the time complexity of the O (logn) additions and deletions. Now that the AVL tree has fulfilled our expectations, why should we introduce the red and black trees? This is because the AVL tree is a highly balanced two-fork search tree, and the cost of maintaining an AVL tree is very large compared to a red-black tree, and because of its high balance, it requires the tree to be adjusted almost every time it is inserted or deleted. The red-black tree is an approximately balanced two-fork search tree that satisfies the longest path of no more than twice times the shortest path, and it is easy to maintain, and does not need to be adjusted every time the tree is inserted. Although the overall performance of the red and black trees than the AVL tree can be almost, but not too bad, and the red and black tree wins in easy to maintain, so the compromise of the red and black trees or use more.
Third, insertIn general, the node that I want to insert is set to red by default. 1. If the inserted node is the root node, it is inserted directly and the root node is dyed black. 2. If the father of the position to be inserted is black, then insert directly. 3, to insert the position of the father is red, then insert a red node will appear two red node continuous situation, so this time we need to adjust the tree to restore balance. Suppose the node to be inserted is cur, whose father is the parent, whose father's brother is uncle, and its grandfather is grand.
Scenario 1:because Cur's father is a red knot, according to the nature of the red and black trees, the grand must not be empty, and must be black. Suppose in this case cur's uncle uncle is red.



Scenario 2:Suppose Cur's uncle node does not exist or exists and is black.
1, assume that Cur is the parent's left child, the parent is the grand left child, at this time just do once right paddle balance.
2, Cur is the right child of the parent, the parent is a grand child, at this time to the parent of a left rotation into the upper right paddle case.

of course, assuming that the parent is Grand's right child, uncle is the grand left child, and the above situation is mirrored, as long as the left hand pointer is interchangeable.
Iv. Deletionthe red-black tree deletion algorithm is similar to the two-fork search tree deletion algorithm, but the red-black tree also restores the tree balance after the deletion. First we want to find the node to delete, if there are two children to delete the node, then we want to find the leftmost child in his right subtree, swap with him, and then convert the node to be deleted to the leftmost node. The following focus on how to restore the balance of the tree after deletion, note that the following actions are based on the node to be deleted left child and right child at least one empty case.
1, delete the node is red, then delete directly, will not affect the balance of the tree. 2, if the node to be deleted is black, but his child is red, then delete the node directly, and then turn his child into black. In this way, the balance of the tree has not been changed. in this case, if the node to be deleted is the root, it is handled in a special way with only the following two cases:

3, to delete the node is black, his child is also black, then divided into a few cases, Suppose to delete the node is its father's right child, his father is the parent, its brother is Subl, his child is cur.

Case 1: If the SUBL is red, then the parent must be black, and the child of Subl must be black. Turn the parent right, then dye the subl black, then dye the parent red.

Situation 2:subl is black case, according to SUBLL and Sublr again divided into the situation
1, if the SUBLL and SUBLR are black
1.1. If the parent is red

1.2. If the parent is black

2, SUBLL is red, Sublr color arbitrary

3, Sublr is red, SUBLL color is black
of course, if the node to be deleted is on the left side of the father's node, and the analysis above is mirrored, just change the left and right hands.

Five, write a function isblance judge whether a red black tree is a legitimate red and black treeJudging by the definition of red and black trees can be simpler, judging whether the definition of red and black trees are satisfied.
//Source code
#pragma onceenum {black,red};template<typename k,typename v>struct rbtreenode{int _color; K _key; V _value; Rbtreenode<k, v> *_left; Rbtreenode<k, v> *_right; Rbtreenode<k, v> *_parent; Rbtreenode (K key, V value): _color (red)//Default node is red, _key (key), _value (value), _left (null), _right (null), _pare NT (NULL) {}};template<typename k,typename v>class rbtree{typedef rbtreenode<k, v> Node;public:RBTree (): _ Root (NULL) {}rbtree (const rbtree<k, v>& tree) {_copy (tree._root, _root);} Rbtree<k, v>& operator= (const rbtree<k, v>& tree) {if (This! = &tree) {rbtree<k, v> tmp (tree ); Swap (_root, tmp._root);} return *this;} ~rbtree () {_destory (_root);} BOOL Find (const k& key) {node* cur = _root;while (cur) {if (Cur->_key > key) cur = Cur->_left;else if (cur->_ Key < key) cur = Cur->_right;elsereturn true;} return false;} BOOL Insert (const k& key, const v& value) {if (_root = = NULL)//If the inserted node is the root node {_root = new node (KEY, value); _root->_color = Black;return true;} node* cur = _root; node* parent = null;while (cur) {if (Cur->_key > key) {parent = Cur;cur = Cur->_left;} else if (Cur->_key < key) {parent = Cur;cur = Cur->_right;}                Elsereturn false; The node to be inserted already exists}cur = new Node (key, value), if (parent->_key>key) parent->_left = Cur;elseparent->_right = cur; Cur->_parent = Parent;while (cur! = _root&&parent->_color = = red)//parent node is red needs to be adjusted {node* grand = PARENT-&G      T;_parent;     Find grandfather node if (parent = = Grand->_left) {node* Uncle = grand->_right; Find Uncle Knot if (Uncle&&uncle->_color = = red)//Uncle Knot is red {grand->_color = Red;parent->_color = black;uncle-      >_color = Black;cur = Grand;parent = cur->_parent;          Red node up, need to continue to judge}else//Uncle node does not exist or for the black node {//First deal with the case of double spin if (cur = = parent->_right)//If Cur is the father's right child {Rotatel (parent); First, the parent is left-handed parent = cur;}        If the cur is the right child of the parent, then the rotation is now turned into a grand right-hand case rotater (grand);Right-parent->_color the grandfather node = Black;grand->_color = Red;break; This time it's already balanced}}else{node* uncle = grand->_left;if (Uncle&&uncle->_color = = red)//If uncle exists and is red {parent->_        color = Black;uncle->_color = Black;grand->_color = RED; The red node moves up and continues to judge cur = Grand;parent = cur->_parent;} else{//if the cur is the left child of the parent, then the right-hand rotation is required to replace the double-spin with the if (cur = = parent->_left) {rotater (parent);p arent = cur;} In the left-handed Rotatel (grand);p Arent->_color = Black;grand->_color = Red;break;}}     _root->_color = BLACK; Place the root node in black return true;} BOOL Remove (const k& key) {node* cur = _root; node* parent = NULL; Node* del = null;while (cur)//Find the node you want to delete {if (Cur->_key > key) cur = Cur->_left;else if (Cur->_key &lt ; Key) cur = cur->_right;elsebreak;}           if (cur = = NULL) return false; Node not found, delete failed//If the node to be deleted has two children, it is first converted to a situation where there is only one child or No child if (cur->_left! = null&&cur->_right! = NULL) {node*       Minright = cur->_right; Records the leftmost node in the right subtree of the node to be deleted while (minRight->_left) {minright = Minright->_left;}         Use swap to delete Cur->_key = Minright->_key;cur->_value = Minright->_value;cur = Minright;       Cur points to the node to be deleted}parent = cur->_parent;                   Find the Father del = cur to delete the node; Del points to the node to be deleted if (Cur->_left = = null)//The left child of the node to be deleted is empty or does not exist {if (cur = = _root)//If the node to be deleted is the root, then the deletion is already balanced {_ Root = Cur->_right;if (cur->_right)//If the right child of the root node is not empty, then it must be red {_root->_parent = Null;_root->_co Lor = BLACK;} Delete Del;return true;} The child of the node to be deleted is linked to the father of the node to be deleted if (Parent->_left = = cur)//cur is the parent's left child, the node to be deleted is not the root, then there must be a father Parent->_left = C Ur->_right;else//cur is the parent of the right child, to delete the node is not the father, then there must be a father Parent->_right = Cur->_right;i                   F (cur->_right)//If the leaf node is not to be deleted cur->_right->_parent = Parent;cur = del->_right; Let cur point to the child to delete the node}else{if (cur = = _root)//The node to be deleted is the root, then the left subtree of the root node must exist {_root = cur->_left;_root->_parent = Null;_root->_color = BLACK; If the left child of the root node is not empty, it must be red delete Del;return true; if (Parent->_left = = cur)//is not the root node to be deleted, the parent must exist Parent->_left = Cur->_left;elseparent->_r             ight = Cur->_left;cur->_left->_parent = parent;                        Cur's left child must exist cur = del->_left; Let cur point to the child to delete the node}if (Del->_color = = red)//If the node to be deleted is red, the deletion has been balanced {delete Del;return true;} if (Del->_color = = Black&&cur&&cur->_color = = red)//If the node to be deleted is black and its child is red, the child is balanced with black (cur- >_color = Black;delete Del;return true;} The node to be deleted is black, and its child is null or black while (parent) {if (Parent->_left = = cur)//If the node to be deleted is the parent node of the left child {node* SUBR = Paren       t->_right;          SUBR is the right child of the parent, and there must be an if (Subr->_color = = red)//parent Right child is the red {Rotatel (parent); The parent is left-handed and dyed after rotation, because a node is still missing on the cur path, so continue to retrieve Curparent->_color = Red;subr->_color = BLACK;} else//If SUBR is black {node* SUBRL = subr->_left; node* SUBRR = subr->_right;if (Parent->_color = = BLACK && (SUBRL = = NULL&AMP;&AMP;SUBRR = NULL) | |       (Subrl&&subrr&&subrl->_color = = Black&&subrr->_color = = BLACK)))     If the parent and children of SUBR and Subr are empty {subr->_color = RED; Make SUBR this path to reduce a black node, and then judge upward parentcur = Parent;parent = cur->_parent;} Else{if (Parent->_color = = red)//If the parent node is red {if ((SUBRL = = NULL&AMP;&AMP;SUBRR = = NULL) | | (Subrl&&subrr&&subrl->_color = = Black&&subrr->_color = = BLACK))         {parent->_color = BLACK;             Turns the parent node into black subr->_color = RED;            The right child turns red, which is equivalent to a black break on the cur path;                To meet the balance, exit}}if directly (Subrl->_color = red)//If the SUBRL is red, first convert the SUBR to Zodan (rotater); subr = SUBR;           Let Subr point to the new parent node after rotation}//to this is the case of Zodan Rotatel (parent); Do a radio if for parent (Parent->_color = = RED)//Will rotate after the new parent node SUBR to the same color as the original parent node Subr->_color = Red;elsesubr->_color = Black;parent-> _color = BLACK;   Subr->_right->_color = black, which dyed the original parent node dark;            Because there is a black knot in the right sub-tree of SUBR, the red color black break;       The tree has been balanced}}}else{node* SUBL = parent->_left;        To delete the node in the right subtree of the parent, and there must be an if (Subl->_color = = red)//parent The left child is red, then by rotation let the number of black nodes on both sides of parent {rotater (parent); Let Paret right turn//Let black nodes on both sides of the same, less a node, and then continue to judge Cur,parent->_color = Red;subl->_color = black;} else//If the parent's left child is black {node* SUBLR = subl->_right; node* SUBLL = subl->_left;//If the parent and subl children are black, the SUBLL child is either all empty or All Black if (Parent->_color = = && (subll = = Null&&sublr = = NULL) | | (Subll&&sublr&&subll->_color = = Black&&sublr->_color = = BLACK)))     {subl->_color = RED; Make SUBL this path less a black contact, and then continue to judge cur = Parent;parent = cur->_parent;} Else{if (Parent->_color = = red)//If the Father node is the red node {if ((Subll = = Null&&sublr = = NULL) | | (Subll&&sublr&&subll->_color = = Black&&sublr->_color = = BLACK)) {Parent-> _color = BLACK;          Add a subl->_color = RED to the black contact on the cur path; Subl the number of black contacts on this path does not change;}}        if (Sublr->_color = = red)//subl's right child is red, the SUBL is left-handed {//double-turn to the right paddle Rotatel (SUBL); subl = Sublr;       Let Subl point to the parent node after rotation}rotater (parent); The color if (Parent->_color = = RED) Subl->_color = Red;elsesubl->_color = Subl The new parent node becomes the parent when the parent is right paddle//will be rotated        Black;parent->_color = Black;subl->_left->_color = Black;break;}}} _root->_color = Black;delete Del;return true;} BOOL Isblance () {if (_root = = null)//If it is an empty tree, it is the balanced return true;if (_root->_color = = red)//if the root node of the tree is red, the tree It's not a balanced return. False;int count = 0;//counts the number of black nodes in the left-most-left of this tree with count, as the benchmark for comparison with other paths node* cur = _root;while (cur) {if (Cur->_color = = BLACK) count++;cur = Cur->_left;} int Num=0;return _isblance (_root,num,count);} Protected:bool _isblance (node* root,int num,const int& count) {if (root = NULL) {return num==count;} If the node is red, determine what color his father is, and if the node is red, it must not be the root node if (Root->_color = = Red&&root->_parent->_color==red) return false;if (Root->_color = BLACK) Num++;return _isblance (root->_ Left,num,count) &&_isblance (root->_right,num,count);} void _copy (node* root,node* &newroot) {if (root = NULL) return; node* cur = new Node (root->_key,root->_value); cur->_color = Root->_color;newroot = Cur;cur->_parent = Newroot;_copy (Root->_left,cur->_left); _copy (root->_right,cur->_right);} void _destory (node* root) {if (root = NULL) return;_destory (Root->_left), _destory (root->_right);d elete root;} void Rotatel (node* parent)//L {node* Ppnode = parent->_parent; node* SUBR = Parent->_right;parent->_right = Subr->_left;if (subr->_left) subR->_left->_parent = Parent;subr->_left = Parent;parent->_parent = subr;if (Ppnode = = null) {_root = Subr;_root->_parent = null;} else{//link with upper layer if (ppnode->_left = = parent) Ppnode->_left = Subr;elseppnode->_right = Subr;subr->_paren t = Ppnode;}}void Rotater (node* parent)//right-handed {node* Ppnode = parent->_parent; node* Subl = Parent->_left;parent->_left = Subl->_right;if (subl->_right) subL->_right->_parent = Parent;subl->_right = Parent;parent->_parent = subl;if (Ppnode = = null) {_root = subl;_root->_parent= null;} else//with upper node link {if (ppnode->_left = = parent) Ppnode->_left = Subl;elseppnode->_right = Su Bl;subl->_parent = Ppnode;}} Private:node* _root;};



A brief analysis of red and black trees

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.