Red/Black Binary Search Tree definition:
1. Each node is either red or black.
2. The root node is black.
3. Red nodes can only have children of black nodes
4. For each node, the path from this node to its child node contains the same number of black nodes
Implementation of the data structure of the red/black tree:
Define the data structure:
# Define red_color 0
# Define black_color 1
Typedef struct red_black_tree_node
{
Int color;
Int data;
Red_black_tree_node * left;
Red_black_tree_node * right;
Red_black_tree_node * parent;
} Red_black_tree_node, * p_red_black_tree_node;
Red_black_tree_node * root_node = NULL;
Create a red/black tree:
Void create_red_black_tree (INT array_data [], int array_length)
{
Red_black_tree_node * P;
For (int I = 0; I <array_length; I ++)
{
P = new (red_black_tree_node );
If (p! = NULL)
{
P-> color = RED_COLOR;
P-> data = array_data [I];
P-> left = NULL;
P-> right = NULL;
}
Red_black_tree_insert (p );
}
}
Void red_black_tree_insert (red_black_tree_node * p)
{
If (root_node = NULL)
{
P-> parent = NULL;
P-> color = BLACK_COLOR;
Root_node = p;
}
Else
{
Red_black_tree_node * temp;
Temp = root_node;
While (temp! = NULL)
{
If (p-> data <= temp-> data) // left sub-tree
{
If (temp-> left! = NULL)
{
Temp = temp-> left;
}
Else
{
P-> parent = temp;
Temp-> left = p;
Break;
}
}
Else // right sub-tree
{
If (temp-> right! = NULL)
{
Temp = temp-> right;
}
Else
{
P-> parent = temp;
Temp-> right = p;
Break;
}
}
}
}
Red_black_tree_insert_fixup (p );
}
Void red_black_tree_insert_fixup (red_black_tree_node * p)
{
While (p-> parent! = NULL) & (p-> parent-> color = RED_COLOR ))
{
// Left sub red-black tree
If (p-> parent! = NULL) & (p-> parent = p-> parent-> left ))
{
// Case 1: has right red uncle
// Uncle_node = p-> parent-> right
If (p-> parent-> right! = NULL) & (p-> parent-> right-> color = RED_COLOR ))
{
P-> parent-> color = BLACK_COLOR;
P-> parent-> right-> color = BLACK_COLOR;
P-> parent-> color = RED_COLOR;
P = p-> parent;
}
Else // no right red uncle (has right black uncle)
{
// P is right child
If (p = p-> parent-> right)
{
P = p-> parent;
Left_rotate (p );
}
P-> parent-> color = BLACK_COLOR;
P-> parent-> color = RED_COLOR;
Right_rotate (p-> parent );
}
}
Else if (p-> parent! = NULL) & (p-> parent = p-> parent-> right) // right sub red-black tree
{
// Case 1: has left red uncle
If (P-> parent-> left! = NULL) & (p-> parent-> left-> color = red_color ))
{
P-> parent-> color = black_color;
P-> parent-> left-> color = black_color;
P-> parent-> color = red_color;
P = p-> parent;
}
Else // No left red uncle (has right black uncle)
{
If (P = p-> parent-> left)
{
P = p-> parent;
Right_rotate (P );
}
P-> parent-> color = black_color;
P-> parent-> color = red_color;
Left_rotate (p-> parent );
}
}
}
Root_node-> color = black_color;
}
Void left_rotate (red_black_tree_node * node)
{
If (node! = NULL)
{
Red_black_tree_node * right_node = node-> right;
Red_black_tree_node * parent = node-> parent;
If (right_node! = NULL)
{
Node-> right = right_node-> left;
If (right_node-> left! = NULL)
{
Right_node-> left-> parent = node;
}
Right_node-> parent = node-> parent;
If (parent! = NULL)
{
If (node = parent-> left)
{
Parent-> left = right_node;
}
Else
{
Parent-> right = right_node;
}
}
Else
{
Root_node = right_node;
}
Node-> parent = right_node;
Right_node-> left = node;
}
}
}
Void right_rotate (red_black_tree_node * node)
{
If (node! = NULL)
{
Red_black_tree_node * left_node = node-> left;
Red_black_tree_node * parent = node-> parent;
If (left_node! = NULL)
{
Node-> left = left_node-> right;
If (left_node-> right! = NULL)
{
Left_node-> right-> parent = node;
}
Left_node-> parent = node-> parent;
If (parent! = NULL)
{
If (node = parent-> left)
{
Parent-> left = left_node;
}
Else
{
Parent-> right = left_node;
}
}
Else
{
Root_node = left_node;
}
Node-> parent = left_node;
Left_node-> right = node;
}
}
}
The preceding steps show how to create a red-black tree. The difficulty of creating a red-black tree is to insert a new node and make some adjustments.
The color of each newly inserted node is red. If the parent node is black, you do not need to adjust it. If the parent node is red (the grandfather node must be black ),
There are six situations to consider when adjusting the inserted new node:
1. The parent node is the left node of the grandfather node, and the uncle (the right node of the grandfather node) is red. change the color of the parent node and the uncle node from red to black,
The color of the grandpa node is changed to red, and the new inserted node is changed again.
2. The parent node is the left node of the grandfather node, and the uncle (the right node of the grandfather node) is black or there is no uncle node. If the newly inserted node is the father
The right node of the Father's Day node is rotated left and the Father's Day node is adjusted as the newly inserted node.
3. The parent node is the left node of the grandfather node, and the uncle (the right node of the grandfather node) is black or there is no uncle node. If the newly inserted node is the father
The left node. Modify the father node to black, the grandfather node to red, and the grandfather node to make a right rotation. The adjustment is complete.
4. The parent node is the right node of the grandfather node, and the uncle (the left node of the grandfather node) is red. change the color of the parent node and the uncle node from red to black,
The color of the grandfather node is changed to Red. The grandfather node is regarded as the new inserted node and the adjustment continues.
5. The parent node is the right node of the grandfather node, and the uncle (the left node of the grandfather node) is black or there is no uncle node. If the newly inserted node is the father
The left node of the parent node is rotated Right at Father's Day, and the parent node is adjusted as the newly inserted node.
6. The parent node is the right node of the grandfather node, and the uncle (the left node of the grandfather node) is black or there is no uncle node. If the newly inserted node is the father
The right node of. Changed the father node to black, and the grandfather node to Red. The grandfather node made a left rotation and the adjustment was completed.
From this point of view, the red/black tree is a complicated data structure and requires careful construction.
All the above Code was modified and tested based on the pseudocode in the book <Introduction to algorithms>.