說明文檔能夠參照紅黑樹
#include<stdio.h>
#include<stdlib.h>
typedef int datatype ;
typedef unsigned int COLOR ;
enum {RED,BLACK};
typedef struct _rb_tree
{
COLOR color;
datatype key;
struct _rb_tree * parent;
struct _rb_tree * lchild;
struct _rb_tree * rchild;
}rbtree;
typedef struct _rb_root
{
rbtree * root = NULL;
}rbroot;
void insert_data(rbroot*T,datatype data);
void left_rotate(rbroot * T,rbtree* node);
void right_rotate(rbroot * T,rbtree* node);
void insert_data(rbroot*T,datatype data);
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 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;
}
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;
}
void insert_data(rbroot*T,datatype data)
{
rbtree * item = NULL;
item = ( rbtree * )malloc(sizeof(rbtree));
item -> lchild = item->rchild = item->parent = NULL;
item -> key = data;
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-> key < temp-> key)
{
temp = temp->lchild;
}
else
{
temp = temp->rchild;
}
}
item->parent = pre;
if ( pre == NULL )
{
T->root = item;
}
else if( item -> key < pre -> key )
{
pre -> lchild = item;
}
else
{
pre -> rchild = 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;
}
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 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 %s\n",tree->key,tree->color == RED ? "red" : "black");
pre_visit(tree->rchild);
}
}
void bh_visit(rbtree * tree,int rbh,int level)
{
if( NULL != tree )
{
bh_visit(tree->lchild,rbh+(tree->lchild == NULL || tree->lchild->color == BLACK),level+1);
bh_visit(tree->rchild,rbh+(tree->rchild == NULL || tree->rchild->color == BLACK),level+1);
}
else
{
printf("bh %d level %d\n",rbh,level);
}
}
int main()
{
rbroot root;
datatype datas[] = {1,2,3,4,5,6,7,8,2,3,4,5,6,7,7};
for( int i = 0 ; i < sizeof(datas)/sizeof(datatype); i++ )
{
insert_data(&root,datas[i]);
}
pre_visit(root.root);
bh_visit(root.root,1,1);
while(root.root && root.root->rchild)
{
printf("----------------- %d\n",root.root->key);
delete_item(&root,root.root->rchild);
pre_visit(root.root);
}
printf("start------after delete\n");
pre_visit(root.root);
printf("black high\n");
bh_visit(root.root,1,1);
printf("%x\n",root.root);
return 0;
}