This address:http://blog.csdn.net/cyp331203/article/details/42677833
Bitter _ Coffee
Welcome reprint, but reproduced please indicate the source, otherwise will be held responsible, thank you!.
The red-black tree is based on a two-fork search tree, which can be found in the "Introduction to Algorithm" binary search tree insertion and deletion and the "Introduction to the algorithm" binary tree in the pre-and post-sequential non-recursive traversal implementation. For a two-fork find tree with a height of H, the time complexity of search, INSERT, DELETE, MINIMUM, Maximum, and so on is O (h). Therefore, when the height of the binary search tree is high, the above operations will be time-consuming, and the red-black tree can solve this problem. Red-Black trees are one of many balanced search trees that ensure that in the worst case, the time complexity of the basic dynamic set operation is O (LOGN)and N is the number of nodes.
One, what is red black tree
The red and black tree is a binary search tree, and the difference is that it adds a storage bit on each node to represent the color of the node, which can be red or black. Each node of a red-black tree contains 5 attributes: Color, key, left, right, and P (parent node). If a node has no child nodes or parent nodes, in the binary lookup tree, the corresponding pointer points to null (empty), and here is the second difference between the red and black trees and the two-fork lookup tree:
The red and black tree does not have any one node left child node, right child node or parent node will point to null (NULL), instead of using a nil sentinel node to place in the original null position, similar to the "Introduction to the algorithm" 10.2 A doubly linked list with Sentinel nodes in a doubly linked list without sentinel nodes and Sentinel nodes. In a red-black tree, the Sentinel node nil is an object that has the same attributes as the tree's normal node. It has a color property of black, and its other properties can be arbitrarily set, which is generally meaningless. Nil is used to replace the pointer to a NULL in the binary lookup tree, while the parent pointer of the root node points to nil. We treat the other nodes in addition to the nil nodes as internal nodes, and in the red-black tree, we focus on the internal nodes.
Red and Black tree structure chart:
Five properties of red and black trees:
Red and black trees, by any one from the root to the leaves of the simple path of the various nodes of the color constraints, red black tree can guarantee that no path will be more than twice times longer than other paths, so called balance . In order to maintain the balance, the red and black trees should meet the following five properties:
1, each node is not red or black.
2, the root node is black.
3, each leaf node (nil) is black, in fact nil only one.
4, if a node is red, then its two child nodes are black.
5. For each node, the same number of black nodes are included on the simple path from the node to all of its descendant leaf nodes.
For the 5th above, there is a new definition, black high : From a node x (without the node) to reach a leaf node on any simple path of the number of black nodes called the black height of the node, Note that the black height is the nil calculation .
The black height is marked out:
How does the red and black tree guarantee its performance O (LGN)?
Proof: The height of the red black Tree is O (LGN)
In fact, a red-black tree with n internal nodes has a maximum height of 2lg (n+1). We set a node x for the black height of HB (x).
First prove that the subtree with either node x as root contains at least 2^ (HB (x)-1)-1 internal nodes, using an inductive method:
① if the height of x is 0, then x is the leaf node (nil), and a subtree with x as the root node contains at least 2^ (1-1) -1=0 internal nodes, which is consistent with the conclusion.
② assumes that the height of X is K (k>=1), the subtree with x as the root node contains at least 2^ (HB (x)-1)-1 internal nodes.
③ for x's height is k+1 red-black tree, we consider its two subtree, its two subtree height is k, then satisfies the ② condition, two subtree contains at least 2^ (HB (x) 1)-1 internal nodes, so the tree with x as root contains at least (2^ (HB (x) 1) 1) + (2^ ( HB (x)-1)-1) +1=2^ (HB (x))-1 internal nodes, so it is proven.
For red-black trees with a height of H, according to the nature of 4 it is not difficult to find that at least half of the black nodes are on each path, otherwise there must be two red nodes adjacent to each other. So the tree's black height is at least h/2. So according to the above proven conclusion, there are n>=2 (H/2-1)-1, so there are: H<=2lg (n+1). Evidence.
According to this proof, the time complexity of the dictionary operation of our two-fork search tree is O (h), and the height of the red-black tree is O (LGN), and the time complexity of the dictionary operation of the red-black tree should be O (LGN). So red-black trees have better performance than binary search trees.
Single branch of the Red and black tree
It is important to note that due to the nature of the red and black trees, a single branch is not possible for some cases.
1. Single branch that may appear:
Because only in the above two cases can be in the case of a single branch, keep the above fifth character (note nil node). And in the following cases, there is no guarantee of the nature of the fifth single-branch case.
2, the single branch of the situation can not occur:
Because the above four but the branch case, cannot guarantee the nature 5. For example, the first two will make the red node---leaf node (nil) line with a black node number less than the Black node line on the Red node. Therefore, it is easy to find that the red and black tree species may only have double branches or black red under the single branch case .
second, left and right-handed operation
rotation operation is a lot of red and black tree operations necessary parts, rotation operation can keep binary search tree nature of the search tree local operations.
Left-and right-handed (both for the above node):
By, we can easily find that, after rotation, it is still possible to maintain the nature of the binary search tree. But can not guarantee the nature of the red black tree, such as the right, if the 21 node is a single branch of the case (a node =nil), will not meet the fifth nature.
We can easily give the left-and right-handed code:
L:
/* * Left */void left_rotate (node* x) {if (x = = Nil_node) {return;} with X as Fulcrum Node* y = X->r_child;x->r_child = y->l_child; The left node of Y is given the right node position of x, which satisfies the nature of the binary search tree if (y->l_child! = Nil_node) {//This sentence cannot be judged less y->l_child->parent = x;//Let the parent pointer of the left node point to X} Y->parent = x->parent;if (x->parent = = Nil_node) {//x is originally a root node this->root = y;} else if (x = = X->parent-> ; r_child) {y->parent->r_child = y;} else {y->parent->l_child = y;} Handle Left Node Y->l_child = X;x->parent = y;}
Right-handed:
/* * Use X as fulcrum for right-*/void right_rotate (node* x) {if (x = = Nil_node) {return;} Node* y = x->l_child;x->l_child = y->r_child;x->l_child->parent = X;y->parent = x->parent;if (X- >parent = = Nil_node) {//x is originally the root node this->root = y;} else if (x = = X->parent->l_child) {Y->parent->l_chil d = y;} else {y->parent->r_child = y;} Y->r_child = X;x->parent = y;}
It is easy to see that the rotational operation, either left or right, has a time complexity of O (1).
Three, the red black tree insert Operation
as mentioned before, the time complexity of the binary search tree's dictionary operation is O (h), while the operation of the red and black tree can be done in O (LGN) _. To do this, we definitely need to make some node adjustments after the insertion to satisfy the nature of the red-black tree. So after inserting, you need to adjust the tree, recolor the node, and rotate it.
Red-black tree node insertion can be divided into the insertion process and adjustment process, where the insertion process and the two-fork search tree is not much difference. Just notice that the search tree is null, and is now replaced with Nil Sentinel nodes, followed by the nodes we always colored red.
code to insert:
void Insert (int k) {node* n = new node (k); node* y = nil_node;node* x = root;while (x! = Nil_node) {//Find suitable insertion position, here is mainly to meet the binary search The nature of the axonal y = x; Y to record the position of X if (X->key > k) {x = X->l_child;} else {x = X->r_child;}} N->parent = y; Find the appropriate insertion position, Y is the parent node for this position if (y = = Nil_node) {//For empty tree case root = n;} else if (Y->key > N->key) {//left node Y->l_child = n ;} else {y->r_child = n;//Right node}//processing niln->l_child = Nil_node;n->r_child = nil_node;//processing the color of the insertion node N->color = RED;// Adjust operation Rb_insert_fixup (n);}
Here's the play, let's take a look at how this rb_insert_fixup adjustment function is implemented.
To adjust, we first need to understand what to adjust, that is, our previous insert operation, will destroy the red and black tree which properties? Let's take a look at these 5 properties:
1, each node is not red or black.
2, the root node is black.
3, each leaf node (nil) is black, in fact nil only one.
4, if a node is red, then its two child nodes are black.
5. For each node, the same number of black nodes are included on the simple path from the node to all of its descendant leaf nodes.
of which 1, 3 of the nature is certainly satisfied, and for 5 of the nature, because we inserted nodes are dyed red, so there is no more black nodes, so 5 of the nature can also be met. May be the problem is 2, 4 nature, for the nature of 2nd, if the insertion is an empty tree (only nil node), then the root node is red, will not meet the 2 nature. If the parent node of the inserted node is red, and we are inserting a red node, then the 4 property is not satisfied.
Processing Properties 2:
for the nature of the 2nd, in fact, very good solution, we only need to adjust the function at the end of a sentence root->color=black can be, the root knot Dianran black.
Processing Properties 4:
for the 4th character, the problem is the parent node is red, then the node to be adjusted and the parent node is red, does not meet the 4 nature, so we need to adjust the condition is the parent node if the red, you need to continue to adjust. There are actually three cases, first of all already the default Z parent node z->p color is red and the loop condition is while (z->color==red):
the first and z Tertiary node y is red, where z is the node to be adjusted (hereinafter):
' because Z's parent node z->p and tert-nodes are all red, the color of the z's grandfather node z->p->p must be black, because it was a "intact" red-black tree before inserting.
In this case, the treatment is: the parent node of z and the tertiary node are dyed black, and the z's grandfather node dyed red, so after we think about it, we found that in fact, the current tree to walk the parent node or the path of the tert-node the number of black nodes have no effect. Then we point the z point to the position of the grandfather node of Z, and then continue into the loop;
the second, Z's tert-node y is black and z is a right child
The practice here is to convert the two cases into three cases, of course, to use the rotation, but we do not want the position of Z to find the change, so here first let z=z->p, and then the Z-Fulcrum for the left-hand, because L will let Z drop a level, So in fact Z is still pointing to the original layer of the node, the position of the z->p->p has not changed.
the third, z of the Tertiary node Y is black and z is a left child
This is actually Z and z->p are both red, z->p->p and z.->p->right are black, what we want to do is to have a number of black nodes between Z and Z->p, so as to satisfy the nature of 4, But at the same time we want to keep the nature 5. So we deal with this:
Z->p dyed black, z->p->p dyed red, and then to the z->p->p as the fulcrum right-handed, so it was done,
It is not difficult to give the implementation code after analyzing the properties of 2 and the properties of 43 cases respectively:
/* Fix the color, because the insertion point, we always dye the its first red, so if the parent node is black there is no need to repair, if the parent node is red, you need to repair * repair color in three cases: *① the father of the current insertion point is red, and the other node of the grandfather node is also red, And the parent node is the left child of the grandparent node *② the parent node of the current insertion point is red, and the other node of the grandparent node is black, and this node is the right child node of the parent node *③ the parent of the current insertion point is red, and the other node of the grandparent node is black, and this node is the left child node of the parent Insert_fixup (node* z) {while (Z->parent->color = = RED) {if (z->parent = = Z->parent->parent->l_child) { If the parent node of Z is the left child node of the grandparent node node* y = z->parent->parent->r_child;if (Y->color = = RED) {//Case 1 processing Nature 4z->parent-> color = black;//Condition 1z->parent->parent->r_child->color = black;//Condition 1z->parent->parent->color = red;//Case 1z = z->parent->parent;//Condition 1} else if (z = = z->parent->r_child) {//Case 2z = z->parent;//condition 2left_ Rotate (z);//Condition 2} else {//Condition 3z->parent->color = black;//Condition 3z->parent->parent->color = red;//condition 3right_ Rotate (z->parent->parent);//Condition 3}} else {//When the parent node is the right child of the grandparent node, the difference with the above is to change all left operations and nodes to the corresponding node* y = z-> Parent->parent->l_child;if (Y->color = = RED) {Z->parent->color = BLAck;z->parent->parent->l_child->color = Black;z->parent->parent->color = RED;z = z->parent- >parent;} else if (z->parent = = z->parent->parent->l_child) {z = Z->parent;right_rotate (z);} else {z->parent- >color = Black;z->parent->parent->color = Red;left_rotate (z->parent->parent);}}} Root->color = black;//Processing Property 2}
the algorithm analysis of inserting operation
By observation, it is not difficult to find that because the height of the red black tree with n nodes is O (LGN), the time complexity of the insertion process is O (LGN), and for the adjustment process Rb_insert_fixup , only case 1 let Z rise two layers, It is possible for the while to occur, but due to the height of the tree, the time complexity is only possible in O (LGN), and for Case 2 and Case 3, the program does not rotate more than two times. As long as the execution to the situation 2 or the 3,while loop is going to end. So the time complexity of the entire node insertion is O (LGN).
Next article will be the red and black tree deletion node, please pay attention.
"Introduction to Algorithms" one of the red and Black tree (insert)