Recently took some time to regain the basic knowledge of data structure, first tried the red and black trees, spent most of the month to study its principles and implementation, the following is learned knowledge and some notes sharing. I hope you will advise me. The implementation of this code please click: Red black Tree Implementation code
Red and black tree basic knowledge definition
The red-black tree is a two-fork search tree with a color attribute, and the color value is red or black, so it's called a red-black tree.
The structure of each node of the red and black tree is defined as follows:
struct Rbnode { int color; void *key; void *value; struct rbnode * left; struct rbnode * right; struct rbnode *parent;};
The parent pointer that sets the root node points to null, and the left and right children of the new node point to null. The leaf node is null.
Defines a macro that determines the color of a red-black tree
#define Isred (x) ((x)! = NULL && (x)->color = = RED)
Therefore, the leaf node null color is non-red, in the red black tree, it is black, including the black leaf node.
The definition of black height, the number of black nodes on any simple path that is triggered from a node x (without the node) to a leaf node is called the black Height (black-height) of the node and is recorded as BH (x).
The nature of red and black trees
1, each node is not red is black;
2, the root node is black;
3, each leaf node is black;
4, if the node is red, then its two children nodes are black;
5. For each node, the path from the node to the leaf node contains the same number of black nodes.
Here is an example of a red-black tree
The rotation of the red and black trees
Rotation operations are often seen in tree data structures, such as AVL trees, red and black trees, and so on. A lot of people understand how rotation is done (how), and can find a lot of information on the web to describe the steps of rotation, but no one is telling me why. Why do you rotate like this? By communicating with friends, for the red and black trees, the reason is to rotate because of the height imbalance of the left and right sub-trees, that is, the Supi is taller or the right subtree is taller than the left sub-tree. Then, take the left-hand as an example, the left side of the tree can be the black height of +1, while the right subtree of black high-1, thereby restoring the black and high balance of the subtree.
Take the right spin for example, α and β for the children of the X, gamma is the right child of Y, because y of the Supi right sub-tree height more than one, so the y is the root of the sub-tree height imbalance, then the y-x axis left to the right side of the balance, and then Y and beta to become the children of X, but because to rotate the x and Y nodes So let Beta be the left child of Y.
Algorithm complexity of rotation
As shown in the illustration, the operation of rotation only modifies the pointer, so the algorithm complexity is O (1).
Analysis of algorithm complexity of red-black tree
The algorithm complexity of all operations of the red and Black Tree is O (LGN). This is because the maximum height of the red-black tree is 2LG (n+1).
The proof is as follows:
The number of black nodes that are set per path is BH (x)
To prove that the maximum height of the red-black tree is 2LG (n+1), it is first proven that any subtree contains 2^BH (x)-1 internal nodes.
The following is used to prove the mathematical inductive method.
When BH (x) equals 0 o'clock, that is, there are 0 nodes, then the subtree contains 2^0-1 = 0 internal nodes, proof.
For other nodes, the black height is BH (x) or BH (x)-1, when x is the red node, the black height is BH (x), otherwise, BH (x)-1. For the next node, because each child node is lower than the parent node's height, the generalization assumes that each child node has at least 2^ (BH (x)-1)-1 internal nodes, so that the subtree with the root x has at least 2^ (BH (x)-1)-1 + 2^ (BH (x)-1)-1 = 2^BH (x)- 1 internal nodes.
Set h is a tree height, according to the nature of 4 can be known, each path at least half of the nodes are black, so BH (x)-1 = H/2
Then the number of red-black tree nodes is n >= 2^ (H/2)-1.
Can get
> n + 1 >= 2^ (H/2)
Take the logarithm on both sides:
Log (n+1) >= H/2
= 2log (n+1) >= h
= h <= 2log (n+1)
By the above proof, the maximum height of the red-black tree is 2log (n+1), so the complexity of the red-black tree lookup is O (LGN). For the insertion and deletion of red and black trees, the algorithm complexity is O (LGN), so all operations of the red and black tree are the complexity of O (LGN).
Analysis of inserting operation of red and black tree
Red-black Tree insert operation, first find the location where you want the new node to be inserted, assign the node red, and then insert the new node. Finally do the nature of red and black tree repair.
Why the new node is giving Red
Because the insert operation can only violate the nature of 2, 4, 5, for the nature of 2, only need to directly black the root node, then the need to deal with the nature of 4 and the nature of 5, if the insertion of a black node, then will affect the new node is the subtree of the black height, which will violate the nature of 5, Then the newly inserted node will not violate the nature of 5, only need to deal with a violation of nature 2 or the nature of 4. That is, the root node is red or there are two contiguous red nodes. In short, it is to reduce the damage to the repair of red and black properties.
Insert algorithm pseudo-code
rb-INSERT (T, node) walk=T.root prev=NULL while(Walk! =NULL) Prev=Walkif(Node.key <Walk.key) Walk=Walk.leftElseWalk =walk.right node.parent=Walkif(Walk = =NULL) T.root=nodeElse if(Node.key <walk.key) Walk.left=nodeElseWalk.right =node RB-insert-fixup (T, node)
Insert algorithm flowchart
Plug-in fix
After insertion, if a new node (node) parent or root node (root) is red, it violates the nature of the red-black tree 4 or property 2. For the latter, you only need to darken the root directly.
The former, in violation of the nature of 4, that is, the red and black trees appear in a row of two red nodes of the situation. The change of the fix also depends on whether the parent node is the left child or the right child of the grandparent's node, and the left and left is symmetrical, where the parent node is seen as the child of the grandfather node. To restore the nature of the red-black tree, it is necessary to darken one of the parent, so that the node is located in the subtree of the black height +1, which will destroy the nature of 5, contrary to the original intention. It is therefore necessary to maintain the nature of the red-black tree with the black height of the other node (Uncle node) of parent->parent (grandparent).
If the uncle is red, the uncle is changed directly to Black, and the parent becomes black. But in this way, take grandparent as the root of the subtree of the black high +1, so the grandparent red so that its black height minus one, and then point node to grandparent, so that the repair node up to two level, until the root node is encountered.
If uncle is black, then you can't turn Uncle Black. Then the red node can only rise to the grandfather node, will be the grandfather knot red, and then turn the parent node black, so that the parent node as the root of the subtree of the left and right sub-tree is not balanced, at this time Supi of the tree's black height more than 1, then you need to turn the grandfather node right to adjust the left balance.
Pseudo-code to insert a repair algorithm
rb-insert-Fixup (T, node) whileis_red (node) parent= node->Parentif!is_red (parent) BreakGrandparent= parent->ParentifParent = =Grandparent.left Uncle=Grandparent.rightifis_red (uncle) Parent.color=BLACK Uncle.color=BLACK Grandparent.color=RED Node=Grandparent ElseIf Node==parent.right Left_rotate (T, parent) Swap (node, parent)ElseParent.color=BLACK Grandparent.color=RED right_rotate (T, grandparent)Elsesame asThen clause with" Right"and" Left"exchanged T.root.color= BLACK
Flowchart for inserting a repair algorithm
Algorithm complexity analysis for insertion
There are two main steps to inserting
A. Find the insertion position of the new node.
B, insert repair. While insert repair includes rotation and causes the repair node to rise.
For a, we can see from the above that the algorithm complexity of finding is O (LGN).
For b, the insertion repair, each repair node up to 2 levels, until the root node encountered, traversed by the maximum path is the height of the tree, the algorithm complexity is O (LGN), the description of the rotation can be the algorithm complexity is O (1), so the algorithm complexity of the insertion repair is O (LGN).
To sum up, the algorithm complexity of the insertion, O (insert) = O (LGN) + O (LGN) = O (LGN)
Delete operation analysis of red and black tree
Red black Tree Delete operation, first find the node to delete, and then find the successor to delete the node, with its successor to delete the location of the node, and finally do the red and black tree nature of the repair.
Red-black trees are more complex to delete than insert operations.
To delete a node, first find the location of the node, and then determine the subtree of node.
If node has only a subtree, replace it with node (successor).
If node has two subtrees, find node's successor and replace node.
If successor is the right child of node, replace successor directly with node, but you need to change the color of successor to node.
If successor is not the right child of node, and since node's successor has no left child (this can be checked for proof), after deleting node's successor successor, Successor's right child needs to be successor.right to successor position.
You need to save the color of successor in the removal process because the delete operation may cause the nature of the red-black tree to be corrupted, while the delete operation removes the successor. So, every time you change successor, color is updated.
Transplant action to use when deleting
Transplant (T, U, v) is the operation of the graft node, the function of which is to make the node v replace the node U position. Used in a delete operation to replace the successor node with the location where the node is to be deleted.
Delete the node's successor, no left child certificate.
Use X to indicate that there are non-empty left and right children's nodes. In the middle sequence traversal of the tree, the node of the left subtree of X is in front of X, and the node in the right subtree of x is behind X. Thus, the precursor of X is in its left sub-number, succeeding in its right subtree.
Suppose S is the successor of X. Then s cannot have left dial hand tree, because in the middle sequence traversal, S's left subtree will be in the middle of X and S. (after X is because it is in the right subtree of X, in front of s because it is in the left subtree of x.) In the middle sequence traversal, as in the previous hypothesis, if any node is between x and S, then the node is not the successor of X.
Delete algorithm pseudo-code
rb-DELETE (T, node) color=Node.color Walk_node=nodeifis_null (node.left) Need_fixup_node=node.right Transplant (T, node, need_fixup_node) ElseIf is_null (node.right) Need_fixup_node=node.left Transplant (T, node, Need_fixup_node)ElseWalk_node=Minimum (node.right) color=Walk_node.color Need_fixup_node=Walk_node.rightifWalk_node.parent! =node Transplant (T, Walk_node, walk_node.right) walk_node.right=node.right walk_node.right.parent=Walk_node Transplant (T, node, walk_node) Walk_node.left=Node.left walk_node.left.parent=Walk_node Walk_node.color=Node.colorifcolor = =BLACK RB-delete-fixup (T, Need_fixup_node)
Note: The author refers to the pseudo-code of the introduction of the algorithm, but at the time of implementation, NULL is used to represent the null node, and if the node to be repaired Need_fixup_node is empty, it cannot get its parent node, thus preserving its parent node Need_fixup_node_ The parent and its direction are direction to make adjustments to access their parent node and its direction when the repair is deleted.
Delete operation flowchart
Removal of repair operation analysis
You need to save the color of successor in the removal process because the delete operation may cause the nature of the red-black tree to be corrupted, while the delete operation removes the successor. So, every time you change successor, color is updated.
Will cause the nature of the red and black tree is destroyed is the successor color is black, when the color of successor is red, will not destroy the nature of red and black trees, for the following reasons:
Nature 1, remove the red knot, will not change the other node color, so will not be destroyed.
Property 2, if the deletion is a red node, then the node can not be a root node, so the nature of the root node will not be destroyed.
Properties 3, the color of the leaf node remains the same.
Nature 4, the deletion is the red junction, because the original tree is a red black tree, so it is impossible to appear in a row of two nodes for the red case. Because the delete is successor just replaces the position of node, but the color is changed to node's color. In addition, if successor is not the right child of node, then you need to first replace the successor right child Successor->right successor, if successor is red, then successor-> Right is definitely black, so it does not cause two consecutive red junction cases. Nature 4 is not destroyed.
Nature 5, removed is the red knot point, does not affect the black height, therefore the Nature 5 is not destroyed.
If the black junction is removed, the nature of the possible damage is 2,4,5. Reasons and recovery methods are as follows:
If node is black, its child is red, and node is root, then it will violate the nature of 2; (fix this property only need to darken root directly)
If successor and Successor->right are red after deletion, then it will violate the Nature 4; (direct successor->right Black to restore nature)
If the black node is deleted, it will result in a black junction on the path-1, which violates the nature of 5.
Then the nature of the remaining 5 is difficult to restore, it may be assumed that the successor->right has an extra black, then the nature of 5 will be maintained, and this will undermine the nature of 1. Because at this point the new_successor is double Black (BB) or Red-black (RB). Then you need to fix the color of the new_successor and move its "extra black" up to make its red-black tree intact.
Note: This assumption is only added to the New_successor node, not the color attribute of the node.
If it is a r-b situation, then only need to turn new_successor directly black, then "extra black" is moved up to New_successor, repair end.
In the case of BB, the extra layer of "extra black" needs to be moved up. Here also to see New_successor is the original parent node of the left child or right child, here set it as the left child, the situation of the child is symmetrical.
If the extra black is moved directly to the parent node, then the subtree with the parent node of New_successor will lose its balance because the black height of the Zuozi is 1. It is therefore necessary to consider the adjustment according to the brother's color of New_successor brothers.
If the brother is red, then the brother's two children and the parent are black, when the extra black can not be moved to the parent node, then you need to do some work, the brother and the parent color exchange, make brother Black, the parent becomes red, In this case, the brother is located in the Golt + 1, with the parent as the root to do a left-hand restore black high balance. After rotation, the parent is red, and one of the brother's children becomes the new Right child node of the parent, turning the brother back to the new sibling node and then thinking about other things.
If the brother is black, then it is necessary to move the black of the brother and the color of his child's knot by moving the black of the brother and the successor of the extra black to achieve the goal.
If Brother->right and Brother->right are both black, then it is good to move the black up directly, that is, Brother->color = RED. The node that contains the extra black now becomes the parent. The parent is RB or BB, and the loop continues.
If Brother->left->color =red,brother->right->color = BLACK, consider it in the final case. The brother->right will turn red. The conversion step is: Brother->left->color = Black;brother->color = RED. In this way brother's left subtree has a layer of black, right-handed brother, restoring properties. Then the brother points to the right node of the current parent, so now the brother->right is red. into a final case.
If Brother->right->color = RED. Then turn the brother->right black so that the brother's black can move up without damaging the red and black tree properties, and the move up step is to make brother into Brother->parent color,brother-> When the parent turns black, the black moves up. Then left-handed parent, so that the extra black of the successor is offset by a left-handed black. But the black height of the parent's right sub-tree is 1, and by just changing the brother->right to black it makes up for the Black Heights minus the right subtree. Now there is no extra black, end the fix, then let successor point to root and determine if root is red.
Remove repair algorithm pseudo-code
whileNode! = Root && Node.color = =BLACK) Parent=node.parentifnode =parent.left Brother=Parent.rightifis_red (brother) Brother.color=BLACK Parent.color=RED Left_rotate (T, parent) Brother=Parent.rightifBrother.left.color = = BLACK and Brother.right.color = =BLACK Brother.color=RED Node=Parent ElseIf Brother.right.color==BLACK Brother.left.color=BLACK Brother.color=RED right_rotate (T, brother) brother=Parent.rightElseBrother.color=Parent.color Parent.color=BLACK Brother.right.color=BLACK Left_rotate (T, parent) node=RootElse(Same asThen clause with ' right ' and ' left ' exchanged) Node.color= BLACK
Flowchart for deleting a repair algorithm
Algorithm complexity analysis for delete operations
The deletion of the operation mainly has to find the node to be deleted, after the removal of the repair.
Fix Red black tree nature is mainly rotation and node up. For the lookup, the algorithm complexity of the lookup is O (LGN), the complexity of the rotation is O (1), the node moves up, the path through the maximum is the high red and black trees, so the complexity of the upper node is O (LGN).
In summary, the complexity of the deletion algorithm is
O (DELETE) = O (LGN) + O (1) + O (LGN) = O (LGN)
Resource sharing
If you do not understand some of the steps, you can go to this site to see the red and black tree each step of the visualization process. [Red and Black Tree Visual website] (http://www.cs.usfca.edu/~galles/visualization/RedBlack.html)
The implementation of this code please click: Red black Tree Implementation code
Summarize
have been afraid to implement the red and black tree, because feel that they can not understand and realize, the inner fear has suppressed himself, but after several struggles, finally summon up the courage to study, found that as long as the intention to study, there is no solution can not solve the problem. Tangled up for a long time to send this blog post, this is just a record of knowledge notes, and do not dare to say to guide anyone, just want to share their notes recorded in the process of understanding, to the people in need. But in fact, think, tangled eggs, let the notes as semi-finished in the impression of sleep, it is better to spend time to improve the release, and then interested to continue to explore.
Original article, writing Limited, Caishuxueqian, if there is not in the text, million hope to inform.
If this article is helpful to you, please click on the recommendation, thank you ^_^
Red and Black tree discovery notes