/*
红黑树的性质:
1、每个结点或是红色,或是黑色
2、根结点是黑色
3、如果一个结点是红色,则它的两个子结点都是黑色
4、对每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点
5、所有叶子结点都是黑色
*/
#include "iostream"
using namespace std;
typedef enum node_color
{
BLACK,
RED
}NODECOLOR;
typedef struct Node
{
int value;
struct Node* parent;
struct Node* left;
struct Node* right;
NODECOLOR color;
}NODE,*NODE_POINT;
class Tree
{
private:
NODE_POINT root;
NODE_POINT* EMPTY;
void LEFT_ROTATE(NODE_POINT x);
void RIGHT_ROTATE(NODE_POINT y);
//插入时保持红黑性质
void RB_INSERT_FIXUP(NODE_POINT z);
//替换过程
void RB_TRANSPLANT(NODE_POINT u,NODE_POINT v);
//删除时保持红黑性质
void RB_DELETE_FIXUP(NODE_POINT x);
//删除所有结点
void DELETE_ALL_NODE(NODE_POINT node);
public:
Tree();
~Tree();
NODE_POINT MINIMUM(NODE_POINT x);
NODE_POINT MAXIMUM(NODE_POINT x);
NODE_POINT MAXIMUM();
NODE_POINT MINIMUM();
NODE_POINT SEARCH(NODE_POINT x,int k);
NODE_POINT SEARCH(int k);
NODE_POINT SUCCESSOR(NODE_POINT node);
void INSERT_NODE(int x);
void DELETE_NODE(int x);
};
void Tree::DELETE_ALL_NODE(NODE_POINT node)
{
if(node!=NULL)
{
DELETE_ALL_NODE(node->left);
if(node->right!=NULL)
{
DELETE_ALL_NODE(node->right);
}
free(node);
node=NULL;
}
}
Tree::~Tree()
{
DELETE_ALL_NODE(root);
}
Tree::Tree():root(NULL),EMPTY(NULL)
{
EMPTY=(NODE_POINT*)malloc(sizeof(NODE));
*EMPTY=NULL;
}
NODE_POINT Tree::MAXIMUM()
{
return MAXIMUM(root);
}
NODE_POINT Tree::MINIMUM()
{
return MINIMUM(root);
}
void Tree::RB_DELETE_FIXUP(NODE_POINT x)
{
while (x!=root&&x->color==BLACK)
{
if(x==x->parent->left)
{
/*
当x为其父结点的左孩子时,删除结点会有以下四种情况
1、x的兄弟结点node是红色
2、x的兄弟结点node是黑色,而且node的两个子结点都是黑色
3、x的兄弟结点node是黑色,node的左孩子是红色,node的右孩子是黑色
4、x的兄弟结点node是黑色,且node的右孩子是红色
x是取代要删除的结点的结点,当x为其父结点的右孩子时,情况类似(颠倒左右)
*/
NODE_POINT node=x->parent->right;
//情况1,左旋可转变为情况2、3、4
if(node->color==RED)
{
node->color=BLACK;
x->parent->color=RED;
LEFT_ROTATE(x->parent);
node=x->parent->right;
}
if(node->left==NULL)
{
//情况2
if(node->right==NULL||node->right->color==BLACK)
{
node->color=RED;
// RIGHT_ROTATE(node);
x=x->parent;//
}
}
else
{
//情况2
if(node->right==NULL)
{
if(node->left->color==BLACK)
{
node->color=RED;
// RIGHT_ROTATE(node);
x=x->parent;//
}
}
//情况2
else if(node->right->color==BLACK&&node->left->color==BLACK)
{
node->color=RED;
// RIGHT_ROTATE(node);
x=x->parent;//
}
else
{
//情况3,可右旋变为情况4
if(node->right->color==BLACK)
{
node->left->color=BLACK;
node->color=RED;
RIGHT_ROTATE(node);
node=x->parent->right;
}
//情况4
node->color=x->parent->color;
x->parent->color=BLACK;
LEFT_ROTATE(x->parent);
x=root;
}
}
}
else
{
NODE_POINT node=x->parent->left;
//情况1,右旋可转变为情况2、3、4
if(node->color==RED)
{
node->color=BLACK;
x->parent->color=RED;
RIGHT_ROTATE(x->parent);
node=x->parent->right;
}
if(node->left==NULL)
{
//情况2
if(node->right==NULL||node->right->color==BLACK)
{
node->color=RED;
// RIGHT_ROTATE(node);
x=x->parent;//
}
}
else
{
//情况2
if(node->right==NULL)
{
if(node->left->color==BLACK)
{
node->color=RED;
// RIGHT_ROTATE(node);
x=x->parent;//
}
}
//情况2
else if(node->right->color==BLACK&&node->left->color==BLACK)
{
node->color=RED;
// RIGHT_ROTATE(node);
x=x->parent;//
}
else
{
//情况3,左旋变为情况4
if(node->left->color==BLACK)
{
node->right->color=BLACK;
node->color=RED;
LEFT_ROTATE(node);
node=x->parent->right;
}
//情况4,右旋
node->color=x->parent->color;
x->parent->color=BLACK;
RIGHT_ROTATE(x->parent);
x=root;
}
}
}
}
x->color=BLACK;
}
void Tree::RB_TRANSPLANT(NODE_POINT u,NODE_POINT v)
{
if(u->parent==NULL)
{
root=v;
}
else if(u==u->parent->left)
{
u->parent->left=v;
}
else
{
u->parent->right=v;
}
if(v!=NULL)
v->parent=u->parent;
}
void Tree::DELETE_NODE(int k)
{
NODE_POINT z,y,x;
z=SEARCH(k);
if(z==NULL)
{
printf("此红黑树中不存在该结点\n");
return ;
}
else
{
y=z;
//用来保存y的颜色
NODECOLOR color;
color=y->color;
if(z->left==NULL)
{
x=z->right;
if(x==NULL)
{
//判断z是否为根结点
if(z->parent==NULL)
{
free(root);
root=NULL;
z=NULL;
return ;
}
else if(z==z->parent->right)
{
z->parent->right=NULL;
z->parent=NULL;
free(z);
z=NULL;
}
else
{
z->parent->left=NULL;
z->parent=NULL;
free(z);
z=NULL;
}
return;
}
RB_TRANSPLANT(z,x);
}
else if(z->right==NULL)
{
x=z->left;
RB_TRANSPLANT(z,x);
}
else
{
//寻找z的后继结点
y=SUCCESSOR(z);
color=y->color;
//如果y没有右孩子,说明它是叶结点,直接替换z就OK
if(y->right==NULL)
{
if(y->parent!=z)
{
//用NULL代替y的位置
RB_TRANSPLANT(y,NULL);
y->right=z->right;
y->right->parent=y;
}
RB_TRANSPLANT(z,y);
y->left=z->left;
y->left->parent=y;
y->color=z->color;
//删除z,释放空间
z->left=NULL;
z->right=NULL;
z->parent=NULL;
free(z);
z=NULL;
return ;
}
else
{
x=y->right;
}
if(y->parent==z)
{
x->parent=y;
}
else
{
RB_TRANSPLANT(y,x);
y->right=z->right;
y->right->parent=y;
}
RB_TRANSPLANT(z,y);
y->left=z->left;
y->left->parent=y;
y->color=z->color;
}
if(color==BLACK)
RB_DELETE_FIXUP(x);
}
if(*EMPTY)
{
delete *EMPTY;
if(*EMPTY==root)
{
root=NULL;
}
*EMPTY=NULL;
}
z->left=NULL;
z->right=NULL;
z->parent=NULL;
free(z);
z=NULL;
}
void Tree::RB_INSERT_FIXUP(NODE_POINT z)
{
if(z->parent!=NULL)
{
NODE_POINT y;
while(z!=root&&z->parent->color==RED)
{
if(z->parent==z->parent->parent->left)
{
if(root->right==NULL)
{
//如果z为其父结点的左孩子,则将原根结点变为它的右兄弟
if(z==z->parent->left)
{
root=z->parent;
z->parent->right=z->parent->parent;
z->parent->right->parent=z->parent;
z->parent->parent=NULL;
z->parent->right->left=NULL;
z->parent->right->color=RED;
root->color=BLACK;
return;
}
else
{
//如果z为其父结点的右孩子,将z变为根结点
root=z;
z->right=z->parent->parent;
z->right->parent=z;
z->right->left=NULL;
z->right->color=RED;
z->left=z->parent;
z->left->parent=z;
z->left->right=NULL;
root->color=BLACK;
return;
}
}
y=z->parent->parent->right;
/*
此时会有三种情况:
1、z的叔结点y是红色
2、z的叔结点y是黑色,且z是一个右孩子
3、z的叔结点y是黑色,且z是一个左孩子
情况1可转变成情况2、3
情况2可转变成情况3
当x的父结点是x的祖父结点的右孩子时,情况类似(左右颠倒)
*/
//情况1,可转变成情况2或3
if(y!=NULL&& y->color==RED)
{
z->parent->color=BLACK;
y->color=BLACK;
z->parent->parent->color=RED;
z=z->parent->parent;
}
else
{
//情况2,可转变成情况3
if(z==z->parent->right)
{
//z上移一层
z=z->parent;
//z左旋转,会下降一层
LEFT_ROTATE(z);
}
//情况3
//修正对性质3的违反,会破坏性质4
z->parent->color=BLACK;
z->parent->parent->color=RED;
//保持性质4
RIGHT_ROTATE(z->parent->parent);
}
}
else
{
if(root->left==NULL)
{
//z为其父结点的右孩子,则原根结点为它的左兄弟
if(z==z->parent->right)
{
root=z->parent;
z->parent->left=z->parent->parent;
z->parent->left->parent=z->parent;
z->parent->parent=NULL;
z->parent->left->right=NULL;
z->parent->right->color=RED;
root->color=BLACK;
return;
}
else
{
//如果z为其父结点的左孩子,将z变为根结点
root=z;
z->left=z->parent->parent;
z->left->parent=z;
z->left->right=NULL;
z->left->color=RED;
z->right=z->parent;
z->right->parent=z;
z->right->left=NULL;
root->color=BLACK;
return;
}
}
y=z->parent->parent->left;
if(y!=NULL&&y->color==RED)
{
z->parent->color=BLACK;
y->color=BLACK;
z->parent->parent->color=RED;
z=z->parent->parent;
}
else
{
if(z==z->parent->left)
{
z=z->parent;
RIGHT_ROTATE(z);
}
z->parent->color=BLACK;
z->parent->parent->color=RED;
LEFT_ROTATE(z->parent->parent);
}
}
}
}
root->color=BLACK;
}
void Tree::INSERT_NODE(int k)
{
//树为空,插入的为根节点
if(root==NULL)
{
root=(NODE_POINT)malloc(sizeof(NODE));
root->value=k;
root->parent=NULL;
root->left=NULL;
root->right=NULL;
root->color=BLACK;
}
else
{
NODE_POINT z;
NODE_POINT x,y;
z=(NODE_POINT)malloc(sizeof(NODE));
z->value=k;
x=root;
y=NULL;
while(x!=NULL)
{
y=x;
if(z->value<x->value)
{
x=x->left;
}
else
{
x=x->right;
}
}
z->parent=y;
if(y==NULL)
{
root=z;
}
else if(z->value<y->value)
{
y->left=z;
}
else
{
y->right=z;
}
z->left=NULL;
z->right=NULL;
z->color=RED;
RB_INSERT_FIXUP(z);
}
}
void Tree::RIGHT_ROTATE(NODE_POINT y)
{
if(y->parent!=NULL)
{
NODE_POINT x;
x=y->left;
y->left=x->right;
if(x->right!=NULL)
{
x->right->parent=y;
}
x->parent=y->parent;
if(y->parent==NULL)
{
root=x;
}
else if(y==y->parent->left)
{
y->parent->left=x;
}
else
{
y->parent->right=x;
}
x->right=y;
y->parent=x;
}
}
void Tree::LEFT_ROTATE(NODE_POINT x)
{
if(x->parent!=NULL)
{
NODE_POINT y;
y=x->right;
x->right=y->left;
if(y->left!=NULL)
{
y->left->parent=x;
}
y->parent=x->parent;
//x为根结点情况
if(x->parent==NULL)
{
root=y;
}
else if(x==x->parent->left)
{
x->parent->left=y;
}
else
{
x->parent->right=y;
}
y->left=x;
x->parent=y;
}
}
NODE_POINT Tree::SUCCESSOR(NODE_POINT x)
{
//右孩子不为空
if(x->right!=NULL)
{
return MINIMUM(x->right);
}
else
{
NODE_POINT y;
y=x->parent;
//右孩子为空,且自身为父节点右孩子
//(当为左孩子时,父节点为其后继节点,直接返回父节点)
while(y!=NULL&&x==y->right)
{
//当x位于根节点的右子树中,y最终为NULL
x=y;
y=y->parent;
}
return y;
}
}
NODE_POINT Tree::SEARCH(int k)
{
return SEARCH(root,k);
}
NODE_POINT Tree::SEARCH(NODE_POINT x,int k)
{
if(x==NULL||k==x->value)
{
return x;
}
if(k<(x->value))
{
return SEARCH(x->left,k);
}
else
{
return SEARCH(x->right,k);
}
}
NODE_POINT Tree::MINIMUM(NODE_POINT x)
{
if(x!=NULL)
{
while(x->left!=NULL)
{
x=x->left;
}
}
return x;
}
NODE_POINT Tree::MAXIMUM(NODE_POINT x)
{
if(x!=NULL)
{
while(x->right!=NULL)
{
x=x->right;
}
}
return x;
}
算法导论-----红黑树
最新推荐文章于 2024-06-24 10:08:14 发布