This article address: http://blog.csdn.net/cyp331203/article/details/42677833
Author: Bitter _ Coffee
Welcome reprint, but reprint please indicate the source, otherwise will investigate the corresponding responsibility, thank you.
The red-black tree is built on the basis of the two-fork Lookup tree, the binary lookup tree can see the "Introduction to the algorithm" binary search tree insertion and deletion and "Introduction to the algorithm" binary tree in front of the first sequence of non recursive traversal implementation. For a two-fork lookup tree with a height of H, the time complexity of search, INSERT, DELETE, MINIMUM, maximum, etc. is all O (h). So when the binary lookup tree height is higher, the above operation will be more time-consuming, and red-black tree can solve this problem. The red-black tree is one of many balanced search trees , which can guarantee that the time complexity of the basic dynamic set operation is O (LOGN)and N is the number of nodes in the worst case.
One, what is the red and black tree
The red-black tree is a binary lookup tree, and the difference is that it adds a bit of storage to each node to indicate the color of the node, which can be red or dark. Each node of the red-black tree contains 5 properties: 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-black tree and the two-fork lookup tree:
In the red-black tree, there is no left child node, right child node, or parent node pointing to null (empty), instead of using a nil sentinel node to place the original null position, similar to the "Introduction to Algorithms" 10.2 Two-way linked lists with Sentinel nodes in a two-way link table without a sentinel node and a sentinel node. In the red-black tree, the Sentinel node nil is an object that has the same attributes as the normal nodes of the tree species. Its color attribute is black, and its other properties can be set arbitrarily, and generally have little meaning. The nil is used to replace the pointer of the original NULL in the binary lookup tree, while the parent pointer of the root node points to nil. We treat other nodes of the nil node as internal nodes, and in the red-black tree we focus primarily on the internal nodes.
Red-Black tree structure chart:
Red-Black tree five properties:
Red-black trees, by any one from the root to the leaf of the simple path of each node in the color constraints, the red-black tree can guarantee that no path will be more than twice times longer than other paths, so called the balance . To keep the balance, the red-black tree satisfies 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 descendants ' nodes.
For the 5th above, there is a new definition of black height : The number of black nodes on any simple path from a node x (excluding the node) to a leaf node is called the black height of the node, note that the black height is the nil calculation .
identify the black height of the above image:
how the red-black tree ensures its performance O (LGN).
Proof: The height of the red-black tree is O (LGN)
In fact, the height of a red-black tree with n internal nodes is at most 2LG (n+1). We set a node X's black height to HB (x).
The first is to prove that the subtree with any node x has at least 2^ (HB (x)-1)-1 internal nodes, using the inductive method:
① if the height of x is 0, then x is a leaf node (nil), and the 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 the k+1 red-black tree of the height of X, we consider its two subtrees, and its two subtrees have a height of k, so satisfying the ② number condition, two subtrees contain at least 2^ (HB (x)-1)-1 internal nodes, so the tree with the root of X contains at least (2^ (HB (x)-1)-1) + (2^ ( HB (x)-1)-1 +1=2^ (HB (x))-1 internal nodes, which is therefore certified.
For a red-black tree with a height of H, according to the Nature 4 it is not difficult to find at least half of the black nodes on each path, otherwise there must be two red nodes adjacent. So the black height of the tree 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). Get the card.
According to this proof, our two-fork search Tree Dictionary operation of the time complexity of O (h), and the red-black tree height of O (LGN), red-black Tree dictionary operation time complexity should be O (LGN). So the red-black tree has better performance than a binary search tree.
single branch of red and black tree
It should be noted here that, because of the nature of the red-black tree, it is impossible for a single branch to occur in some cases.
1, may appear the single branch:
Because only in the two cases above, it is possible to maintain the fifth property above (note the nil node) in the case of a single branch. And the following several cases, are not guaranteed the fifth property of a single branch of the situation.
2, impossible to appear single branch situation:
Because of the above four but the branch case, cannot guarantee the nature 5. The first two, for example, are sure to make the black nodes of the red node-> leaf node (nil) line less than the black nodes of the red node-> black node line. Therefore, it is easy to find that the red-black tree species can only have two branches or black red under the single branch of the situation .
two, L and right rotation operation
Rotation operation is a lot of red and black tree operation is essential parts, rotation operation can keep binary search tree nature of the search tree local operations.
Left and right (both for the above node):
It is easy to see from the diagram above that the nature of the binary search tree can still be maintained after the rotation. But can not guarantee the nature of the red-black tree, such as the right image, if the 21 node is a single branch of the case (a node =nil), will certainly not meet the fifth property.
We can easily give a left-handed and right-handed code:
L:
* * * with X as fulcrum for the left/
void Left_rotate (node* x) {
if (x = = Nil_node) {return
;
}
Node* y = x->r_child;
X->r_child = y->l_child; Let the left node of Y get to the right node of x, which satisfies the nature of the binary search tree
if (y->l_child!= nil_node) {//This sentence can be judged less
y->l_child->parent = x; Let the left node's parent pointer 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;
}
Processing left node
y->l_child = x;
X->parent = y;
}
Right Rotation:
* * * with X as fulcrum for right
spin
/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 a root node
this->root = y;
} else if (x = = X->parent->l_child) {
y->parent->l_child = y;
} else {
y->parent->r_child = y;
}
Y->r_child = x;
X->parent = y;
}
It is easy to find that rotational operations, whether left-handed or right-handed, have a time complexity of O (1).
Three, the red black tree insert Operation
As mentioned before, the binary search tree dictionary operation time Complexity is O (h), while the operation of the red-black tree can be completed in O (LGN) _. In order to do this, we definitely need to make some adjustments to the node after the insertion, so that it satisfies the nature of the red and black tree. So after you finish inserting, you need to adjust the tree, recolor the nodes, and rotate.
The insertion process and the adjustment process can be divided into the node inserts of the red-black tree, and the insertion process is not much worse than the two-fork search tree. Just note that the search for null in the tree is now replaced by the Nil Sentinel node, followed by the insertion of the node we always color it red.
inserted code:
void Insert (int k) {
node* n = new node (k);
Node* y = nil_node;
node* x = root;
while (x!= nil_node) {//Find the appropriate insertion position, which is mainly satisfying the nature of the binary search tree
y = x;//y to record the position of x
if (X->key > K) {
x = X->l_chil D;
} else {
x = x->r_child;
}
}
N->parent = y; Found the appropriate insertion position, Y is the parent node for this position
if (y = = Nil_node) {//is an empty tree,
root = n;
} else if (Y->key > N->key) {//left section Dot
y->l_child = n;
} else {
y->r_child = n;//Right node
}
//handle nil
N->l_child = Nil_node ;
N->r_child = Nil_node;
Handles the insertion node's color
n->color = RED;
Adjust Operation
Rb_insert_fixup (n);
}
Here's the play, and let's take a look at how this adjustment function is implemented rb_insert_fixup.
To adjust, we first need to understand what to adjust, that is, our previous insert operation, will destroy the red-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 descendants ' nodes.
1, 3 nature is certainly satisfied, and for 5 properties, because we inserted the nodes are dyed red, so there is no more black nodes, so 5 nature can also be satisfied. May be the problem is 2, 4 properties, for 2nd nature, if inserted is an empty tree (only nil node), then the root node is red, it does 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 nature is not satisfied.
Processing Property 2:
For the nature of 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 Property 4:
And for the nature of 4th, the problem is the parent node is red, at this point to adjust the node and the parent node are red, does not meet the 4 nature, so we need to adjust the judgment condition is the parent node if red, you need to continue to adjust. Here in fact there are three kinds of cases, first of all already default Z's parent node z->p color is red, the loop condition is while (z->color==red):
condition One, Z's tert-node y is red, where z is the node to be adjusted (hereinafter):
Because Z's parent node z->p and the tertiary node are all red, the z->p->p of Z's grandfather node must be black, because it was a "good" red and black tree before it was inserted.
For this situation, the solution is: the z's parent node and the tert-node are dyed black, and the grandfather of Z Dye Red, after doing so, we carefully think about it, found that in fact, the current tree to go to the parent node or go the path of the number of the black node has no effect. Then we point the z point to the grandparent position of Z, and then we go on to the loop.
See here, you may not understand why to do so, in fact, we can see that the way we solve the problem is to change the color and rotation, where the z,z of the parent node, z of the tertiary nodes are red, if we simply use the rotation, in fact, there is no way to completely solve the problem, Because the relationship between the parent node and the tertiary node is "symmetric", here their color is also the same, all red, whether left or right can not completely solve the problem of the adjacent red node, such as: Our grandfather node 21 for the fulcrum, whether left or right, will find 11 and 13 or together, and red. So here we're going to dye it, 21 red, then the 13 and 22 black, which can solve the 11 and 13 are red, but can not solve 21 of the parent node is still red, in fact, we can not guarantee 21 of the parent node 9 is what color, so we can not use the rotation to solve, You can only point Z to 21 and throw the problem to the loop to continue processing.
condition Two, Z's tert-node y is black and z is a right child
The practice here is to convert the two situations into three situations, of course we have to use the rotation, but we do not want the position of Z to find change, so here first let z=z->p, and then z as the fulcrum of the left, because L will let Z down a level, so actually Z or point to the original layer of the node, Z- The position of the >p->p has not changed.
Here is just a simple conversion into situation three, with a focus on the situation three.
situation three, Z's tert-node y is black and z is a left child
In fact, Z and Z->p are all red, z->p->p and Z.->p->right are black, and what we want to do is to have more than one black node between z and z->p to satisfy the nature of 4, but at the same time we want to keep the nature of 5. So we deal with this:
Z->p dyed black, z->p->p dyed red, and then to the Z->p->p pivot to the right, this is done, as shown:
In the picture above, the first thing to be clear is that node 9 of the node is not nil, otherwise it is certainly unbalanced, so the occurrence of three must be in the loop, and not just after inserting. So now you can see why it's possible to solve the problem with a single stain and a right spin here:
① staining: By 21 dye black and 26 dye red, we can solve the nature of 4, but let the original 26-39 this path is less than a black node, will certainly destroy the nature of 5; So we're going to use the rotation
② left: For the right to spin here to solve the 26-39 route less a black node problem, but also to ensure the color nature of red and black.
First look at the node, we go through the right rotation (26 red as the fulcrum), let the 21 (black) rise to the Grandparent node, let 26 (red) fall into the right subtree, so that from the path of 21-9 black nodes are the same as before, and 21-39 of the right path, up a black node 21, so the nature of 5 is guaranteed.
Then look at the red-black nature, which is the nature of 4. After the rotation of the 21,9,26,39 four nodes to see, red-black properties can be guaranteed, the main focus on the right rotation process moved the original 21 node of the right Node A, after the right to move to 26 of the left subtree, then requires a must be a black node, then A is mody. It is certain that a must be, because before conversion 21-a this line to satisfy the nature 4, and only 9 and 21 are red will destroy the nature of 4, that is, except 21 and 9, the other parts of the red and black tree are satisfied with the nature of the red and black tree, so 21 this right node A is no exception, A is black, so bingo, Problem solved!
Through the above analysis of Nature 2 and 43 kinds of properties, it is not difficult to give the implementation code:
* * Repair color, because the insertion point, we always dye the first red, therefore, if the parent node is black, you do not need to repair, if the parent node is red, you need to repair * repair color is divided into three cases: *① the father of the current insertion point is red and the other node of the grandparent is red, and the parent node is a grandparent *② The parent node of the current insertion point is red, and the other node of the grandparent node is black, and the node is the parent node of the right child node *③ the current insertion point is red, and the other node of the grandparent node is black, and the node is the parent node of the left child nodes */void Rb_insert_f Ixup (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) {//Situation 1 processing nature 4 Z->parent->color = black; Situation 1 Z->parent->parent->r_child->color = black; Condition 1 z->parent->parent->color = RED; Conditions 1 z = z->parent->parent; Condition 1} else if (z = = z->parent->r_child) {//Case 2 z = z->parent; Conditions 2 left_rotate (z); Situation 2} else {//Case 3 Z->parent->color = black; Condition 3 Z->parent->parent->color = RED; Situation 3 Right_rotate (z->pArent->parent); Condition 3}} else {//When the parent node is the right child of the grandparent node, the difference is that all left operations and nodes are changed to the corresponding right-hand node* y = Z->parent->parent->l_chi
ld
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 of the N-node red-black tree height of O (LGN), so the time complexity of the insertion process is O (LGN), and for the adjustment process Rb_insert_fixup , only 1 let Z rise two levels, It is possible for a while to always occur, but due to the high tree limit, the time complexity is only possible in O (LGN), and for conditions 2 and 3, the program does not rotate more than two times. Because as long as the implementation of the 2 or 3,while cycle will be over. So the time complexity of inserting the whole node is O (LGN).
Next will be the red and black tree deletion node, please pay attention.