学习红黑树原理,网络上有很多文章。学习红黑树的具体实现,个人推荐去看JDK中的TreeMap源码。因为该源码很简洁,并且很容易改为其它语言的实现,最重要的是该份实现得到世人的认可,可以保证是没问题的代码。
下面是我根据其实现,使用c语言改写的红黑树实现,目前只有红黑树的插入实现。
#include <stdio.h>
#include <stdlib.h>
enum COLOR {
red,
black
};
typedef struct Node {
struct Node *left,*right,*parent;
int value;
int color;
} Node , *Tree;
Node* p(Node* x)
{
return x->parent;
}
Node* u(Node* x)
{
if(p(p(x))->left == p(x))
{
return p(p(x))->right;
} else {
return p(p(x))->left;
}
}
int color(Node* x)
{
if(x != NULL)
{
return x->color;
} else {
return black;
}
}
void ll(Tree &T,Node *x)
{
if(x->right != NULL)
{
Node *y = x->right;
x->right = y->left;
if(y->left != NULL)
{
y->left->parent = x;
}
y->parent = x->parent;
if(x->parent != NULL)
{
if(p(x)->left == x)
{
p(x)->left = y;
} else {
p(x)->right = y;
}
} else {
T = y;
}
y->left = x;
x->parent = y;
}
}
void rr(Tree &T,Node *x)
{
if(x->left != NULL)
{
Node *y = x->left;
x->left = y->right;
if(y->right != NULL)
{
y->parent = x;
}
y->parent = x->parent;
if(p(x) != NULL)
{
if(p(x)->left == x)
{
p(x)->left = y;
} else {
p(x)->right = y;
}
} else {
T = y;
}
y->right = x;
x->parent = y;
}
}
void fixupafterinsert(Tree &t,Node *x)
{
x->color = red;
while( x != NULL && x != t && p(x)->color == red )
{
if(p(p(x))->left == p(x))
{
//在左侧
if(color(u(x)) == red)
{
//叔的颜色是红色
p(x)->color = black;
u(x)->color = black;
p(p(x))->color = red;
x = p(p(x));//进入下次循环,进行调整
} else {
//叔的颜色是黑色,或者空
//判断在左还是右
if(p(x)->right == x)//因为最开始考虑的是左树,所以此处要先考虑右子
{
x = p(x);
ll(t,x);
}
//然后着色,父黑色,祖父是红色
p(x)->color = black;
p(p(x))->color = red;
rr(t,p(p(x)));
//此时黑色的父是根,x是左子,祖是右子
//调整完毕
}
} else {
//在右子树上
if(color(u(x)) == red)
{
p(x)->color = black;
u(x)->color = black;
p(p(x))->color = red;
x = p(p(x));
} else {
//考虑叔是黑色,或空
if(p(x)->left == x)
{
//右旋
x = p(x);
rr(t,x);
}
//着色,然后左旋
p(x)->color = black;
p(p(x))->color = red;
ll(t,p(p(x)));
}
}
}
//此处处理根
t->color = black;
}
void print(Node *x)
{
if(x != NULL)
{
print(x->left);
printf("%d ",x->value);
print(x->right);
}
}
void insert(Tree &t ,int n)
{
if(t==NULL)
{
t = (Node*)malloc(sizeof(Node));
t->left = NULL;
t->right = NULL;
t->value = n;
t->color = black;
} else {
Node* x = t;
Node* p = NULL;
while(x != NULL)
{
if(n < x->value)
{
p = x;
x = x->left;
} else {
p = x;
x = x->right;
}
}
x = (Node*)malloc(sizeof(Node));
x->left = NULL;
x->right = NULL;
x->value = n;
x->color = red;
x->parent = p;
if(n < p->value)
{
p->left = x;
} else {
p->right = x;
}
fixupafterinsert(t,x);
}
}
int main(void)
{
Node* root;
insert(root,30);
insert(root,50);
insert(root,60);
insert(root,60);
insert(root,70);
insert(root,10);
print(root);
return 0;
}
该源码确定能够运行。