1. 程式人生 > >紅黑樹的建立,插入,刪除

紅黑樹的建立,插入,刪除

這個東西真的是很喜歡,但是學習了很長一段時間都很糊塗,先寫了一個沒有任何考慮特殊情況的紅黑樹,以後再想其他的吧。至於紅黑樹的擴張以後再想吧。

#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; 
}