红黑树的建立,插入,删除

这个东西真的是很喜欢,但是学习了很长一段时间都很糊涂,先写了一个没有任何考虑特殊情况的红黑树,以后再想其他的吧。至于红黑树的扩张以后再想吧。

#include <stdio.h>
#include <malloc.h>
#define MAX 99999999
#define MIN -99999999
/*
        国庆在家无聊ing,由此学习一些树的数据结构,深深的为这些数据结构所震撼,牛呀。
        描述了红黑树的插入删除操作,这个数据结构真是变态,不过很好用,是可以扩充的树,喜欢!!!
        在随机的插入下,其搜索时间复杂度为O(lgn),这个是普通二叉树不可以相比的,
        之前和好多平衡树 ,区间树也是红黑树的扩充,当时看的很糊涂,现在终于理清楚了!!!
                                                                                          2007-10-04
*/
struct node
{
       long key;
       char color;
       struct node *p;
       struct node *left;
       struct node *right;      
};
struct node *head;
struct node *nil;

void INORDER_TREE_WALK(struct node* x)            //中根遍历
{
     //printf("%ld %c ",x->key,x->color);         //debug 先根遍历
     if(x->left!=nil) INORDER_TREE_WALK(x->left);
     printf("%ld %c ",x->key,x->color);
     if(x->right!=nil) INORDER_TREE_WALK(x->right);     
}

struct node *TREE_SEARCH(struct node* x,long k)    //查找关键字节点
{
       if(x==nil||x->key==k) return x;
       else if(k<x->key) return TREE_SEARCH(x->left,k);
       else  return TREE_SEARCH(x->right,k);      
}

struct node *TREE_MINIMUM(struct node* x)           //查找最小节点
{
     while(x->left!=nil)
     x=x->left;
     return x;    
}

struct node *TREE_MAXIMUM(struct node* x)           //查找最大节点
{
     while(x->right!=nil)
     x=x->right;
     return x;    
}

struct node *TREE_SUCCESSOR(struct node* x)          //查找后继
{
     if(x->right!=nil) return TREE_MINIMUM(x->right);
     struct node* y=x->p;
     while(y!=nil&&x==y->right)
     {
           x=y;
           y=y->p;                                                
     }  
     return y;    
}

struct node *LEFT_ROTATY(struct node *head,struct node *x)       //左旋转
{
     struct node *y=x->right;
     x->right=y->left;
     if(y->left!=nil) y->left->p=x;
     y->p=x->p;
     if(x->p==nil) head=y;
     else if(x==x->p->left) x->p->left=y;
     else x->p->right=y;
     y->left=x;
     x->p=y; 
     return head;   
}

struct node *RIGHT_ROTATY(struct node *head,struct node *x)       //右旋转
{
     struct node *y=x->left;
     x->left=y->right;
     if(y->right!=nil) y->right->p=x;
     y->p=x->p;
     if(x->p==nil) head=y;
     else if(x==x->p->left) x->p->left=y;
     else x->p->right=y;
     y->right=x;
     x->p=y;
     return head;    
}

struct node *RB_INSERT_FIXUP(struct node *head,struct node *z)
{
     //INORDER_TREE_WALK(head);
     // printf(" insert/n");
     struct node *y=nil;
     while(z->p->color=='R')
     {
           if(z->p==z->p->p->left)
           {
              y=z->p->p->right;
              if(y->color=='R')
              {
                 z->p->color='B';
                 y->color='B';
                 z->p->p->color='R';
                 z=z->p->p;                
              }
              else if(z==z->p->right)
              {
                   z=z->p;
                   head=LEFT_ROTATY(head,z);
                  // INORDER_TREE_WALK(head);
                  // printf(" left/n");
                  // getchar();    
              }
              if(z!=head)
              {
                 z->p->color='B';
                 z->p->p->color='R';
                 head=RIGHT_ROTATY(head,z->p->p);
              }
              else
              head=RIGHT_ROTATY(head,head);
             // INORDER_TREE_WALK(head);
             // printf(" right/n");
             // getchar();                       
           }
           else
           {
              y=z->p->p->left;
              if(y->color=='R')
              {
                 z->p->color='B';
                 y->color='B';
                 z->p->p->color='R';
                 z=z->p->p;                
              }
              else if(z==z->p->left)
              {
                   z=z->p;
                   head=RIGHT_ROTATY(head,z);    
              }
              z->p->color='B';
              z->p->p->color='R';
              head=LEFT_ROTATY(head,z->p->p); 
           }                      
     }
     head->color='B';
     return head;   
}

