Introduction to Algorithmic Learning---the insertion of specific interpretations of red and black trees (C language Implementation)

Source: Internet
Author: User

Before we learn binary search tree when hair now in some cases its height is not very uniform, and sometimes degenerate into a long chain, so we quoted some "balanced" two-fork search tree. The red and black tree is a "balanced" two-fork search tree, which ensures that in the worst case, the time complexity of the basic dynamic set operation is O (NLGN) by attaching the color bits and paths on each node. The following summarizes the nature of the red and black trees and then analyzes the insertion of the red and black trees. and give a complete code.

First give the red and black tree node definition:

#define RED 1#define BLACK 0///红黑树结点定义,与普通的二叉树搜索树相比多了一个颜色域struct node{      int///定义1为红,0为黑      node *p,*left,*right;      node(){         ///默认结点颜色为黑      }}*RBTree;

I. From the nature of the red and black trees
The red and black tree is a binary search tree, which adds a storage bit to each node to represent the color of the node. can be red or black. The red-black tree ensures that no path will be twice times longer than the other path, regardless of the node color on the simple path from root to leaf node. Thus is approximate to the equilibrium.

The following gives the red black tree Five "red black nature". These properties are the basis for subsequent insertions and deletions.
1). Each knot is either red or black.
2). The root node is black.


3). Each leaf knot is black
4). Suppose a node is red. Then its two sub-nodes are black.
5). For each node. The same number of black nodes are included in the simple path from the node to the leaf node of all its descendants.
We set the number of black nodes on a simple path from a node x (without the node) to a leaf node to the black height of the node, as BH (x). Obviously according to the nature of 5, each node of the black height is unique. Here we show that the height of a red black tree containing n internal nodes is at most 2LG (n+1).
First prove that at least 2^BH (x)-1 internal nodes are included in the subtree with either node x as the root. We use the mathematical induction method to summarize the black height of x.

Assuming that the black height of x is 0 or x is the leaf node, it is clearly correct.

The black height of x is BH (x), the black height of the two subtrees trees is BH (x) or BH (x)-1 (depending on their own color), it can be concluded that the corresponding internal node is at least 2^ (BH (x)-1)-1, that is, X includes the internal node is at least 2^ (BH (x) 1) -1+2^ (BH (x) -1) -1+1=2^BH (x)-1, therefore proof. And now we have n nodes with a height of H. Then, depending on the nature of 4, it is possible to know that at least half of the nodes on any simple path from the root to the leaf node (excluding the root node) are black. Therefore the black height of the tree is at least h/2; Then there is the above conclusion n>=2^ (H/2)-1. H<=2LG (n+1).

So we have proved that the dynamic set operation Search,minimum,successor and so on can be completed in the time complexity of O (LGN).

Here is a picture of a red and black tree.


Two. Rotation operation
In the subsequent insertion and deletion process will be destroyed by the nature of the red and black tree sent, in order to maintain these properties, it is necessary to change some nodes in the tree color and pointer structure.

The changes to the pointer structure are completed by rotation. Rotation is divided into left-and right-handed, and the two operations appear more than once in insert and delete operations. Let's analyze these two operations first.
The corresponding images for both operations are as follows:

As can be seen from the image, left-and right-handed operations are not very complex. The following is an example of left-handed analysis: we assume that the right son of node X is Y. The premise of the left is that the node must have a right son.

The result of the left-hand is: y instead of x,x becomes Y's right son. X becomes the left son of Y. The left son of Y becomes X's right son.

The following is a specific code implementation:

//L: Can be performed on a node with the right child at random./// pass in a reference to the node pointer to select/// rotate after X's right child y replaces x, and x becomes Y's left child, Y's left child becomes X's right child///The following code is finished with these three piecesvoidLeftrotate (Rbtree x) {Rbtree y=X -Right///y represents the right child of XX -Right=Y -Left///First step: Left child with X's right child set to Y      if(Y -Left!=Nul) y -Left -P=X Y -P=X -P///Change parent node of y to x      if(x -P==Nul)////second step: Y instead of X, need to be discussedRt=Y///x is the root node, set y as the root node .      Else if(x==X -P -left) x -P -Left=Y/// change y to x parent node's left child      ElseX -P -Right=Y/// change Y to the right child of X parent nodeY -Left=X///Step three: Left child with X set to YX -P=Y;}

