#include<stdio.h>
#include<stdlib.h>
typedef int datatype ;
typedef unsigned int COLOR ;
enum {RED,BLACK};
typedef struct _rb_tree
{
COLOR color;
datatype low,high,max;
struct _rb_tree * parent;
struct _rb_tree * lchild;
struct _rb_tree * rchild;
}rbtree;
typedef struct _rb_root
{
rbtree * root = NULL;
}rbroot;
void left_rotate(rbroot * T,rbtree* node);
void right_rotate(rbroot * T,rbtree* node);
void insert_data(rbroot*T,datatype low,datatype high);
void insert_item(rbroot*T,rbtree *item);
void insert_fixup(rbroot*T,rbtree* item);
void pre_visit(rbtree * tree);
void rb_transplant(rbroot *T,rbtree * from ,rbtree * to);
void delete_item(rbroot *T,rbtree * item);
void delete_fixup(rbroot *T,rbtree * parent,rbtree * item);
rbtree* tree_minimum(rbtree * tree);
void updateMax(rbtree*parent,rbtree* item);
void left_rotate(rbroot * T,rbtree* node)
{
rbtree *right = NULL;
right = node->rchild;
node->rchild = right->lchild;
if ( NULL != right->lchild )
{
right->lchild->parent = node;
}
right -> parent = node -> parent;
if ( NULL == node -> parent )
{
T->root = right;
}
else if( node == node->parent->lchild )
{
node->parent->lchild = right;
}
else
{
node->parent->rchild = right;
}
right->lchild = node;
node->parent = right;
if (NULL == right->lchild->rchild )
{
right->lchild->max == right->lchild->high;
}
else
{
right->lchild->max == right->lchild->rchild->max;
}
}
void right_rotate(rbroot * T,rbtree* node)
{
rbtree *left = NULL;
left = node->lchild;
node->lchild = left->rchild;
if ( NULL != left->rchild )
{
left->rchild->parent = node;
}
left -> parent = node -> parent;
if ( NULL == node -> parent )
{
T->root = left;
}
else if( node == node->parent->lchild )
{
node->parent->lchild = left;
}
else
{
node->parent->rchild = left;
}
left->rchild = node;
node->parent = left;
if (NULL == left->rchild->lchild )
{
left->rchild->max == left->rchild->high;
}
else
{
left->rchild->max == left->rchild->lchild->max;
}
}
void insert_data(rbroot*T,datatype low,datatype high)
{
rbtree * item = NULL;
item = ( rbtree * )malloc(sizeof(rbtree));
item -> lchild = item->rchild = item->parent = NULL;
item -> low = low;
item->max = item -> high = high;
item -> color = RED;
insert_item(T,item);
}
void insert_item(rbroot*T,rbtree *item)
{
rbtree * pre = NULL , *temp = T->root ;
while ( NULL != temp )
{
pre = temp;
if (item-> low < temp-> low)
{
temp = temp->lchild;
}
else
{
temp = temp->rchild;
}
}
item->parent = pre;
if ( pre == NULL )
{
T->root = item;
}
else if( item -> low < pre -> low )
{
pre -> lchild = item;
}
else
{
pre -> rchild = item;
}
updateMax(pre,item);
insert_fixup(T,item);
}
void insert_fixup(rbroot*T,rbtree* item)
{
rbtree* uncle = NULL;
while (NULL != item->parent && RED == item->parent->color)
{
if ( item->parent == item -> parent -> parent -> lchild )
{
uncle = item -> parent -> parent -> rchild;
if ( NULL != uncle && uncle->color == RED )
{
item -> parent -> color = BLACK;
uncle -> color = BLACK;
item -> parent -> parent -> color = RED;
item = item -> parent -> parent;
}
else
{
if (item == item->parent->rchild)
{
item = item -> parent;
left_rotate(T,item);
}
item -> parent -> color = BLACK;
item -> parent -> parent -> color = RED;
right_rotate(T,item->parent-> parent);
}
}
else
{
uncle = item -> parent -> parent -> lchild;
if ( NULL != uncle && uncle->color == RED)
{
item -> parent -> color = BLACK;
uncle -> color = BLACK;
item -> parent -> parent -> color = RED;
item = item -> parent -> parent;
}
else
{
if (item == item->parent->lchild)
{
item = item -> parent;
right_rotate(T,item);
}
item -> parent -> color = BLACK;
item -> parent -> parent -> color = RED;
left_rotate(T,item->parent-> parent);
}
}
}
T->root->color = BLACK;
}
void delete_item(rbroot *T,rbtree * item)
{
rbtree * replace = NULL,*deletingItem = NULL,*parent = NULL;
COLOR deletingColor = RED;
deletingItem = item;
deletingColor = item->color;
if (NULL == deletingItem->lchild && NULL == deletingItem->rchild)
{
replace = NULL;
parent = deletingItem->parent;
if (NULL == deletingItem->parent)
{
T->root = NULL;
}
else
{
rb_transplant(T,deletingItem,replace);
}
}
else if ( NULL == deletingItem->lchild )
{
replace = deletingItem->rchild;
parent = deletingItem->parent;
rb_transplant(T,deletingItem,replace);
}
else if(NULL == deletingItem->rchild)
{
replace = deletingItem->lchild;
parent = deletingItem->parent;
rb_transplant(T,deletingItem,replace);
}
else
{
/* 根据前面的条件判断,左右子树已经不会是空。*/
deletingItem = tree_minimum(deletingItem->rchild);
/*tree_minimum找到的是一个借点,肯定不为空。*/
deletingColor = deletingItem->color;
parent = deletingItem->parent;
replace = deletingItem->rchild;
if (item == deletingItem->parent)
{
/*
这种就是比较特殊的情况了
没有左子树,这种的parent的parent就事本身。
另一种是因为挂接,而且可以回溯。
这种如果是右孩子的右孩子为空,就无法回溯,通过给定的方式声明。
*/
parent = deletingItem;
}
else
{
rb_transplant(T,deletingItem,deletingItem->rchild);
deletingItem->rchild = item->rchild;
deletingItem->rchild->parent = deletingItem;
}
rb_transplant(T,item,deletingItem);
deletingItem->lchild = item->lchild;
deletingItem->lchild->parent = deletingItem;
deletingItem->color = item->color;
}
updateMax(parent,replace);
if (BLACK == deletingColor)
{
delete_fixup(T,parent,replace);
}
delete item;
}
void delete_fixup(rbroot *T,rbtree * parent,rbtree * item)
{
/*失去了一个black节点,那么也就是说原来的这个节点的黑高至少为2,那么兄弟节点肯定不为空。*/
rbtree * brother = NULL;
while ( item != T->root && (NULL == item || BLACK == item->color ))
{
if ( item == parent->lchild )
{
brother = parent->rchild;
if (RED == brother->color)
{
/*
parent肯定是黑色
这样做是为了交换,然后转化为相同子问题。即下面的三种情况。
这样就可以统一方便的处理。
*/
brother -> color = BLACK;
parent->color = RED;
left_rotate(T,parent);
brother = parent->rchild;
}
if ( ( NULL == brother->lchild || BLACK == brother->lchild->color ) && ( NULL == brother->rchild || BLACK == brother->rchild->color ))
{
/*左孩子的黑高降低了,将右孩子的黑高也降低,也就是右孩子设为红,如果父节点为黑,此时子树已经黑高平衡,但是因为降低了黑高,所以需要向上回溯。
如果是回溯到了root,则说明,整个降低了一层黑高。
如果说是回溯到了父亲节点为红色,也就只需要修改红色为黑色,就可以弥补两边的黑高不平衡了,变黑后,两边的黑高同时+1.
*/
brother->color = RED;
item = parent;
parent = parent->parent;
}
else
{
/*
到了这里,说明其中有一个为红,或者两个都为红
这个就可以通过旋转的方式弥补黑高。
前面的为什么不可以呢?因为旋转没有办法保证一定成功。
分析:
1. 如果父节点为红:
右子树就是黑
通过右旋转拉长,再左旋转升高变色平衡。
如果右子树的左孩子是空,就会失败,无法进行右旋转。所以只能回溯。
如果右子树的左孩子不空,且为黑,也就是黑高>3了。这个时候进行右旋转拉长。再左旋平衡。但是这个过程,右子树的左孩子不平衡。
如果右子树的左孩子不空,且为红,也就是现在的这种情况了。
2. 如果父节点是黑色:
右子树为红,无法旋转,因为嫁接过去的子树仍然不平衡。
右子树为黑,如上。
为什么下面的旋转以后可以呢?
1. 兄弟肯定有一个孩子为红,也就是说,兄弟肯定为黑。
左子树为红,则右旋,右边子树黑高不变。
坐旋转,嫁接变红,左边黑高变高,因为右子树为红,所以整体的平衡。
但是因为
*/
if ( NULL == brother->rchild || BLACK == brother->rchild->color )
{
/*
如果右子树为黑,也就是说左子树为红,这个操作主要是对右子树染红,如果本身就是红色就不用染色了。
到了这里,此时的条件就是,兄弟节点一定为黑色。
先进行变色右旋转,形成brother的左右平衡,且变高了一个。
旋转后需要跟新brother.这个时候的brother的左和新的节点黑高相同。只需要左旋转升高,嫁接变色就可以了。
这个操作是为了确保右边为红。
*/
brother->lchild->color = BLACK;
brother->color = RED;
right_rotate(T,brother);
brother = parent->rchild;
}
brother->color = parent->color;
/* brother 即将继承 parent的身份,颜色.*/
parent->color = BLACK;
/*parent 也即将降级左旋升高。左树黑高。*/
brother->rchild->color = BLACK;
/*因为之前就确保了右孩子为红,变黑右子树左旋转后黑高不变。*/
left_rotate(T,parent);
/*旋转之后已经平衡,所以退出循环*/
item = T->root;
}
}
else
{
brother = parent->lchild;
if (RED == brother->color)
{
brother -> color = BLACK;
parent->color = RED;
right_rotate(T,parent);
brother = parent->lchild;
}
if ( ( NULL == brother->lchild || BLACK == brother->lchild->color ) && ( NULL == brother->rchild || BLACK == brother->rchild->color ))
{
brother->color = RED;
item = parent;
parent = parent->parent;
}
else
{
if ( NULL == brother->lchild || BLACK == brother->lchild->color )
{
brother->rchild->color = BLACK;
brother->color = RED;
left_rotate(T,brother);
brother = parent->lchild;
}
brother->color = parent->color;
parent->color = BLACK;
brother->lchild->color = BLACK;
right_rotate(T,parent);
item = T->root;
}
}
}
if (NULL != item)
{
item->color = BLACK;
}
}
rbtree* tree_minimum(rbtree * tree)
{
while(NULL != tree && NULL != tree->lchild )
{
tree = tree->lchild;
}
return tree;
}
void updateMax(rbtree*parent,rbtree* item)
{
while ( NULL != parent && item == parent->rchild )
{
if( NULL == item )
{
parent->max = parent->high;
}
else
{
parent->max = item->max;
}
item = parent;
parent = parent->parent;
}
}
void rb_transplant(rbroot *T,rbtree * deleting ,rbtree * replace)
{
/* replace来充当继承人,deleting 和 replace 交接完父子关系之后就成了自由人。 */
if ( NULL == deleting->parent )
{
T->root = replace;
}
else if( deleting == deleting -> parent -> lchild )
{
deleting->parent->lchild = replace;
}
else
{
deleting->parent->rchild = replace;
}
if (NULL != replace)
{
replace->parent = deleting->parent;
}
}
void pre_visit(rbtree * tree)
{
if( NULL != tree )
{
pre_visit(tree->lchild);
printf("%d %d %d\n",tree->low,tree->high,tree->max);
pre_visit(tree->rchild);
}
}
int bh_find(rbtree * tree,int key)
{
while( NULL!= tree && tree->max >= key)
{
if( tree->low <= key && key < tree->high )
{
return 1;
}
else if(key < tree->low)
{
tree = tree->lchild;
}
else
{
tree = tree->rchild;
}
}
return 0;
}
int main()
{
rbroot root;
datatype datas[] = {1,2,3,4,5,6,7,8,2,3,4,5,6,7,7,9};
for( int i = 0 ; i < sizeof(datas)/sizeof(datatype); i+=2 )
{
insert_data(&root,datas[i]*datas[i+1],datas[i+1]*datas[i+1]);
}
pre_visit(root.root);
for( int i = 0 ; i < sizeof(datas)/sizeof(datatype); i++ )
{
printf("-------------------- ask --------------------\n");
printf("%d is %s\n",datas[i]*datas[i]+5,bh_find(root.root,datas[i]*datas[i]+5)?"in!":"not in.");
}
return 0;
}
来源:oschina
链接:https://my.oschina.net/u/3695598/blog/4281710