struct node *RB_INSERT(struct node *head,struct node *z)
{
       struct node *y=nil;
       struct node *x=head; 
       while(x!=nil)
       {
            y=x;
            if(z->key<x->key) x=x->left;
            else x=x->right;            
       }
       z->p=y;
       if(y==nil)  head=z;
       else if(y->key>z->key) y->left=z;
       else y->right=z;
       //INORDER_TREE_WALK(head);
       //printf(" insert/n");
       head=RB_INSERT_FIXUP(head,z);
       return head;
}

struct node *RB_DELETE_FIXUP(struct node *head,struct node *x)
{
     struct node *w;
     while(x!=head&&x->color=='B')
     {
          if(x==x->p->left)        //如果x为左儿子
          {
             w=x->p->left;         //用w表示x的叔叔
             if(w->color=='R')     //当叔叔节点颜色为红时,需要处理颜色并左旋转转入下述情况
             {
                w->color='B';
                x->p->color='R';
                head=LEFT_ROTATY(head,x->p);
                w=x->p->right;               
             }
             if(w->left->color=='B'&&w->right->color=='B')   //当叔叔的孩子都为黑孩子时
             {
                w->color='R';
                x=x->p;                                            
             }
             else if(w->right->color=='R')    //当叔叔的孩子只有右孩子为黑孩子时,要右旋转转入下述情况
             {
                w->left->color='B';            //交换w和他左孩子的颜色并左旋
                w->color='R';
                head=RIGHT_ROTATY(head,w);
                w=x->p->right;
             }                                 //经过以上步骤使得x兄弟w是黑色,而且w的右孩子是红色的
             w->color=x->p->color;             
             x->p->color='B';
             w->right->color='B';
             head=LEFT_ROTATY(head,x->p);                
          }
          else
          {
             w=x->p->right;         
             if(w->color=='R')     
             {
                w->color='B';
                x->p->color='R';
                head=RIGHT_ROTATY(head,x->p);
                w=x->p->left;               
             }
             if(w->left->color=='B'&&w->right->color=='B')  
             {
                w->color='R';
                x=x->p;                                            
             }
             else if(w->left->color=='R')   
             {
                w->right->color='B';
                w->color='R';
                head=LEFT_ROTATY(head,w);
                w=x->p->left;
             }
             w->color=x->p->color;
             x->p->color='B';
             w->left->color='B';
             head=RIGHT_ROTATY(head,x->p);    
          }
          x->color='B';                                       
     }
     return head;
}

struct node *RB_DELETE(struct node *head,struct node *z)
{
       struct node *x,*y;
       if(z->left==nil||z->right==nil) y=z;
       else y=TREE_SUCCESSOR(z);
       if(y->left!=nil) x=y->left;
       else x=y->right;
       if(x!=nil) x->p=y->p;
       if(y->p==nil) head=x;
       else if(y==y->p->left) y->p->left=x;
       else y->p->right=x;
       if(y!=z)
       {
          z->key=y->key;
          z->color=y->color;       
       }
       if(y->color=='B')
       head=RB_DELETE_FIXUP(head,x);
       return head;     
}

struct node *NODE_CREAT(long k)             //创建节点
{
      struct node *tmp;
      tmp=(struct node*)malloc(sizeof(struct node));
      tmp->left=nil;
      tmp->right=nil;
      tmp->p=nil;
      tmp->color='R';
      tmp->key=k;
      return tmp;
}

void NIL_CREAT()
{
       nil=(struct node*)malloc(sizeof(struct node));
       nil->key=MIN;
       nil->color='B';
       nil->p=nil;
       nil->left=nil;
       nil->right=nil;
}

int main()
{
    long n,t,a[10]={4,1,3,2,16,9,10,14,8,7,};
    struct node *ty;
    NIL_CREAT();
    head=nil;
    ty=nil;
    for(int i=0;i<10;i++)
    head=RB_INSERT(head,NODE_CREAT(a[i]));
    INORDER_TREE_WALK(head);
    printf(" done/n");
    while(scanf("%ld",&n)==1&&n)
    { 
          ty=TREE_SEARCH(head,n);
          head=RB_DELETE(head,ty);
          INORDER_TREE_WALK(head);
          printf("/n");                
    } 
    return 0; 
}
 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值