Red and black Trees
The red-black tree is a two-fork lookup tree , but adds a storage bit to the node's color at each node, either red or black. By limiting the shading of any one path from the root to the leaf,
The red and black tree ensures that no path will be twice times longer than the other path , and thus is nearly balanced. These operations perform faster when the height of the binary lookup tree is low, but when the height of the tree is high, the performance of these operations may
No better than using a chain list. The red-black tree is a balanced two-fork lookup tree that ensures that, in the worst case scenario, the basic dynamic operation set runs at O (LGN).
1. The nature of red and black trees
#define RED 0#define BLACK 1struct redblacktreenode{ T key; struct Redblacktreenode * parent; struct Redblacktreenode * left ; struct Redblacktreenode * Right ; int color;};
The properties of the red and black trees are as follows:
(1) Each knot is either red or black.
(2) The root node is black.
(3) Each leaf node (NIL) is black.
(4) If one of the nodes is red, then its two sons are black.
(5) For each node, the same number of black nodes are included on all paths from the node to its grandson node.
Hegau: The number of black nodes on any simple path that reaches a leaf node from a node x (without the node) is called the black height of the junction.
As: BH (x), Sentinel does not count dark high
As a red and black tree:
It can be seen from the graph that nil is not a null pointer, but a leaf node. the parent of the root node is also nil, which can be considered as a sentinel in practice, making it easy to operate on black red. The operation of the red and black tree is mainly to the internal node operation.
Because the internal node stores the value of the keyword. In order to facilitate discussion, the book ignores the leaf node, as the red-black tree becomes as shown:
The concept of black height is given in the book: The number of black nodes is called the black height of the node, starting from a node x (which does not contain the node) to any path to a leaf node. by the nature of the red-black tree (5),
All descent paths starting from this node have the same number of black nodes. The black height of the red black tree is defined as the black height of its root node.
The book gives a lemma to explain why the red and black tree is a good search tree, and the lemma has been proved (using inductive method to prove that the need for a strong inductive reasoning knowledge, it is my shortcomings, reading the pain lies in this).
Lemma: The height of a red-black tree with N nodes is 2lg (n+1).
Any sub-species with an X-root node contains at least 2^BH (x)-1 internal nodes.
The black height of the root is at least h/2, so n>= 2^ (H/2)-1
2. Rotation
For red and black trees, the Search/min/max is the same as the normal binary search tree. But delete and insert need to guarantee the nature of the red and black trees after operation, so we need to introduce the rotation here.
In the red Black tree node insertion and deletion operations, will change the structure of the tree shape, resulting in the result may not satisfy the red and black tree some properties, in order to ensure that after each insert and delete operation, still can be reported to maintain the nature of the red and black trees, need to change the tree
The color and pointer structure of some of the nodes in the The change in the pointer structure is done by rotation. Two kinds of rotations are given in the book: Left and right rotation. As the rotation process:
From the diagram can be drawn to the left and right rotation of the process, assuming that a node x rotation, Y is the child of X, then the left rotation process is: the chain between x and Y is "branch axis", so that the right child of X is the left child of Y, Y's parent node is the parent of X, Y's left child is X. The pseudo-code for left rotation is given in the book as follows:
Left_rotate (t,x) y = right[x] //Get Right child rihgt[x] = Left[y] //Set X right child for Y left child if left[y]! = NIL Then parent[left[x]] = x parent[y] = parent[x] //Set Y parent node to x parent if parent[x] = NIL then root[t] = Y
else if x==left[parent[x] then left[parent[x]] = y else right[[parent[x]] = y left[y] = x // Set Y's left child to x Parent[x] =y
Assuming that a node y is rotated right and X is the left child of Y, the left rotation process is: Y's left child is set to the right child of X, the parent of X is set to the parent of Y, and the right child of X is set to Y. There is no pseudo-code for right rotation in the book, which is easy to implement with reference to left-rotating pseudocode:
Right_rotate (t,y) x = left[y] //Get left child left[y] = right[x]//Set Y left child for x right child if right[x]! = NIL Then Parent[right[x]] = y parent[x] = Parent[y] //parent node of y as parent of x if parent[y] = NIL then root = x else if y== Left[parent[y]] then left[parent[y]] = x else right[parent[y]] = x right[x] = y//set X right child for Y
parent[y] = X
In order to better understand the rotation operation, the book gives a left rotation for example, as shown in:
2. Inserting algorithm of red and black tree
The insertion algorithm of red-black tree is improved on the basis of searching 溹 binary tree, because it satisfies the nature of search 溹 binary tree after inserting, but it may not satisfy the nature of the red-black tree, so we need to call Rb-insert-fixup
fixed into red and black trees. Its pseudo code is as follows: (Reference search binary tree insert:http://www.cnblogs.com/NeilZhang/p/5654393.html)
Rb_insert (t,z) y=NIL x=root (T) whileX! =NIL Doy=xifkey[z]<Key[x] then x=Left[x]Elsex=Right[x] Parent[z]=yify =NIL then root=ZElse ifKEY[Z] <Key[y] then Left[y]=ZElseRight[y] =Z left[z]=NIL Right[z]=NIL Color[z]= RED//The new Insert node is marked in red.Rb_insert_fixup (T,z)//make adjustments to meet the nature of the red-black tree
The main process of inserting red and black trees is the rb_insert_fixup process, and the book has a lot of space to introduce. First, it analyzes the properties of the red-black tree after inserting a new node, then classifies and discusses the possible destructive properties, and gives the solution. Because the new element is labeled red each time it is inserted, this may be 2 (the root node is black) and the property 4 (a red junction of the left and right children are black) is destroyed. For example, inserting a new node destroys the nature of 4.
If each insertion of a new node Z causes the nature of the red-black tree to be destroyed, then more than one property is destroyed, and not the nature of 2 is the nature of 4. Violation of the Nature 2 is because z is the root and red, violating the nature of 4 because Z and its parent node parent[z] are red.
If the nature of 2 is violated, then the red root must be the new node z, which is the only inner node of the tree, because Z's parent point and two children are nil (black), does not violate the nature of 4. Violation of Nature 2 during the entire insertion process only this time. So for
Violation of the nature of 2 of the node, directly its junction into Black can be.
The remaining problem is that the nature of the red-black tree has not been destroyed until the new node z is inserted, for a violation of the nature of 4. Insert Node Z after the violation of Nature 4, must be because Z and its Father node Parent[z] are red, at this time only violate the nature of 4, without violating
Other properties. Suppose the new insertion node z, causing the red black tree Nature 4 is destroyed, at this time Z and its parent node parent[z] are red, because the nature of the red and black tree before inserting node Z is not destroyed, parent[z] is red, it is easy to launch Z's grandfather node Parent[parent[z]
Must be black. At this time according to Parent[z] "is parent[parent[z]" the left child or right child to discuss. Because there is symmetry between the left and right, the book only gives Parent[z] as the left child of the parent[parent[z], and then gives three possible cases.
Case 1): Z's uncle Knot y is red
At this point parent[z] and y are all red, the solution is to set Z's parent node parent[z] and uncle Knot y both to black, and Z's grandfather node Parent[parent[z]] to red and then from grandfather Node Parent[parent[z]. Continue to determine whether the nature of the red-black tree is broken. The process is as follows:
Case 2): Uncle Z is black, and z is the right child
Condition 3): Uncle Z is black, and Z is the left child
In both cases 2 and 3, Y is black, which is distinguished by whether the child is left or right by Z. The condition 2 can be rotated to case 3. Case 2 Z is the right child, rotated to become a condition 3, making z into left child, you can use a left rotation at the parent[z] node to complete. Either indirectly or directly through condition 2 into the situation 3,z's uncle Y is always black. In case 3, parent[z] is "black, parent[parent[z]", and then a right rotation is made in red and then from Parent[parent[z]. Situation 2, 3 fixed a violation of the nature 4, the correction process will not cause other red and black properties are destroyed. The remediation process is as follows:
Give a complete example to illustrate the insertion process, as shown in
:
The book gives the pseudo-code of Rb_insert_fixup, the pseudo-code only gives the parent node of Z is the case of the left child, for the right child's situation and the left child's situation is symmetrical, just the left child to change to leave.
rb_insert_fixup (t,z) whileColor[parent[z]] =RED Do ifParent[z] = =Left[parent[parent[z] ] then y=Right[parent[parent[z] ]ifColor[y] = = RED//situation 1,z's uncle is redThen color[parent[z]] =BLACK Color[y]=BLACK Color[parent[parent[z]]=RED z=Parent[parent[z]]Else ifz = = Right[parent[z]]//situation 2,z Uncle for Black, Z for right childThen z =Parent[z] Left_rotate (t,z) Color[pa RENT[Z]]=black//situation 3,z Uncle for Black, Z for left childColor[parent[parent[z]] =RED right_rotate (T, parent[parent[z])Else(Same asThen clause with ' right ' and ' left ' exchanged) color (root (T))= BLACK;//set the root node to black
4. Delete
Deletion process is the most complex, see a lot of times to understand a probably, need to look repeatedly, many want to delete the process will destroy what nature, and then targeted to adjust.
Red-black Tree The deletion of the node process is the basis for improving the process of removing nodes in the binary lookup tree. Similar to the two-fork search tree, the deleted nodes are divided into three cases:<1> children, <2> left child or right child, <3> both tree = left child and right child. The removal process can refer to the previous log: Http://www.cnblogs.com/Anker/archive/2013/01/28/2880581.html. The red-black tree needs to be checked for damage to the properties of the red and black trees after deleting the nodes. If the deleted node Y is red, the deleted tree remains the property of the red-black tree because the nodes in the tree
The black height of the point does not change, there is no red node of two adjacent (parent node and sub-node), Y is red cannot be root, all roots are still black. If the deleted node Z is black, this destroys the nature of the red and black tree and calls Rb_delete_fixup to adjust. Removed from
The only child node Y knot x or nil place to start adjusting. The pseudo-code for Rb_delete is given in the book:
1 Rb_delete (t,z) 2 if left[z] ==nil or right[z] = = NIL 3 then y=z 4 else y=tree_successor (z) 5 if left [Y] = NIL 6 then X=left[y] 7 else X=right[y] 8 parent[x] = parent[y] 9 if p[y] ==nil10 then root [T] =x11 else if y = left[[prarnt[y]]12 then left[parent[y]] = x13 else Right[parent[y]] =x14 If y!=z15 then key[z] = key[y]16 copy Y's data into z17 if color[y] = = Black //When the deleted node is dark, adjust it 18
then rb_delete_fixup (t,x) return y
The book analyzes the problem that the deleted node Y is black: first, if y is the root and a red child of Y becomes a new root, it violates the nature of 2. Second, if X and Parent[y] (at this time parent[x] = Parent[y]) are red, it violates the nature of 4. Third, deleting y will result in a 1 reduction in the number of black nodes on any path that previously contained Y, violating the nature of 5. The book gives a solution to the third problem: set the node x to have an extra heavy black (see here is not very clear, my understanding is that regardless of the x is what color, will x add an extra heavy black, this can guarantee the number of black nodes increased by 1), will be any path containing the node x black node number plus 1, This ensures that the nature of 5 is established. When the black node Y is deleted, its black "push" to its sub-node, causing the problem to become a node x may not be red, not black, thus violating the nature of 1. Because x is added a color, that is, the node x is double black or red-black. This will contribute 2 or 1 to the number of black nodes on the path containing x respectively. But the color property of x is still red (if X is red-black) or black (if x is double black). In other words, the extra black of a node is reflected in the x pointing to it instead of its color property.
Process Rb_delete_fixup Recovery Properties 1,2,4. For the recovery Nature 2, 4 is very simple, because X is red, all directly to the X node is black. The book highlights how to restore the nature of 1. At this point, X is black and needs to be recovered depending on whether X is the left child or right child, since the left and the left are symmetrical, and only the X is the recovery process of the child. Take x as the first additional black node, cycle from the X-node, and move the extra black node up the tree until:
(1) x points to a red and black node, at which point x is individually black.
(2) x points to the root, which can simply eliminate the extra black, or
(3) Make the necessary rotation and color changes
In the loop, X always points to the non-root node with double black. Set W is the sibling node of x, because X is double black, so w cannot be nil. The book is divided into four kinds of situation discussion:
The situation 1:x's brother W is red
At this point because X is double black, contribute two black nodes, all w must have black children. In this case, W is black, parent[x] is red, and a left rotation is done on parent[x]. At this point the new brother W of X is black, so that the condition 1 is converted to conditions 2, 3 or 4. The process of scenario 1 is as follows:
The case of 2:x's brother W is black, and the two children of W are black.
The process is to remove a heavy black from X and W, that is, X has only one heavy black and w is red, and adds extra black to the parent node of x Parent[x]. The process is as follows:
Situation 3:x's brother W is Black, W's left child is red, right child is black
Swap the color of W and its left child left[w] and rotate the W right. After rotation X's new brother W is a black node with a red right child, converted into case 4. The process is as follows:
The case of 4:x's brother W is black, and the right child of W is red.
The procedure is to set the color of W to Parent[x], set the color of parent[x] to black, the right child of W to black, and then to the right of Parent[x], and finally set the X to root. The process is as follows:
The pseudo-code for Rb_delete_fixup is given in the book:
1 Rb_delete_fixup (t,x) 2 while x!= root[t] and Color[x] ==black 3 do if x = = Left[parent[x]] 4 Then W = right[parent[x]] 5 if color[w] = = Red//case 1 x brother W is Red 6 then Colo R[W] = BLACK 7 Color[parent[x]] = RED 8 left_rotate (T,parent[x]) 9 W = right[parent[x]]10 if color[left[w]] [= BLACK and Color[right[w]] = BLACK11 then color[w] = RED//case 212 x = parent[x]13 else if COLOR[RIGHT[W]] [=black14 then color[left[w]] = BLACK//case 315 COLOR[W] = RED16 right_rotate (t,w) 17 W = right[parent[x]]18 Color[w] = color[parent[x]]//case 419 COLOR[PARENT[X]] = BLACK20 Color[right[w]] = BLACK21 Left_rotate (T,parent[x]) x=root (T) all else (same as then clasue with "righ T "and" left "exchanged) Color[x]=black
Introduction to algorithms Part three--basic data structure--red-black tree