这里只写了最重要的插入和删除操作,其他的搜索等操作 就懒得写了。
这里是
这里是
接下来是我的代码:
#ifndef RBTREE_H
#define RBTREE_H
template <typename T>
struct RBNode{
RBNode<T> *parent;
RBNode<T> *left;
RBNode<T> *right;
T value;
bool red;
RBNode(const T& x,RBNode<T>* p){
left = 0;
value = x;
red = true;
parent = p;
right = 0;
}
};
template <typename T>
class RBTree{
private:
RBNode<T> *root;
void LRotation(RBNode<T>* p);//左旋和右旋
void RRotation(RBNode<T>* p);
bool AdjustColor(RBNode<T> *p);
void AdjustAfterDelete(RBNode<T> *x,RBNode<T> *p);//必须要有一个父指针。
void GetParentLinked(RBNode<T> *a,RBNode<T> *b);
bool GetColorWithNULL(RBNode<T> *p){//由于没有哨兵节点,则需要考虑指针为空返回黑色。
if(p)return p->red;
else return false;
}
public:
RBTree(){
root = 0;
}
bool Search(const T &x);
bool Delete(const T &x);
bool Insert(const T &x);
};
//改变其向下的指针的同时要更新其父指针。
template <typename T>
void RBTree<T>::LRotation(RBNode<T>* p){
RBNode<T> *r = p->right;
if(p->parent){
if(p->parent->right == p) p->parent->right = r;
else p->parent->left = r;
r->parent = p->parent;
}else{
root = r;
r->parent = 0;
}
p->parent = r;
if(r->left)r->left->parent = p;
p->right = r->left;
r->left = p;
return ;
}
template <typename T>
void RBTree<T>::RRotation(RBNode<T>* p){
RBNode<T> *r = p->left;
if(p->parent){
if(p->parent->right == p) p->parent->right = r;
else p->parent->left = r;
r->parent = p->parent;
}else{
root = r;
r->parent =0;
}
p->parent = r;
if(r->right)r->right->parent = p;
p->left = r->right;
r->right = p;
return ;
}
template <typename T>
bool RBTree<T>::Insert(const T &x){
if(!root){
root = new RBNode<T>(x,0);
root->red = false;
return true;
}
RBNode<T>* p = root, *fa=root;
while(p){
fa = p;
if(x <p->value)
p = p->left;
else if(x > p->value)
p = p->right;
else
return false;
}
if(x < fa->value) p = fa->left = new RBNode<T>(x,fa);
else p = fa-> right = new RBNode<T>(x,fa);
AdjustColor(p);
return true;
}
template <typename T>
bool RBTree<T>::AdjustColor(RBNode<T> *p){
if( p == root){
p->red = false;
return true;
}
else if( ! p->parent->red )
return true;
else {
RBNode<T>* uncle, *f, *g;
f = p -> parent;
g = f->parent;
bool uncleColor;//由于叔叔节点可能为空
if(f == g->left)
uncle = g->right;
else
uncle = g->left;
if(uncle)uncleColor = uncle->red;
else uncleColor = false;
if(uncleColor){
uncle->red = false;
f->red = false;
g->red = true;
//将祖父节点设为红色
AdjustColor(g);
}else{
if(g->left == f){
if(f->left == p){
g->red = true;
f->red = false;
RRotation(g);
}else{
LRotation(f);
AdjustColor(f);
}
}else{
if(f->right == p){
g->red = true;
f->red = false;
LRotation(g);
}else{
RRotation(f);
AdjustColor(f);
}
}
}
}
return true;
}
template <typename T>
void RBTree<T>::GetParentLinked(RBNode<T> *a,RBNode<T> *b){
if(a == root){
root = b;
if(b)
b->parent = 0;
return;
}
if(a->parent->left == a){
a->parent->left = b;
if(b)
b->parent = a->parent;
}else{
a->parent->right = b;
if(b)
b->parent = a->parent;
}
}
template <typename T>
bool RBTree<T>::Delete(const T &x){
RBNode<T> *p = root ,*s,*fa;
if(!root)return false;
while(p){
if(p->value == x)break;
else if(x < p->value)p = p->left;
else p = p->right;
}
if(p){
if( p->left && p->right){//当存在左右孩子时,向下旋转
s = p->right;
while(s->left){
s = s->left;
}
int temp = p->value;
p->value = s->value;
s->value = temp;
p = s;
}
if(p->red){//为红色叶子节点,直接删除
GetParentLinked(p,p->left);
delete p;
}else{//为黑色时,将其红色子孩子替代他
//由于之前已经向下旋转,则这里只有一种特殊可能,即单支情况删除黑色根节点。
fa = p->parent;//之后可能没有父节点。
if(p->left){
s = p->left;
GetParentLinked(p,p->left);
}
else {
s = p->right;
GetParentLinked(p,p->right);
}
delete p;
AdjustAfterDelete(s,fa);
}
return true;
}else return false;
}
template <typename T>
void RBTree<T>::AdjustAfterDelete(RBNode<T> *x ,RBNode<T> *p){
if(p){//如果有父指针,则有四种情况。
RBNode<T> *w ;
bool inLeftTree = true;//标记左右情况,左右情况不同旋转方向以及判断方式也不同。
if(p->left == x)w = p->right;
else {
w = p->left;
inLeftTree = false;
}
if(w->red){
w->red = false;
p->red = true;
if(inLeftTree)
LRotation(p);//以p为支点进行旋转,不用考虑当前节点是否为空。
else
RRotation(p);
AdjustAfterDelete(x,p);
}else{
if( !GetColorWithNULL(w->left) && !GetColorWithNULL(w->right) ){
w->red = true;
x = p;
if(x ->red)x->red = false;//出错一次,要根据新的x节点进行判断。
else AdjustAfterDelete(x,x->parent);
}else if(( inLeftTree && GetColorWithNULL(w->right) ) //情况4
|| ( !inLeftTree && GetColorWithNULL(w->left) ) ){
bool tempRed = p->red;
p->red = w->red;
w->red = tempRed;
if(inLeftTree){
w->right->red = false;
LRotation(p);
}else{
w->left->red = false;
RRotation(p);
}
}else {//情况3
w->red = true;
if(inLeftTree){
w->left->red = false;
RRotation(w);
AdjustAfterDelete(x,p);
}else{
w->right->red = false;
LRotation(w);
AdjustAfterDelete(x,p);
}
}
}
}else{//如果不存在父节点,则此节点为根节点,则置为黑色结束。
if(x)
x->red = false;
return ;
}
}
#endif