The implementation of the red and black tree source code

Source: Internet
Author: User
Tags exit count printf

Recently, because of the support for CCache to join the red-black tree, find the code that has been implemented as a reference, this only to find that the original implementation is problematic, but also blame my test case writing is not good, just the insertion of the test, I have read this code and caused confusion of friends to apologize.

This time, all the code was rewritten, referenced the implementation algorithm of the red and black tree in the Linux kernel, and the test case was strengthened, hopefully this is the last revision of the red-black tree algorithm.

/*-----------------------------------------------------------
An implementation algorithm of Rb-tree insertion and deletion operation
Resources:
1) <<introduction to algorithm>>
2) http://lxr.linux.no/linux/lib/rbtree.c
Author: http://www.cppblog.com/converse/
You can freely spread, modify this code, reprint place Please indicate the original author
Several properties of red and black trees:
1 Each node is only red and black two colors
2) The root node is black
3 The Empty node is black (in the red and black tree, the parent of the root node and all leaf nodes lchild and rchild do not point to null, but point to a well-defined empty node).
4 If a node is red, then the color of its left and right two sub nodes is black
5 for each node, the black node on any path from this node to the leaf node
The same number of
-------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int key_t;
typedef int data_t;
typedef enum COLOR_T
{
RED = 0,
Black = 1
}color_t;
typedef struct RB_NODE_T
{
struct rb_node_t *left, *right, *parent;
key_t key;
data_t data;
color_t color;
}rb_node_t;
/* Forward Declaration * *
rb_node_t* Rb_insert (key_t key, data_t data, rb_node_t* root);
rb_node_t* Rb_search (key_t key, rb_node_t* root);
rb_node_t* rb_erase (key_t key, rb_node_t* root);
int main ()
{
int I, count = 900000;
key_t key;
rb_node_t* root = null, *node = NULL;
Srand (Time (NULL));
for (i = 1; i < count; ++i)
{
Key = rand ()% count;
if ((Root = Rb_insert (key, I, Root))
{
printf ("[i =%d] Insert key%d success!\n", I, key);
}
Else
{
printf ("[i =%d] Insert key%d error!\n", I, key);
Exit (-1);
}
if (node = Rb_search (key, Root))
{
printf ("[i =%d] search key%d success!\n", I, key);
}
Else
{
printf ("[i =%d] search key%d error!\n", I, key);
Exit (-1);
}
if (!) ( I% 10))
{
if ((Root = Rb_erase (key, Root))
{
printf ("[i =%d] Erase key%d success\n", I, key);
}
Else
{
printf ("[i =%d] Erase key%d error\n", I, key);
}
}
}
return 0;
}
Static rb_node_t* Rb_new_node (key_t key, data_t data)
{
rb_node_t *node = (rb_node_t*) malloc (sizeof (struct rb_node_t));
if (!node)
{
printf ("malloc error!\n");
Exit (-1);
}
Node->key = key, node->data = data;
return node;
}
/*-----------------------------------------------------------
| Node Right
| /\ ==>/\
| A right node Y
| / \ / \
| b y a B
-----------------------------------------------------------*/
Static rb_node_t* Rb_rotate_left (rb_node_t* node, rb_node_t* root)
{
rb_node_t* right = node->right;
if ((Node->right = Right->left))
{
right->left->parent = node;
}
right->left = node;
if ((right->parent = node->parent))
{
if (node = = node->parent->right)
{
Node->parent->right = right;
}
Else
{
Node->parent->left = right;
}
}
Else
{
root = right;
}
Node->parent = right;
return root;
}
/*-----------------------------------------------------------
| Node left
| / \ / \
| Left Y ==> a node
| / \ / \
| A b b y
-----------------------------------------------------------*/
Static rb_node_t* Rb_rotate_right (rb_node_t* node, rb_node_t* root)
{
rb_node_t* left = node->left;
if ((Node->left = left->right))
{
left->right->parent = node;
}
left->right = node;
if ((left->parent = node->parent))
{
if (node = = node->parent->right)
{
Node->parent->right = left;
}
Else
{
Node->parent->left = left;
}
}
Else
{
root = left;
}
Node->parent = left;
return root;
}
Static rb_node_t* rb_insert_rebalance (rb_node_t *node, rb_node_t *root)
{
rb_node_t *parent, *gparent, *uncle, *tmp;
while (parent = node->parent) && Parent->color = = RED)
{
Gparent = parent->parent;
if (parent = = Gparent->left)
{
Uncle = gparent->right;
if (Uncle && uncle->color = = RED)
{
Uncle->color = black;
Parent->color = black;
Gparent->color = RED;
node = gparent;
}
Else
{
if (parent->right = node)
{
Root = Rb_rotate_left (parent, root);
TMP = parent;
parent = node;
node = tmp;
}
Parent->color = black;
Gparent->color = RED;
Root = Rb_rotate_right (gparent, Root);
}
}
Else
{
Uncle = gparent->left;
if (Uncle && uncle->color = = RED)
{
Uncle->color = black;
Parent->color = black;
Gparent->color = RED;
node = gparent;
}
Else
{
if (Parent->left = node)
{
Root = Rb_rotate_right (parent, root);
TMP = parent;
parent = node;
node = tmp;
}
Parent->color = black;
Gparent->color = RED;
Root = Rb_rotate_left (gparent, Root);
}
}
}
Root->color = black;
return root;
}
Static rb_node_t* rb_erase_rebalance (rb_node_t *node, rb_node_t *parent, rb_node_t *root)
{
rb_node_t *other, *o_left, *o_right;
while ((!node | | node->color = black) && node!= root)
{
if (Parent->left = node)
{
other = parent->right;
if (Other->color = = RED)
{
Other->color = black;
Parent->color = RED;
Root = Rb_rotate_left (parent, root);
other = parent->right;
}
if (!other->left | | other->left->color = black) &&
(!other->right | | other->right->color = black))
{
Other->color = RED;
node = parent;
Parent = node->parent;
}
Else
{
if (!other->right | | other->right->color = black)
{
if ((O_left = Other->left))
{
O_left->color = black;
}
Other->color = RED;
Root = Rb_rotate_right (other, root);
other = parent->right;
}
Other->color = parent->color;
Parent->color = black;
if (other->right)
{
Other->right->color = black;
}
Root = Rb_rotate_left (parent, root);
node = root;
Break
}
}
Else
{
other = parent->left;
if (Other->color = = RED)
{
Other->color = black;
Parent->color = RED;
Root = Rb_rotate_right (parent, root);
other = parent->left;
}
if (!other->left | | other->left->color = black) &&
(!other->right | | other->right->color = black))
{
Other->color = RED;
node = parent;
Parent = node->parent;
}
Else
{
if (!other->left | | other->left->color = black)
{
if ((O_right = other->right))
{
O_right->color = black;
}
Other->color = RED;
Root = Rb_rotate_left (other, root);
other = parent->left;
}
Other->color = parent->color;
Parent->color = black;
if (other->left)
{
Other->left->color = black;
}
Root = Rb_rotate_right (parent, root);
node = root;
Break
}
}
}
if (node)
{
Node->color = black;
}
return root;
}
Static rb_node_t* rb_search_auxiliary (key_t key, rb_node_t* root, rb_node_t** Save)
{
rb_node_t *node = root, *parent = NULL;
int ret;
while (node)
{
parent = node;
RET = node->key-key;
if (0 < ret)
{
node = node->left;
}
else if (0 > Ret)
{
node = node->right;
}
Else
{
return node;
}
}
if (save)
{
*save = parent;
}
return NULL;
}
rb_node_t* Rb_insert (key_t key, data_t data, rb_node_t* root)
{
rb_node_t *parent = NULL, *node;
parent = NULL;
if (node = Rb_search_auxiliary (key, Root, &parent))
{
return root;
}
node = Rb_new_node (key, data);
Node->parent = parent;
Node->left = Node->right = NULL;
Node->color = RED;
if (parent)
{
if (Parent->key > key)
{
parent->left = node;
}
Else
{
parent->right = node;
}
}
Else
{
root = node;
}
Return Rb_insert_rebalance (node, root);
}
rb_node_t* Rb_search (key_t key, rb_node_t* root)
{
Return Rb_search_auxiliary (key, Root, NULL);
}
rb_node_t* rb_erase (key_t key, rb_node_t *root)
{
rb_node_t *child, *parent, *old, *left, *node;
color_t color;
if (!) ( node = Rb_search_auxiliary (key, Root, NULL))
{
printf ("Key%d is not exist!\n");
return root;
}
old = node;
if (Node->left && node->right)
{
node = node->right;
while (left = node->left)!= NULL)
{
node = left;
}
Child = node->right;
Parent = node->parent;
color = node->color;
if (child)
{
Child->parent = parent;
}
if (parent)
{
if (Parent->left = node)
{
Parent->left = child;
}
Else
{
Parent->right = child;
}
}
Else
{
root = child;
}
if (node->parent = = old)
{
parent = node;
}
Node->parent = old->parent;
Node->color = old->color;
Node->right = old->right;
Node->left = old->left;
if (old->parent)
{
if (Old->parent->left = = old)
{
old->parent->left = node;
}
Else
{
old->parent->right = node;
}
}
Else
{
root = node;
}
old->left->parent = node;
if (old->right)
{
old->right->parent = node;
}
}
Else
{
if (!node->left)
{
Child = node->right;
}
else if (!node->right)
{
Child = node->left;
}
Parent = node->parent;
color = node->color;
if (child)
{
Child->parent = parent;
}
if (parent)
{
if (Parent->left = node)
{
Parent->left = child;
}
Else
{
Parent->right = child;
}
}
Else
{
root = child;
}
}
Free (old);
if (color = black)
{
root = Rb_erase_rebalance (Child, parent, root);
}
return root;
}

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.