/*
**data structure-->rb_tree
**auther-->yejing
**data---->2014.8.5
**brief:红黑树五大特性
1,每个节点都有一个或红或黑的颜色
2,根节点是黑色的
3,叶节点都是黑的
4,如果一个节点是红的,那么它的两个子节点都是黑色的
5,对于任意一个节点,它到它的子孙节点的任意一条路径都有相同数目的黑色节点
**version->1.0(creat the file)
**test pc:ubuntu 12.14
*/
#include <stdio.h>
#include <stdlib.h>
enum color_t{
BLACK,
RED
};
typedef struct rb_node_t{
struct rb_node_t *parent, *left, *right;
int data;
int key;
color_t color;
}rb_node;
static rb_node* create_rb_tree(void){
rb_node* root = (rb_node*)malloc(sizeof(rb_node));
if(!root)
return NULL;
memset((char*)root, 0, sizeof(rb_node));
root->color = BLACK;
root->key = 1;
root->data = 0;
return root
}
static rb_node* left_rotate(rb_node* tree, rb_node* node){
if(!tree || !node)
return NULL;
rb_node* right = node->right;
//turn right's left subtree to node's
node->right = right->left;
if(right->left)//if it is exists
right->left->parent = node;
if(node == tree)//the node needs rotate is the root of the tree
node = right;
else{
if(node = node->parent->left)//the node needs rotate is the left subtree of its parent
node->parent->left = right;
else
node->parent->right = right;
right->parent = node->parent;
}
//connect right and node
right->left = node;
node->parent = right;
return tree;
}
static rb_node* right_rotate(rb_node* tree, rb_node* node){
if(!tree || !node)
return NULL;
rb_node* left = node->left;
node->left = left->right;
if(left->right)
left->right->parent = node;
if(node == tree)
tree = left;
else{
if(node->parent->right = node)
node->parent->right = left;
else
node->parent->left = left;
left->parent = node->parent;
}
node->parent = left;
left->right = node;
return tree;
}
static rb_node* search_pos(rb_node* tree, int key, int* match){
if(!tree)
return NULL;
rb_node* tmp = tree;
while(tmp){
if(tmp->key < key)
tmp = tmp->right;
else if(tmp->key > key)
tmp = tmp->left;
else{
*match = 1;
return tmp;
}
}
*match = 0;
return tmp;
}
static rb_node* rb_new_node(int key, int data){
rb_node* tmp = (rb_node*)malloc(sizeof(rb_node));
if(!tmp)
return NULL;
tmp->key = key;
tmp->data = data;
tmp->parent = tmp->left = tmp->right = NULL;
return tmp;
}
void rb_insert_fixup(rb_node* tree, rb_node* node){
if(!tree || !node)
return;
rb_node *parent, *uncle, *gparent, *tmp;
while(node->parnet && (parent = node->parent) && (parent->color == RED))//node的父节点存在,且为红色
{
gparent = parent->parent;//定义祖父节点
if(gparent && parent == gparent->left)//node的父亲是其祖父的左孩子
{
uncle = gparent->right;//定义叔父节点,此时叔父节点为其祖父的右孩子
if(uncle && uncle->color == RED){
parent->color = BLACK;
uncle->color = BLACK;
gparent->color = RED;
node = gparent;
}
else{//uncle为黑色
if(node == parent->right){//node为其父的右孩子
tree = left_rotate(tree, node);
tmp = parent;
parent = node;
node = tmp;
}
parent->color = BLACK;
gparent->color = RED;
tree = right_rotate(tree, node);
}
}
else//node的父亲是其祖父的右孩子
{
if(gparent)
{
uncle = gparent->left;//uncle为其祖父的左孩子
if(uncle && uncle->color == RED){
parent->color = BLACK;
uncle->color = BLACK;
gparent->color = RED;
node = gparent;
}
else{//uncle为黑色
if(node == parent->left)//node为其父的左孩子
{
tree = right_rotate(tree, node);
tmp = parent;
parent = node;
node = tmp;
}
parent->color = BLACK;
gparent->color = RED;
tree = left_rotate(tree, node);
}
}
}
}//end of while()
tree->color = BLACK;
return tree;
}
static rb_node* rb_node_insert(rb_node* tree, int key){
if(!tree)
return NULL;
rb_node* tmp;
rb_node* node;
int is_match = 0;
tmp = search_pos(tree, key, &is_match);
if(!tmp)
return NULL;
node = rb_new_node(key, 1);
if(!node)
return tree;
node->key = key;
node->color = RED;
node->parent = NULL;
node->left = NULL;
node->right = NULL;
if(key < tmp->key)
tmp->left = node;
else
tmp->right = node;
rb_insert_fixup(tree, node);
return tree;
}
/*
删除较插入要复杂一些,加上一份伪代码分析
RB-DELETE(T, z)
1 if left[z] = nil[T] or right[z] = nil[T]//有最多一个儿子
2 then y ← z
3 else y ← TREE-SUCCESSOR(z)//有两个儿子,取其右子树的最小值
4 if left[y] ≠ nil[T]//如果y的左子树非空
5 then x ← left[y]
6 else x ← right[y]
7 p[x] ← p[y]//处理y的父亲与其儿子之间的关系
8 if p[y] = nil[T]//如果y的父亲为空,即y为跟节点
9 then root[T] ← x
10 else if y = left[p[y]]//y是其父亲的左孩子
11 then left[p[y]] ← x
12 else right[p[y]] ← x//y是其父亲的右孩子
13 if y ≠ z
14 then key[z] ← key[y]
15 copy y's satellite data into z
16 if color[y] = BLACK //如果y是黑色的,
17 then RB-DELETE-FIXUP(T, x) //则调用RB-DELETE-FIXUP(T, x)
18 return y
//如果y不是黑色,是红色的,则当y被删除时,红黑性质仍然得以保持。不做操作,返回。
//理由:
//1,树中各节点的黑高度没有变化
//2,不存在两个相邻的红色节点
//3,如果y是红色的,就不可能是根,故根仍然是黑色的
*/
rb_node* rb_delete(rb_node* tree, rb_node* node){
if(!tree || !node)
return tree;
}
红黑树
最新推荐文章于 2024-12-11 00:02:12 发布