#include <iostream>
using namespace std;
struct TNode {
//节点颜色枚举类
enum RBColor
{
BLACK = 0,
RED = 1
};
int key;
RBColor color;
TNode* p;
TNode* left;
TNode* right;
};
class RBTree{
public:
//树根
TNode* root;
//nil几点
TNode* nil;
//黑高
int blackHeight;
RBTree() {
nil = new TNode;
nil->color = TNode::BLACK;
nil->key = -1; //没有任何意义,防止nil的值不确定
nil->p = nil->left = nil->right = nil;
root = nil;
blackHeight = 0;;
}
void RBInsertKey(int key);
void RBInsertFixup(TNode* z);
void RBLeftRoatate(TNode* x);
void RBRightRoatate(TNode* x);
void printRBTree(TNode* x);
void check(TNode* x);
};
void RBTree::RBLeftRoatate(TNode* x) {
TNode* y = x->right;
x->right = y->left;
//3条线,x-y.left,y-x.parent,x-y
if (y->left != nil) {
y->left->p = x;
}
y->p = x->p;
if (x == root) {
root = y;
}
else if(x->p->left == x){
x->p->left = y;
}
else {
x->p->right = y;
}
x->p = y;
y->left = x;
}
void RBTree::RBRightRoatate(TNode* x) {
TNode* y=x->left;
x->left = y->right;
if (y->right != nil) {
y->right->p = x;
}
y->p = x->p;
if (x == root) {
root = y;
}
else if (x->p->left == x) {
x->p->left = y;
}
else {
x->p->right = y;
}
x->p = y;
y->right = x;
}
void RBTree::RBInsertKey(int key) {
TNode* y = nil;
TNode* x = root;
while (x != nil) {
y = x;
if (x->key > key) {
x = x->left;
}
else {
x = x->right;
}
}
TNode* temp = new TNode;
temp->key = key;
temp->color = TNode::RED;
temp->p = y;
temp->left = temp->right = nil;
if (y == nil) {
root = temp;
}
else if(temp->key<y->key) {
y->left = temp;
}
else {
y->right = temp;
}
RBInsertFixup(temp);
}
void RBTree::RBInsertFixup(TNode* z) {
while (z->p->color == TNode::RED) {//父节点是红色
if (z->p == z->p->p->left) {//父节点是左孩子
TNode* y = z->p->p->right;//将y指向叔叔节点
if (y->color == TNode::RED) {//叔叔节点是红色(父红,叔红)
//case 1 变换颜色
//将叔叔节点和父节点都设为黑色
y->color = TNode::BLACK;
z->p->color = TNode::BLACK;
y->p->color = TNode::RED;//将祖父节点设为红
z = y->p;
}
else {//叔叔节点是黑色的或者为空(父红,叔黑)
//z是右孩子,以父节点左旋
if (z == z->p->right) {//case2
z = z->p;
RBLeftRoatate(z);
}
//case3,注意是先变色再旋转,而不是先旋转后变色,左旋之后节点变色,设置父亲为黑,祖父为红,
z->p->color = TNode::BLACK;
z->p->p->color = TNode::RED;
RBRightRoatate(z->p->p);
}
}
else {//父节点是右孩子
TNode* y = z->p->p->left;
if (y->color == TNode::RED) {
y->color = TNode::BLACK;
z->p->color = TNode::BLACK;
y->p->color = TNode::RED;
z = y->p;
}
else {
if (z == z->p->left) {
z = z->p;
RBRightRoatate(z);
}
z->p->color = TNode::BLACK;
z->p->p->color = TNode::RED;
RBLeftRoatate(z->p->p);
}
}
}
if (root->color == TNode::RED) {
blackHeight++;
}
root->color = TNode::BLACK;//设置根结点为黑色
}
void RBTree::printRBTree(TNode *x) {
if (x->left != nil) {
printRBTree(x->left);
}
cout<<x->key<<"\t"<<((x->color==TNode::BLACK)?"black":"red" )<<endl;
if (x->right != nil) {
printRBTree(x->right);
}
}
int main()
{
int key;
RBTree * t = new RBTree;
for(int i=1;i<=6;i++){
cin>>key;
t->RBInsertKey(key);
}
t->printRBTree(t->root);
return 0;
}
测试数据:
将关键字 41、38、31、12、19、8 连续地插入一棵初始化为空的红黑树
验证了算法的正确性
有个大佬的博客比我更详细:http://xiaoyblog.sinaapp.com/archives/537