红黑树实现代码

在算法导论中看了红黑树,没事儿就实现了一下,代码贴在下面。


#include <iostream>

using namespace std;

const int black = 1;
const int red = -1;
typedef struct node
{
    struct node* parent;
    struct node* lchild;
    struct node* rchild;
    int color;
    int data;
}node,*pnode;
typedef struct tree{
    node *root;
}tree;
node NIL={NULL,NULL,NULL,black,1943};//哨兵节点,1943是我的幸运数字哈,哨兵节点默认为黑色,树种用NIL代替null




void right_rotate(tree *t,node *x)//right_rotate
{
    if(x!=t->root){
      node* y = x->lchild;
      node* p = x->parent;
      if(x==p->lchild)
      {
          y->parent = p;
          p->lchild = y;
          x->parent = y;
          x->lchild = y->rchild;
          y->rchild->parent = x;
          y->rchild = x;
      }else{
          y->parent = p;
          p->rchild = y;
          x->parent = y;
          x->lchild = y->rchild;
          y->rchild->parent = x;
          y->rchild = x;
      }
    }else{
    node* y = x->lchild;
    x->lchild = y->rchild;
    y->rchild->parent = x;
    y->parent = x->parent;
    x->parent = y;
    y->rchild = x;
    t->root = y;
    }
}




void left_rotate(tree* t,node * x)//left_rotate
{
    if(x!=t->root){
      node* y = x->rchild;
      node* p = x->parent;
      if(x==p->lchild)
      {
          y->parent = p;
          p->lchild = y;
          x->parent = y;
          x->rchild = y->lchild;
          y->lchild->parent = x;
          y->lchild = x;
      }else{
          y->parent = p;
          p->rchild = y;
           x->parent = y;
          x->rchild = y->lchild;
          y->lchild->parent = x;
          y->lchild = x;
      }
    }else{
    node* y = x->rchild;
    x->rchild = y->lchild;
    y->lchild->parent = x;
    y->parent = x->parent;
    x->parent = y;
    y->lchild = x;
    t->root = y;
    }
}




void rb_insert_fixup(tree* t,node* n);//插入节点之后重新调整为红黑树调整为
void rb_insert(tree* t,node *n)//插入节点
{
    node* parent = t->root;
    node* p = parent;
    n->color = red;
    bool isLeft = false;
    while(p!=&NIL)
    {
        parent = p;
        if(p->data>n->data)
        {
            p = p->lchild;
            isLeft = true;
        }else{
            p = p->rchild;
            isLeft = false;
        }




    }
    if(isLeft)//插入节点为左儿子
    {
        parent->lchild = n;
        n->parent = parent;


    }else//插入节点为右儿子
    {
        parent->rchild = n;
        n->parent = parent;
    }
    if(parent->color==red)
    rb_insert_fixup(t,n);
    t->root->color = black;
}




void rb_insert_fixup(tree* t,node* n)
{
    node* p = n;
    while(p!=t->root&&p->parent!=t->root&&p!=&NIL)
    {
        if(p->parent==p->parent->parent->rchild)//插入节点的父是插入节点祖父的右儿子
        {
            if(p->parent->parent->lchild->color==red)//插入节点的叔叔是红色的
            {
                p->parent->color = black;
                p->parent->parent->lchild->color=black;
                p->parent->parent->color = red;
                p = p->parent->parent;
                continue;
            }else//插入节点的叔叔是黑色的
            {
                if(p==p->parent->lchild)
                {
                    right_rotate(t,p->parent);
                    left_rotate(t,p->parent);
                    p->color = black;
                    p->lchild->color = red;
                    break;
                }else
                {
                    left_rotate(t,p->parent->parent);
                    p->parent->color = black;
                    p->parent->lchild->color = red;
                    break;
                }




            }
        }else//插入节点的父是插入节点祖父的左儿子
        {
             if(p->parent->parent->rchild->color==red)
            {
                p->parent->color = black;
                p->parent->parent->rchild->color=black;
                p->parent->parent->color = red;
                p = p->parent->parent;
                continue;
            }else
            {
                if(p==p->parent->rchild)
                {
                    left_rotate(t,p->parent);
                    right_rotate(t,p->parent);
                    p->color = black;
                    p->rchild->color = black;
                    break;
                }else
                {
                    right_rotate(t,p->parent->parent);
                    p->parent->color = black;
                    p->parent->rchild->color = red;
                    break;
                }




            }
        }
    }
}

node* tree_successor(tree* t,node* n)//取节点n的后继节点
{
    node* p = n->rchild;
    node* parent = p;
    while(p!=&NIL)
    {
        parent = p;
        p = p->lchild;
    }
    return parent;
}

void rb_delete_fixup(tree* t,node* n);

