算法学习---红黑树

1、红黑树是二叉收索树的一种,可以保证在最坏情况系基本动态集合操作的时间复杂度为O(lgn)。本质是让树尽量均衡。
红黑树的定义(红黑树是在二叉收索树的基础上加上了下面的条件):
(1)每个节点或是红色的,或是黑色的。
(2)根节点和叶结点是黑色的。(红黑树中将NIL结点定义为也节点,称为外部结点;把带关键字的结点视为树的内部结点)。
(3)如果一个结点是红色的,则它的两个子结点是黑色的(父结点也是黑色的)。
(4)对每个结点,从该结点到其所有后代叶结点的简单路径上,均包括相同数目的黑色结点。(不含该结点的黑结点的数目称为黑高
2、引理:一颗有n个内部结点的红黑树的高度至多为2lg(n+1)。
证明:
3、代码的实现:
R_B_tree.h

#ifndef   __RedBlackTree
#define   __RedBlackTree
#include<iostream>
#include<queue>
using namespace std;
typedef enum NodeColor{
    RED,     
    BLACK
}NodeColor;
typedef  struct  Node{
    NodeColor  color;
    int   key;
    Node *left;
    Node *right;
    Node *parent;
}Node;
class RedBlackTree{
  public:
       RedBlackTree();                    //空树
      ~RedBlackTree();   
      Node *Search(int key);              //根据关键字key从根部查询节点,将节点返回
      Node *Minimum(Node *x);             //以x为根的红黑树的最小值
      Node *Maximum(Node *x);             //以x为根的红黑树的最大值
      Node *Successor(Node *node);        //后继
      Node *Predecessor(Node *node);      //前驱
      void  InsertNode(Node *node);       //将node结点插入root树
      void  InorderTreeWalk(Node *x);     //中序遍历
      void  DelleteNode(Node *z);         //删除节点
private:
      void  LeftRotate(Node *x);         //按x点左旋
      void  RightRotate(Node *y);        //按y点右旋
      void  InsertFixup(Node *z);        //插入节点后从新着色
      void  Transplant(Node *u,Node *v); //用v节点为根的子树替换u节点为根的子树
      void  DelleteFixup(Node *z);       //删除节点之后重新着色
private:
    Node  leaf;       //哨兵结点
public:
    Node  *root;       //树根 
};

#else
#pragma   message("--RedBlackTree已编译。")  
#endif

R_B_tree.cpp

#include"R_B_tree.h"
RedBlackTree::RedBlackTree(){
    this->leaf.color=BLACK;
    this->leaf.key=0;
    this->leaf.left=NULL;
    this->leaf.parent=NULL;
    this->leaf.right=NULL;
    root=&leaf;         //空红黑树
}
RedBlackTree::~RedBlackTree(){

}
Node * RedBlackTree::Minimum(Node *x){
    if( x==&leaf ){        //x为叶子
        return x;
    }
    while( x->left != &leaf ){
       x=x->left;
    }
    return x;            //最小
}
Node * RedBlackTree::Maximum(Node *x){
    if( x==&leaf ){        //x为叶子
        return x;
    }
    while( x->right != &leaf ){
       x=x->right;
    }
    return x;            //最大
}   
Node * RedBlackTree::Successor(Node *node){
    if(node==&leaf) return node;
    return Minimum(node->right);
}
Node * RedBlackTree::Predecessor(Node *node){
    if(node==&leaf) return node;
    return Maximum(node->left);
}
Node * RedBlackTree::Search(int key){
    Node  *x;
    x=root;
    while( x != &leaf && x->key != key ){
        if( x->key > key )x=x->left;
        else  if(x->key < key) x=x->right;
    }
    return x;    //查询失败是返回叶子结点
}
void RedBlackTree::LeftRotate(Node *x){
    Node  *y;
    y=x->right;
    x->right=y->left;
    if( y->left != &leaf ){
        y->left->parent=x;
    }
    y->parent=x->parent;
    if( x->parent == &leaf ){     //x为根
        root=y;
    }else{
        if( x == x->parent->left ){   //x为父结点的左孩子
            x->parent->left=y;
        }else{                       //x为右孩子
            x->parent->right=y;
        }
    }
    y->left=x;
    x->parent=y;
}
void RedBlackTree::RightRotate(Node *y){
    Node *x;
    x=y->left;
    y->left=x->right;
    if( x->right != &leaf){
      x->right->parent=y;
    }
    x->parent=y->parent;
    if( y->parent == &leaf ){
       root=x;
    }else{
        if( y->parent->left==y ){   //左边第一个结点
            y->parent->left=x;
        }else{
            y->parent->right=x;     //右边第一个结点
        }
    }
    x->right=y;
    y->parent=x;
}
void RedBlackTree::InsertFixup(Node *z){
    Node *y;
    while( z->parent->color == RED ){
        if( z->parent==z->parent->parent->left ){
           y=z->parent->parent->right;            //叔结点
           if( y->color==RED ){                   //情况一
               z->parent->color=BLACK;
               y->color=BLACK;
               z->parent->parent->color=RED;
               z=z->parent->parent;
           }else{
               if( z->parent->right == z ){       //情况二  右孩子
                   z=z->parent;
                   this->LeftRotate(z); 
               }
               z->parent->color=BLACK;            //情况三  左孩子
               z->parent->parent->color=RED;
               this->RightRotate(z->parent->parent);
           }
        }else{
           y=z->parent->parent->left;             //叔结点
           if( y->color==RED ){                   //情况一
               z->parent->color=BLACK;
               y->color=BLACK;
               z->parent->parent->color=RED;
               z=z->parent->parent;
           }else{
               if( z->parent->left == z ){       //情况二  左孩子
                   z=z->parent;
                   this->RightRotate(z); 
               }
               z->parent->color=BLACK;            //情况三  左孩子
               z->parent->parent->color=RED;
               this->LeftRotate(z->parent->parent);
           }
        }
    }
    root->color=BLACK;
}
void RedBlackTree::InsertNode(Node *node){
    Node *y,*x;
    y=&leaf;x=root;
    while( x!=&leaf ){
      y=x;
      if( node->key < x->key ){
          x=x->left;
      }else{
          x=x->right;
      }
    }
    node->parent=y;
    if( y == &leaf ){
       root=node;
    }else{
        if(node->key<y->key){
            y->left=node;
        }else{
            y->right=node;
        }
    }
    node->left=&leaf;
    node->right=&leaf;
    node->color=RED;
    this->InsertFixup(node);
}
void RedBlackTree::InorderTreeWalk(Node *x){    
    if( x != &leaf ){
        InorderTreeWalk(x->left);
        cout<<"key="<<x->key;
        if( x->color==RED ){
            cout<<" RED";
        }else{
            cout<<" BLACK";
        } 
        cout<<" parent_ket="<<x->parent->key<<"  key_left="<<x->left->key<<"  key_right="<<x->right->key<<endl;
        InorderTreeWalk(x->right);
    }
}
void RedBlackTree::Transplant(Node *u,Node *v){
    if(u->parent==&leaf){
       root=v;
    }else{
        if( u==u->parent->left ){
           u->parent->left=v;
        }else{
           u->parent->right=v;
        }
    }
    v->parent=u->parent;
}
void RedBlackTree::DelleteFixup(Node *z){
    Node *w;
    while( z!=root && z->color == BLACK ){
        if( z==z->parent->left ){
            w=z->parent->right;
            if( w->color==RED ){
                w->color=BLACK;
                z->parent->color=RED;
                this->LeftRotate(z->parent);
                w=z->parent->right;
            }
            if( w->left->color==BLACK && w->right->color==BLACK){
                w->color=RED;
                z=z->parent;
            }else{
                if( w->right->color==BLACK ){
                    w->left->color=BLACK;
                    w->color=RED;
                    this->RightRotate(w);
                    w=z->parent->right;
                }
                w->color=z->parent->color;
                z->parent->color=BLACK;
                w->right->color=BLACK;
                this->LeftRotate(z->parent);
                z=root;
            }
        }else{
            w=z->parent->left;
            if( w->color==RED ){
                w->color=BLACK;
                z->parent->color=RED;
                this->RightRotate(z->parent);
                w=z->parent->left;
            }
            if( w->left->color==BLACK && w->right->color==BLACK){
                w->color=RED;
                z=z->parent;
            }else{
                if( w->left->color==BLACK ){
                    w->right->color=BLACK;
                    w->color=RED;
                    this->LeftRotate(w);
                    w=z->parent->left;
                }
                w->color=z->parent->color;
                z->parent->color=BLACK;
                w->left->color=BLACK;
                this->RightRotate(z->parent);
                z=root;
            }   
        }
    }
    z->color=BLACK;
}
void RedBlackTree::DelleteNode(Node *z){
    Node *x,*y;
    NodeColor  y_original_color;
    y=z;
    y_original_color=y->color;
    if( z->left==&leaf ){
        x=z->right;
        Transplant(z,z->right);
    }else{
        if(z->right==&leaf){
           x=z->left;
           Transplant(z,z->right);
        }else{
            y=Minimum(z->right);
            y_original_color=y->color;
            x=y->right;
            if( y->parent==z ){
               x->parent=y;
            }else{
               Transplant(y,y->right);
               y->right=z->right;
               y->right->parent=y;
            }
            Transplant(z,y);
            y->left=z->left;
            y->left->parent=y;
            y->color=z->color;
        }
    }
    if(y_original_color==BLACK){
       DelleteFixup(x);
    }
    delete z;
}

main.cpp

#include<ctime>
#include"R_B_tree.h"
int main(){
   Node *newNode;
   RedBlackTree  RB;
   int i=4;
   srand(time(0));
   int kk;
   while(i<11){
      //kk=rand()%10+5;
      newNode=new Node;
      newNode->color=RED;
      newNode->key=i;
      newNode->left=NULL;
      newNode->right=NULL;
      newNode->parent=NULL;
      RB.InsertNode(newNode);
      i++;
   }
   cout<<"创建的红黑树"<<endl;
   RB.InorderTreeWalk((RB.root));
   if( RB.Search(RB.root->key)->key==0 ){
       cout<<"查询的结点不存在!"<<endl;
   }else{
       cout<<"查询的根节点结点为 "<<RB.Search(RB.root->key)->key<<endl;
   }
   RB.DelleteNode((RB.root));
   cout<<"删除根节点之后的红黑树 "<<endl;
   RB.InorderTreeWalk((RB.root));
   if( RB.Search(RB.root->key)->key==0 ){
       cout<<"查询的结点不存在!"<<endl;
   }else{
       cout<<"查询的根节点结点为 "<<RB.Search(RB.root->key)->key<<endl;
   }
   int asd;
   cin>>asd;
   return 0;
}

运行截图:
这里写图片描述
4、关于红黑树删除的一些说明
红黑树所有操作里,结点的删除是最复杂的,相关的删除的操作的详细过程可以看http://www.cnblogs.com/Anker/archive/2013/01/30/2882773.html博客,写的不错,看过之后容易明白。在这里我在添加关于4种情况的实例,从而可以更好理解红黑树删除时的四种情况。
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值