• 红黑树总结


    1.红黑树的性质。

      1)根节点是黑色。

      2)所有节点要么是红色,要么是黑色。

      3)红节点的孩子必然是黑色。

      4)都用叶子节点结尾,且叶子节点是哨兵,都是黑色,没有实际的key值。

      5)每一个节点的所有黑高都是相等的,黑高即是从此节点开始,到每一个哨兵所经历的黑节点的个数。

    2.红黑树的插入。

       1)插入。与普通二叉查找树没有区别。

       2)插入修复。(为了方便,在插入的节点通常都先设为红节点)

          case 1:如果插入节点z的父亲p是黑色,那么并不影响红黑色树的任何性质。

          case 2:如果插入节点z的父亲p是红色,影响了性质3,这时p的父亲g必然是黑色,那么p的父亲的另外一个孩子u(即是p的叔父节点)的颜色有以下几种情况。

                  case 2.1:u是红色的,只需要将u,p变成黑色,他们的父亲g变成红色,然后把g赋值给z进行下一轮修复。

                  case 2.2:u是黑色的,这时看z与p是否都是同侧(即都是左孩子,还是都是右孩子),如果是同侧,可绕g旋转,并且把更改p,g的颜色即可恢复。

                  case 2.3:u是黑色的,,这时看z与p是否都是同侧(即都是左孩子,还是都是右孩子),如果是异侧,可绕p旋转,并且把z改为旋转后的孩子(即旋转前的父亲),然后变成情况2.2,进行修复。

    3.红黑树的删除。

         1)删除。正常删除即可,注意记录删除点的孩子移动行踪x,及其删除点z的原始颜色,如果是红色,不影响红黑树的任何性质,否则要进行删除修复。

         2)删除修复。(如果修复过程中根节点变红,最终一定要把他变黑)

                case 1:如果x是红色,只需要将变成黑色即可恢复性质。

                case 2:如果x是黑色,x的兄弟w是红色,那么x的父亲p是黑色,把他变成黑色,并且绕P旋转就可以转换成x的兄弟是w是黑色即case 3。

                case 3:如果x是黑色,x的兄弟w是黑色,如果w的其同侧孩子是黑色,异侧孩子也是黑色,把w变成红色,把x与w的父亲作为新的x进行下一轮修复。

                case 4:如果x是黑色,x的兄弟w是黑色,如果w的其同侧孩子是黑色,异侧孩子是红色,绕w旋转可以转换成 case 5;

                case 5:如果x是黑色,x的兄弟w是黑色,如果w的其同侧孩子是红色,绕x与w的父亲旋转并且相应的变色即可修复。

    4.代码

    1)RB_Tree.h

    //NO Solution Questions:
    // The Root Init IS dynamic or Static?
    // NIL Node IS Dynamic,How to Get Space?
    // can`n use "inline" ,why?
    // Don`t Put many numbers Test

    /******
    Date:2015.3.5
    Code is Edit BY LHF
    *******/

    //---------------------
    //---------------------
    #ifndef RB_TREE_HHHH
    #define RB_TREE_HHHH
    #define NULL 0

    enum Color
    {
    Red,
    Black
    };
    typedef struct _node
    {
    int key;
    _node* Left;
    _node* Right;
    _node* p;
    Color color;

    }Node;

    //typedef struct RB_ree
    //{
    // int NodeCount;
    // Node* Root;
    //
    //}T;
    class Rb_Tree
    {
    public:
    Rb_Tree()
    {
    NIL.color=Black;
    NIL.Left=NULL;
    NIL.Right=NULL;
    NIL.p=NULL;
    NIL.key=-10000;
    Root =new Node();
    //Node r,a,b;
    (*Root).color=Black;
    (*Root).key=2;
    (*Root).Left=new Node();
    (*Root).Right=new Node();
    (*Root).p=NULL;
    *(*Root).Left=*(*Root).Right=NIL;
    (*Root).Left->p=Root;
    (*Root).Right->p=Root;
    //Root=&r;

    };
    Rb_Tree(Node* _root)
    {
    Root=_root;
    //NIL=new Node();
    NIL.color=Black;
    NIL.Left=NULL;
    NIL.Right=NULL;
    NIL.p=NULL;
    NIL.key=-10000;
    };
    void LeftLoate(Node* node);
    void RightLoate(Node* node);
    void RB_Insert(Node* z);
    void RB_Insert_Fixup(Node* z);
    void RB_TransPlant(Node* u,Node* v);
    void RB_Delete(Node* z);
    void RB_Delete_Fixup(Node* x);
    Node* Tree_Min(Node* node);
    Node* SearchNode(int key);

    void PintTree()
    {
    PintNode(Root);
    };
    ~Rb_Tree()
    {
    //delete Root;
    };

    private:
    void PintNode(Node* node);
    int NodeCount;
    Node* Root;
    Node NIL;
    };

    #endif

    2)RB_Tree.cpp

    #include"RB-TREE.h"
    #include<iostream>
    using namespace std;

    bool operator == (Node a,Node b)
    {
    if(a.key!=b.key)
    return 0;
    /*if(a.Left!=b.Left)
    return 0;
    if(a.Right!=b.Right)
    return 0;*/
    if(a.color!=b.color)
    return 0;
    return 1;
    /*if(a.p!=b.p)
    return 0;*/

    }
    bool operator != (Node a,Node b)
    {
    return !(a==b);
    }
    void Rb_Tree::PintNode(Node* node)
    {
    if(*node!=NIL)
    {
    cout<<node->key<<":"<<node->color<<" ";
    PintNode(node->Left);
    PintNode(node->Right);
    }
    else
    {
    cout<<endl;
    }

    }

    Node* Rb_Tree::SearchNode(int key)
    {
    Node *temp=Root;
    while (*temp!=NIL)
    {
    if(temp->key<key)
    {
    temp=temp->Right;
    }
    else if(temp->key>key)
    {
    temp=temp->Left;
    }
    else
    {
    return temp;
    }
    }
    return NULL;
    };
    void Rb_Tree::LeftLoate(Node* node)
    {
    Node* y=node->Right;
    //if(y->Left!=NULL)
    {
    node->Right=y->Left;
    }
    y->Left=node;
    y->p=node->p;
    if(node->p!=NULL)
    {
    if(node==node->p->Right)
    {
    node->p->Right=y;
    }
    else
    {
    node->p->Left=y;
    }
    }
    node->p=y;
    }
    void Rb_Tree::RightLoate(Node* node)
    {
    Node* y=node->Left;
    //if(*(y->Right)!=Rb_Tree::NIL)
    {
    node->Left=y->Right;
    }
    y->Right=node;
    y->p=node->p;
    if(node->p!=NULL)
    {
    if(node==node->p->Right)
    {
    node->p->Right=y;
    }
    else
    {
    node->p->Left=y;
    }
    }
    node->p=y;
    }
    void Rb_Tree::RB_Insert(Node* z)
    {
    Node* y=NULL;
    /*int a=5;
    int c=6;
    int * const b=&a;
    *b=c;
    int*c =b;*/
    Node* x=Rb_Tree::Root;
    while (*x!=Rb_Tree::NIL)
    {
    y=x;
    if(z->key<x->key)
    {
    x=x->Left;
    }
    else
    {
    x=x->Right;
    }
    }

    z->p=y;
    if(y==NULL)
    {
    Root=z;
    }
    else if(z->key<y->key)
    {
    y->Left=z;
    }
    else
    {
    y->Right=z;
    }
    z->Left=new Node(NIL);
    z->Left->p=z;
    z->Right=new Node(NIL);
    z->Right->p=z;
    z->color=Red;
    RB_Insert_Fixup(z);
    //delete y;
    }
    void Rb_Tree::RB_Insert_Fixup(Node* z)
    {
    while (z->p!=NULL&&z->p->color==Red)
    {
    if(z->p==z->p->p->Right)
    {
    if(z->p->p->Left->color==Red)
    {
    z->p->color=Black;
    z->p->p->Left->color=Black;
    z->p->p->color=Red;
    z=z->p->p;
    continue;
    }
    if(z==z->p->Left)
    {
    z=z->p;
    RightLoate(z);
    //z=z->Left;
    }
    z->p->color=Black;
    z->p->p->color=Red;
    LeftLoate(z->p->p);
    }
    else
    {
    if(z->p->p->Right->color==Red)
    {
    z->p->color=Black;
    z->p->p->Right->color=Black;
    z->p->p->color=Red;
    z=z->p->p;
    continue;
    }
    if(z==z->p->Right)
    {
    z=z->p;
    LeftLoate(z);
    //z=z->Left;
    }
    z->p->color=Black;
    z->p->p->color=Red;
    RightLoate(z->p->p);
    }
    }
    Root->color=Black;
    }
    void Rb_Tree::RB_TransPlant(Node* u,Node* v)
    {
    if(u->p==NULL)
    {
    Root=v;
    }
    else if(u==u->p->Left)
    {
    u->p->Left=v;
    }
    else
    {
    u->p->Right=v;
    }
    v->p=u->p;
    }
    void Rb_Tree::RB_Delete(Node* z)
    {
    Node* x=NULL;
    Node* y=z;
    Color y_orginal_color=z->color;
    if(*(z->Left)==NIL)
    {
    x=z->Right;
    RB_TransPlant(z,z->Right);
    }
    else if(*(z->Right)==NIL)
    {
    x=z->Left;
    RB_TransPlant(z,z->Left);
    }
    else
    {
    y=Tree_Min(z->Right);
    x=y->Right;
    y_orginal_color=y->color;
    if(y->p==z)
    {
    x->p=y;

    }
    else
    {
    RB_TransPlant(y,y->Right);
    y->Right=z->Right;
    z->Right->p=y;
    }
    RB_TransPlant(z,y);
    y->color=z->color;
    y->Left=z->Left;
    y->Left->p=y;
    }
    if(y_orginal_color==Black)
    {
    RB_Delete_Fixup(x);
    }
    /*if(z->Left->p==z&&*(z->Left)==NIL)
    {

    }*/
    //delete x;
    }
    void Rb_Tree::RB_Delete_Fixup(Node* x)
    {
    while (x->color==Black&&*(x->p)!=NIL)
    {
    if(x==x->p->Left)
    {
    if(x->p->Right->color==Red)
    {
    x->p->color=Red;
    x->p->Right->color=Black;//case 1
    LeftLoate(x->p);
    }
    if(x->p->Right->Right->color==Black&&x->p->Right->Left->color==Black)//case 2
    {
    x->p->Right->color=Red;
    x=x->p;
    continue;
    }
    if(x->p->Right->Right->color==Black&&x->p->Right->Left->color==Red)//case 3
    {
    x->p->Right->color=Red;
    x->p->Right->Left->color=Black;
    RightLoate(x->p->Right);
    }
    x->p->Right->color=x->p->color;
    x->p->color=Black;
    x->p->Right->Right->color=Black;
    LeftLoate(x->p);
    break;
    }
    else
    {
    if(x->p->Left->color==Red)
    {
    x->p->color=Red;
    x->p->Left->color=Black;//case 1
    RightLoate(x->p);
    }
    if(x->p->Left->Left->color==Black&&x->p->Left->Right->color==Black)//case 2
    {
    x->p->Left->color=Red;
    x=x->p;
    continue;
    }
    if(x->p->Left->Left->color==Black&&x->p->Left->Right->color==Red)//case 3
    {
    x->p->Left->color=Red;
    x->p->Left->Right->color=Black;
    LeftLoate(x->p->Left);
    }
    x->p->Left->color=x->p->color;
    x->p->color=Black;
    x->p->Left->Left->color=Black;
    RightLoate(x->p);
    break;
    }
    }
    x->color=Black;
    }
    Node* Rb_Tree::Tree_Min(Node* node)
    {
    while (*(node->Left)!=NIL)
    {
    node=node->Left;
    }
    return node;
    }

  • 相关阅读:
    MySQL 50条必练查询语句
    Spring MVC
    macaron 根目录默认为templates文件夹,所以如果启动目录同目录下有templates目录,要给它指定另一个文件夹
    table 表格配色
    应用连接数瓶颈解决方案
    idea修改文件的打开方式
    golang template使用
    childnode的after()方法失效问题
    vue双循环或者多循环作用于同一元素时,在外套template标签
    vue遇到组件数据变更了,但是不渲染的问题
  • 原文地址:https://www.cnblogs.com/ilovewuzhaoxia/p/4323501.html
Copyright © 2020-2023  润新知