Right-handed is similar to left-hand, with code such as the following:

//Right-turn: can be performed on whatever node has left child/// pass in a reference to the node pointer to be right-handed/// rotation after node x is replaced by left child y, X becomes the right son of Y, Y's right child becomes X's left childvoidRightrotate (Rbtree x) {Rbtree y=X -Left///y represents the left child of XX -Left=Y -Right///First step: X's left child changed to Y's right child        if(Y -Right!=Nul) y -Right -P=X Y -P=X -P///Change parent node of y to x        if(x -P==Nul)////second step: Y instead of X, need to be discussedRt=Y///x Original root node, specify Y as the new root node .        Else if(x==X -P -left) x -P -Left=Y/// Change x parent node's left child to Y        ElseX -P -Right=Y/// Change x parent node's right child to YY -Right=X///Step three: Change the right node of Y to xX -P=Y;}

Three. Insert a specific explanation
The difficulty in understanding the insertion and deletion of red and black trees is that there are too many things to do after we change a node.

We've also got the main approach: categorize the entire situation and then be able to understand why the code is written like this. In fact, just to understand the case in the introduction of the algorithm, the operation of the red and black tree is not difficult to understand.

The following applies the idea of classification discussion to understand the red-black tree insert operation.


First, let's give the code for the insertion section first:

/// red-black tree InsertThe ///rb insertion function is only slightly different from the normal BST insertion function.///// we replaced the original null with the NUL node, and then dyed it red for the newly added node .//// then call the Rbinsertfixup function to adjust so that the nature of the red and black tree is not destroyedvoidRbinsert (int key) {Rbtree Z=NewNode Z -Color=RED; Z -Key=Key Z -P=Z -Left=Z -Right=Nul; Rbtree y=Nul; Rbtree x=Rt while(x!=Nul)/// According to the nature of binary search tree to find the insertion point of Z{y=Xif(Z -Key<X -Key) x=X -LeftElseX=X -Right } Z -P=Yif(Y==Nul)/// The root node is insertedRt=ZElse if(Z -Key<Y -Key) y -Left=ZElseY -Right=Z Rbinsertfixup (z);/// inserting red nodes may violate certain properties of red and black trees, call adjustment function to adjust}

From the code point of view, the insertion here is not much different from the insertion of a two-fork search tree. Just add an Insert adjustment function at the end: Rbinsertfixup (). The reason to increase the adjustment function is that we insert a node and dye it red to cause a property of the red-black tree to be violated, so we need to focus on what is going to be a violation of that nature, and then we do so in the adjustment function of this kind of situation in the nature of the recovery.
First we set the insertion node to Z. Z will be dyed red when inserted.

Assume that the parent node of z is black. Will not violate whatever the nature. No need to adjust. So we just need to discuss the case where the parent node of z is red.

Then in such a case, only a property of 4 is bound to be violated. Then we press the parent node of Z to be the left son of his grandfather's node or the right son (there is no intrinsic difference between the two cases, just slightly different in coding). Let's just talk about the parent node of Z is the case of the left son of his grandfather's node. We then set the tertiary node of z (that is, the sibling node of the z parent node) as Y. Under these conditions, we will discuss the following categories:
1) Condition 1:y color is red
At this point the grandfather node must be black (due to the fact that the red-black tree was not violated before inserting the node).

In this case, we can dianran the parent knot of Z into black. Z's tertiary knot Dianran into black, and Z's grandfather knot Dianran red; Z's grandfather node below the subtree must be a legitimate red-black tree, but Z's grandfather node may violate the nature of 4. It is equivalent to ascending z in the tree by two layers (z=z->p->p).

This scenario assumes that the parent node of the new z is black and exits the loop (assuming that the new z is the root, it will definitely exit.) At this point the root node may be dyed red, so the root node needs to be dyed black after exiting the loop.


Examples of such conditions are the following:

2): The color of y is black
In the case where Y's color is black, we classify the left child or right child by Z as the parent node.
(1). Z is the left child of its parent node
At this point we can dianran the parent knot of Z into Black, and Z's grandfather knot Dianran Red. Then do a right-spin recovery for the grandfather node of Z 4, and do not violate the other nature (for this we can just draw one to be able to see very clearly).
(2). Z is the right child of its parent node
It is clear that this can be done by pointing Z to the parent node of Z and then turning the z once to the case (1).