node* rb_delete(tree* t,node* n)//删除节点
{
    node* p = t->root;
    node* parent = p;
    node* d = &NIL;
    node* replc = &NIL;
    bool isLeft = false;
    while(p!=&NIL)//找到n的位置,以防删除不存在节点
    {
         parent = p;
        if(p->data>n->data)
        {
           p = p->lchild;
           isLeft = true;
        }else{
           if(p->data<n->data)
           {
               p = p->rchild;
               isLeft = false;
           }else
           {
               break;
           }
        }
    }
    if(p==&NIL)
    {
        cout<<"element not exist"<<endl;
        return p;
    }
   if(n->lchild==&NIL||n->rchild==&NIL)//若n没有两个儿子
   {
       d = n;
   }else//n有两个宝贝儿子
   {
       d = tree_successor(t,n);//则删除他丫的后继,把n的值与后继的值对调,但是颜色不改变
   }
   if(d->lchild!=&NIL)//如果没有两个儿子则用其中一个儿子顶替父亲,(没有儿子则用右边的NIL节点顶上,NIL是一个哨兵节点)
   {
       replc = d->lchild;
   }else{
   replc = d->rchild;
   }

   replc->parent = d->parent;

   if(d->parent->lchild == d)
   {
       d->parent->lchild = replc;
   }else{
   d->parent->rchild = replc;
   }

   if(d!=n)
   {
       int temp = d->data;
       d->data = n->data;
       n->data = temp;
   }

   if(d->color==black)
   {
       rb_delete_fixup(t,replc);
   }
   d->lchild = &NIL;
   d->rchild = &NIL;
   d->parent = &NIL;
   return d;
}

void rb_delete_fixup(tree* t,node* n)//删除后如果有双黑节点则要重新调整树为红黑树
{
    node* p = n;
    while(p!=t->root)
    {
        if(p==p->parent->lchild)//双黑p是左儿子
        {
            if(p->parent->rchild->color == red)//p的兄弟是红色的
            {
                int temp = p->parent->color;
                p->parent->color = p->parent->rchild->color;
                p->parent->rchild->color = temp;
                left_rotate(t,p->parent);
                p->color = black;
            }else{
               if(p->parent->rchild->rchild->color==red)//p的远侄是红色的
               {
                   p->parent->rchild->color = p->parent->color;
                   p->parent->color = black;
                   p->parent->rchild->rchild->color = black;
                   left_rotate(t,p->parent);
                   break;
               }else{
                 if(p->parent->rchild->lchild->color==red)//p的近侄是红色的
                 {
                     right_rotate(t,p->parent->rchild);
                     p->parent->rchild->color = p->parent->color;
                     p->parent->color = black;
                     left_rotate(t,p->parent);
                 }else{//两个侄子都是黑色的
                      p->parent->rchild->color = red;
                      if(p->parent->color == red)
                      {
                          p->parent->color = black;
                          break;
                      }
                      p->color = black;
                      p = p->parent;
                 }
               }
            }
        }else{//p是右儿子

          if(p->parent->lchild->color == red)
            {
                int temp = p->parent->color;
                p->parent->color = p->parent->lchild->color;
                p->parent->lchild->color = temp;
                right_rotate(t,p->parent);
                p->color = black;
            }else{
               if(p->parent->lchild->rchild->color==red)
               {
                   p->parent->lchild->color = p->parent->color;
                   p->parent->color = black;
                   p->parent->lchild->lchild->color = black;
                   right_rotate(t,p->parent);
                   break;
               }else{
                 if(p->parent->lchild->rchild->color==red)
                 {
                     left_rotate(t,p->parent->rchild);
                     p->parent->lchild->color = p->parent->color;
                     p->parent->color = black;
                     right_rotate(t,p->parent);
                 }else{
                      p->parent->lchild->color = red;
                      if(p->parent->color == red)
                      {
                          p->parent->color = black;
                          break;
                      }
                      p->color = black;
                      p = p->parent;
                 }
               }
            }

        }


    }
    p->color = black;//最后双黑p调整为普通黑色
}

void printTree(node* n)//先序遍历输出。
{
    if(n!=&NIL)
    {
        cout<<n->data<<" - "<<n->color<<endl;
        printTree(n->lchild);
        printTree(n->rchild);
    }
    return;
}
int main()//简单测试了,没有问题。若错了,欢迎拍砖。=。=
{
    tree t;
    node ROOT={&NIL,&NIL,&NIL,black,5};
    node n1 = {&NIL,&NIL,&NIL,red,1};
    node n4 = {&NIL,&NIL,&NIL,red,4};
    node n7 = {&NIL,&NIL,&NIL,red,7};
    node n3 = {&NIL,&NIL,&NIL,red,3};
    node n6 = {&NIL,&NIL,&NIL,red,6};
    node n2 = {&NIL,&NIL,&NIL,red,2};
    node n8 = {&NIL,&NIL,&NIL,red,8};
    node n9 = {&NIL,&NIL,&NIL,red,9};
    t.root = &ROOT;
    rb_insert(&t,&n4);
    rb_insert(&t,&n3);
    rb_insert(&t,&n2);
    rb_insert(&t,&n1);
    rb_insert(&t,&n6);
    rb_insert(&t,&n7);
    rb_insert(&t,&n8);
    rb_insert(&t,&n9);
    rb_delete(&t,&ROOT);
    printTree(t.root);
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值