Chapter 2 Introduction to algorithms-red and black trees

Source: Internet
Author: User

In practice, we do not directly use the Binary Search Tree, because the performance of the Binary Search Tree is heavily dependent on the insertion sequence of elements, especially when an element is inserted in an ascending manner, in this case, the binary search tree will become a linked list. In practical applications, we use the "balanced" binary search tree, including the AVL, red, black, and AA trees, the most commonly used is the red/black tree (the underlying implementation of the associated containers in STL is the red/black tree used), which ensures that the time complexity of basic dynamic set operations in the worst case is O (lgn)

The red/black tree adds a color attribute on each node, which can be red or black. Due to the nature of the red/black tree, no path can grow twice as long as other paths, therefore, it is "approximately balanced", but the red/black tree usually leads to a good balance. experience tells us that the average search efficiency of the red/black tree is equal to that of the AVL Tree.

The nature of the red/black tree:
1. Each node is either red or black;
2. The root node is black.
3. Each leaf node (null) is black.
4. If a node is red, its two child nodes are black.
5. For each node, the simple path from this node to all its descendant leaf nodes contains the same number of black nodes

Implementation Policy of the red/black tree:
Add sentinel: T. nil stands for nil, where T. nil is an object with the same attributes as a common node. All pointers to nil are directed to T. nil pointer replacement (mainly because nil cannot be colored)
We can add a sentry for each leaf node like figure (a), so that each Nil's parent node has a good definition, but it will waste a lot of space, so we only use one sentint. nil represents all nil: the parent node of all leaf nodes and root nodes.

We may wonder why we need to define a T. Nil? It is expressed by null. Is it black by default? STL does not have this sentry, but STL does not have a delete operation ------ as far as I know, T. the biggest role of Nil is the delete operation-its parent node can be changed to any node, which is used to trace back its parent node.

In the implementation of the Red-black tree, the height of the subtree can be changed, that is, the operation that can make it different from the general binary search tree is: rotation. Rotation can change the height of the sub-tree to maintain the property of the red/black tree:

The left-hand (X, Y are not T. Nil) is used to increase y and decrease X. It is mainly used to exchange parent-child relationships:

Left-rotate (t, x) y = x. Right X. Right = Y. Left if y. Left! = T. nil y. left. P = x Y. P = x. P if X. P = T. nil // X is the root T. root = y else if x = x. p. left X. p. left = y else X. p. right = y. left = x. P = y

Right hand:

RIGHT-ROTATE(T,x) y=x.left x.left=y.right if y.right!=T.nil   y.right.p=x y.p=x.p if x.p=T.nil   T.root=y elseif x==x.p.left   x.p.left=y else   x.p.right=y y.right=x x.p=y

Insert operation:

Insert operations are divided into two parts: insert and adjust;

If the nodes to be inserted are all red, the properties of the red and black trees are 1, 3, and 5 unchanged. When the original tree is empty, the properties of the tree are changed. 2. The nature of the tree may be changed. 4;

The subsequent adjustment is to make the properties 2 and 4 retained.

RB-INSERT (T, Z) y = T. Nil x = T. Root while X! = T. nil y = x if z. key <X. key x = x. left else x = x. right Z. P = y if y = T. nil T. root = z elseif Z. key <Y. key y. left = z else y. right = z // The following section is more than the common Binary Search Tree Z. left = T. nil Z. right = T. nil Z. color = Red RB-INSERT-FIXUP (T, Z) // Adjustment

The principle of adjustment is to move the nodes that break the rules up as much as possible. In the worst case, if you move the nodes up to the root node, you only need to set the root node to black.
The adjustment occurs in the following way: when the parent node of the inserted node is a red knot, the grandfather node must be black and the uncle node is unknown:

In this case, there are six situations. The following three situations are analyzed when the parent node of the inserted node is the left child of the grandfather node:

Case1: The primary node is red (the insertion node is left-side Insertion-External insertion, or right-side Insertion-interpolation)

At this time, as long as the C times are red, B, d is changed to black, and the Blak-height remains unchanged, the only node that may violate the nature is C, therefore, the node that breaks the rule is moved up.

Case2: The uncle node is black, and the inserted node is insert on the right --- interpolation:

We will change the inner side to the outer side to insert the parent node A of the inserted node to the left side. At this time, we will point Z to B and change it to the outer side, that is, the third case.

Case3: The uncle node is black, and the inserted node is left-side inserted --- external inserted

At this time, C is used as the pivot, right-handed, and B is changed to black, and C is changed to red.

RB-INSERT-FIXUP (T, Z) while Z. p. color = red if z. P = z. p. p. left y = z. p. p. right // uncle node if y. color = red // case1 Z. p. color = black y. color = black Z. p. p. color = Red z = z. p. P elseif z = z. p. right // case2 z = z. P left-rotate (T, Z) // insert it to the outside and execute case3 Z. p. color = black Z. p. p. color = Red Right-rotate (T, Z. p. p) else // Insert the parent node of the node. For the right child of the grandfather node, replace [left] with [right] T. root. color = black

The delete operation can be divided into two parts: delete and adjust

The first step is to delete the Helper Program-transplant. Replace the U-root subtree with the V-root subtree, which is usually applicable to the unique child knots of U.

RB-TRANSPLANT(T,u,v) if u.p==T.nil   T.root=v elseif u==u.p.left   u.p.left=v else u.p.rigth=v v.p=u.p

Delete programs from the same binary search tree. [See Binary Search Tree code parsing]

Focus on-Y: the node to be deleted from the tree or moved to the node in the tree (that is, the successor to the original node to be deleted)

If y is red, it is deleted directly without violating the nature;

If y is black, if y is the deleted node, the number of black nodes in any simple path containing y is less than 1. If Y is a mobile node, the same applies;

Here we adopt the following strategy:

If X is an element that replaces the position after deletion or movement of Y, there is still a heavy black color for X, but the problem now becomes: X is neither red nor black, violating Nature 1.

When X is the left child of its parent node:

Case0:

When X is single-weight black and single-weight red, the task is completed if X is directly set to black;

Case1: X is double black, and X's brother node W is red. At this time, X's parent node must be black:

What we need to do at this time is: change the color of B to red with the parent node B of X, and change the color of W to black. In this case, except for property 1, other properties are maintained.

<After case1, the brother node of X is Black>

Case2: X is double black, X's brother node W is black, and W's two child nodes are black:

In this case, the color of W turns red, removing the heavy black of X, and adding a heavy black to the X parent node. At this time, the only node that violates the nature is the parent node of X.

Case3: X is double black, X's brother node W is black, W's left child is black, and right child is Red:

Now we change W right, and C to the new W, C to black, d to red, and then to the fourth case.

Case4: X is double black, Brother node W is black, and W's right child is Red:

In this case, you can remove the heavy black -- of X --.

The RB-DELETE-FIXUP while X! = T. root and X. color = black // at this time, it is a two-digit black if x = x. p. left // when X is the left child of the parent node W = x. p. right // X's sibling node if W. color = red // case1 W. color = black X. p. color = Red left-rotate (t, x. p) W = x. p. rightif W. left. color = black and W. right. color = black // case2 W. color = Red X = x. pelseif W. right. color = black // case3 W. left. color = Black W. color = Red Right-rotate (T, W) W = x. p. right // case4 W. color = x. p. color X. p. color = Black W. right. color = Black left-rotate (t, x. p) x = T. root else left and right interchange X. color = bblack // case0

The following is a copy of the STL red/black tree. The simple version of The Red/black tree expands the binary search tree:

Related Keywords:
Related Article E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth \$300-1200 USD