红黑树是一个典型的key,value的结构,通过key去查找value,看上去是带颜色的二叉树。

红黑树遍历的方式是中序遍历(从中间key值的根节点开始有序查找),所以查找起来更加快速。

这里把红黑树构造理解为

红黑树 = 根节点 + 基础结构;

并且红黑树如下性质:

①根节点为黑

②叶子结点为黑(叶子结点是黑色NIL节点,也叫“哨兵”)

③红色节点不相邻

④红色的子支为黑

⑤根节点到每一个叶子的路径上黑色节点数相同(黑高)

构造如下:

typedef int KEY_TYPE;

typedef struct _rbtree_node
{
    unsigned char color;
    struct _rbtree_bode *left;
    struct _rbtree_bode *right;
    struct _rbtree_bode *parent;//有利于对红黑树旋转

    KEY_TYPE key;
    void *value;
}rbtree_node;//红黑树结点的定义

typedef struct _rbtree
{
    rbtree_node *root;
    rbtree_node *nil;//创建一个空节点,判断是否为叶子节点
};

当然红黑树作为二叉树的一种可以对其进行旋转操作:

python实现一个基本的红黑树 红黑树遍历方式_c++

对此,实现如图的代码

void _left_node(rbtree *T,rbtree_node *x)
{
    rbtree_node *y = x->right;
    x->right = y->left;
    y->left  = x;        //第一个方向
    if(y->left != T->nil){
        y->left->parent=x;
    }
    y->parent = x->parent;
    if(x->parent==T->nil){
        y->root=y;
    }else{
        x->parent->right=y;
    }                     //第二个方向
    y->left=x;
    x->parent=y;          //第三个方向
}

void _right_node(rbtree *T,rbtree_node *y)
{
    rbtree_node *x = y->right;
    y->right = x->left;
    x->left  = y;        //第一个方向
    if(x->left != T->nil){
        y->left->parent=x;
    }
    x->parent = y->parent;
    if(y->parent==T->nil){
        x->root=x;
    }else{
        y->parent->right=x;
    }                     //第二个方向
    x->left=y;
    y->parent=x;          //第三个方向
}//把全部x变成y,y变成x就成了右旋

以及实现的插入操作:

void rbtree_insert(rbtree *T,rbtree_node *z)
{
    rbtree_node *x= T->root; //x相当于遍历用的i
    rbtree_node *y= T->nil;

    while(x != T->nil){
        y = x; //这里的y就是x的父节点
        if(z->key<x->key){
            x = x->left;
        }else if(z->key > x->key){
            x = x->right;
        }else{
            return ;
        }
    } //找到对应插入z的父节点
    z->parent = y;
    if(y==T->nil){
        T->root = z;    //空的,那么z就是根节点
    }else if(z->key < y->key){
        y->left = z;
    }else{
        t->right = z;
    }
    z->color = RED;//默认增加红色节点,不影响黑高,只需要判断父节点是否为红
}

这里为了让新的到的红黑树仍然是红黑树,优先赋值为其赋值为红色,讨论其父节点是否是红即可。若为红色对其进行讨论:

回过头来看红黑树对子节点的颜色的处理,这实质上是为了防止同一父节点的两个分支深度相差不大。(保证每两个新节点的加入一定是在两个不一样的分支!!!<----这一点可以代入递归的思想,由红黑树最深处往根节点递归,每一个节点都满足红黑树的平衡的特性)

        对红黑的树旋转则是对两个分支长度的平衡!!——>本次红黑树设计用到了fix_up函数是用于,插入一次节点必定被调用的一次处理,因为用户往往不需要对红黑树内部自动的增删改查透明,所以此函数可能被开发忽略。

void rbtree_insert_fixup(rbtree *T,rbtree_node *z){
    while(z->parent->color == RED){//进入while已知:当前为RED,父节点为RED,爷爷为BLACK        if(z->parent == z->parent->parent->left){
             rbtree_node *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 == z->parent->right){
                     z = z->parent;
                     _left_node(T,z);
                 }//先旋转,再变色!
                 z->parent->color = BLACK;
                 z->parent->parent->color = RED;
             }
        }//????几种情况的理解
    }
    while(z->parent->color == RED){//进入while已知:当前为RED,父节点为RED,爷爷为BLACK
        if(z->parent == z->parent->parent->right){
             rbtree_node *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 == z->parent->left){
                     z = z->parent;
                     _left_node(T,z);
                 }
                 z->parent->color = BLACK;
                 z->parent->parent->color = RED;
             }
        }//right与left交换
    }
    T->root->color = RED;
}