算法学习---红黑树

来源:互联网 发布:mac 如何切换中英文 编辑:程序博客网 时间:2024/06/06 01:20

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
原创粉丝点击