Examples of these two situations are as follows: The picture of the situation on the two corresponding to our here (2), the situation three is for us here (1)

In general, only Y is black, and we can get out of the loop. The distinction between the two cases above is only a small shift in the internal structure.

Comprehensive. In fact, the red and black tree insert operation is mainly in violation of the nature of 4. The process of adjusting the function is the process of adjusting the property 4 by two kinds of cases. is not very complex. The above gives the case of the parent node of Z for its grandfather node left son. In fact, the situation is basically the same for the right son (see Code for details).
Another puzzling point is that the red-black tree's code is heavily used in the form of z->p->p, but does this really cause a null pointer exception? In this paper, the introduction of this algorithm is more specific argument.

Here I would like to briefly say my opinion: first, when inserting the root node, is not into the loop, so do not reference z->p->p. Then after inserting the root node. The grandfather nodes of each node outside the root node are always there, so the first reference will not be a problem. The problem is only possible if the z is now moved up in the tree (corresponding to 1), it may move up to a location. The parent node of this location does not have a parent node, which causes the null pointer to be critical, but we should note that this position is only likely to be the root node, and if z moves to the root, then it exits the loop because the parent node of the root is black! There is no longer a reference to a form such as z->p->p. So there's no need to worry about z->p->p. A null pointer exception appears in the reference.

The following is the code for the red-black Insert Adjustment function Rbinsertfixup () function, which corresponds to the three cases we discussed above:

/// Red black tree Insert Adjustment function//// We will insert knot Dianran into red, may violate the nature of 4, so to adjust///The process of adjustment is in fact a classification discussion based on different situations, the process of continuous conversion///finally turned into a condition capable of recovering by dyeing and rotationvoidRbinsertfixup (Rbtree z) {/// in the following code, the Z-node is always in violation of that node of Nature 4.      while(Z -P -Color==RED)///x is red, its parent node is also red, indicating that the nature of 4 is violated, to continue to adjust{///The following procedure is classified as the left child or right son of X->p's grandfather node.           if(Z -P==Z -P -P -Left/// parent node is the left child of his grandfather's knot .{Rbtree y=Z -P -P -Right/// represents the tertiary node of Z                 /// below to sort by the color of Y                 if(Y -Color==RED) {/// if y is red and Z's grandfather node must be black, then we pass the following dyeing process                   ///In the case of guaranteed black height (nature 5), Z is moved up two layers in the tree, Z=z->p->pZ -P -Color=BLACK; Y -Color=BLACK; Z -P -P -Color=RED; Z=Z -P -P///Assume that the loop is ended by moving up to the root node or a node with a parent node that is not red.}Else   /// tert-junction is black{/// At this point, we will discuss the classification according to the left child or right child whose parent node is Z .                   ///Assuming Z is the left child can directly recover by dyeing and right-handed                   /// assuming Z is the right child to turn left to the right child                      if(Z==Z -P -right) {Z=Z -P Leftrotate (z);/// Direct left-handed}//// dyeing again, then right-handed to restore propertiesZ -P -Color=BLACK; Z -P -P -Color=RED; Rightrotate (Z -P -p); }           }Else/// Father node is the right child of the grandfather's knot .{Rbtree y=Z -P -P -Left/// tert-Nodal points                  if(Y -Color==RED) {Z -P -Color=BLACK; Y -Color=BLACK; Z -P -P -Color=RED; Z=Z -P -P }Else{/// right son can be directly left-handed, and once again color recovery properties                   /// left son can turn right into right son and then deal with                         if(Z==Z -P -left) {Z=Z -P                         Rightrotate (z); } Z -P -Color=BLACK; Z -P -P -Color=RED; Leftrotate (Z -P -p); }           }     }/// dyeing the root node black is a necessary step. Deal with two kinds of situations     ///1. The first insertion of the root node is dyed red .     ///2. And in the above loop, the root node may be dyed red .Rt -Color=BLACK;}

Next: Algorithm Introduction learning-red black tree Specific explanation of the deletion

Introduction to Algorithmic Learning---the insertion of specific interpretations of red and black trees (C language Implementation)

Related Article

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.