通俗易懂看RB-tree(二)

来源:互联网 发布:淘宝客户信誉查询 编辑:程序博客网 时间:2024/06/05 19:11

RB-tree结点设计

codes:

typedef bool rb_tree_color_typeconst rb_tree_color_type rb_tree_red=false;const rb_tree_color_type rb_tree_black=true;struct rb_tree_node_base  {    typedef rb_tree_color_type color_type;//颜色种类    typedef rb_tree_node_base *base_ptr;//红黑树节点指针        color_type color;    base_ptr parent;    base_ptr left;    base_ptr right;};

迭代器设计

codes:
void increment//前进,含义是找到比当前结点大的元素中最小的元素{    if(node->right!=0)    {        node=node->right;        while(node->left!=0)            node=node->left;    }    else    {        base_ptr y=node->parent;        while(node==y->right)//若此时是y的右节点,则一直向上递归        {            node=y;            y=y->parent;        }        /*此时node为y的左节点,而node的右节点和y都大于node        所以当node的右节点不等于y 时,返回y;(若相等,出错)*/        if(node->right!=y)            node=y;    }}void decrement//后退,含义是找比当前元素小的元素中最大的元素{    if(node->color==rb_tree_red&&node->parent->parent==node)        node=node->right;//此处node是根节点    else if(node->left!=0)    {        base_ptr y=node->left;        while(y->right!=0)            y=y->right;        node=y;    }    else    {        //若没有左节点,则判断该节点是否是左节点,向上递归,直到该节点为右节点停止;        //由二叉搜索树的性质,节点只要在右子树上,就肯定比父节点大,所以寻找以该节点为右子树的父节点;        base_ptr y=node->parent;        while(node==y->left)        {            node=y;            y=y->parent;        }        node=y;    }}

调整RB-tree(旋转及改变颜色)

inline void rb_tree_rebalance(rb_tree_node_base*x,rb_tree_node_base *&root){    x->color=rb_tree_red;//新节点必为红色;    while(x!=root&&x->parent->color==rb_tree_red)    {        if(x->parent==x->parent->parent->left)        {            rb_tree_node_base *y=x->parent->parent->right;//令y为伯父节点;            if(y&&y->color==rb_tree_red)            {                x->parent->color=rb_tree_black;                y->color=rb_tree_black;                x->parent->parent->color=rb_tree_red;                x=x->parent->parent;            }            else            {                //无伯父节点,或伯父节点为黑;                if(x==x->parent->right)//此时是内侧插入                {                    x=x->parent;                    rb_tree_rotate_left(x,root);                }                x->parent->color=rb_tree_black;                x->parent->parent=rb_tree_red;                rb_tree-rotate_right(x->parent->parent,root);                            }            else//父节点为祖父节点之右节点;            {                rb_tree_node_base *y=x->parent->parent->left;                if(y&&y->color==rb_tree_red)                {                    x->parent->color=rb_tree_black;                    y->color=rb_tree_black;                    x->parent->parent=rb_tree_red;                    x=x->parent->parent;                }                else//无伯父节点,或者伯父节点为黑                {                    if(x==x->parent->left)                    {                        x=x->parent;                        rb_tree_rotate_right(x,root);                    }                    x->parent->color=rb_tree_black;                    x->parent->parent->color=rb_tree_red;                    rb_tree_rotate_left(x->parent->parent,root);                }            }        }    }    root->color=rb_tree_black;//根节点永远为黑色;    }//左旋转inline void rb_tree_rotate_left(rb_tree_node_base *x,rb_tree_node_base *&root){    //x为旋转点;    rb_tree_node_base *y=x->right;//y为旋转点的右子结点    x->right=y->left;    if(y->left!=0)        y->left->parent=x;    y->parent=x->parent;        //y要完全代替x的地位,将x的所有关系完全接收过来;    if(x==root)        rooy=y;    else if(x==x->parent->left)        x->parent->left=y;    else        x->parent->right=y;    y->left=x;    x->parent=y;}//右旋转inline void rb_tree_rotate_right(rb_tree_node_base *x,rb_tree_node_base *&root){    rb_tree_node_base *y=x->left;    x->left=y->right;    if(y->right!=0)        y->right->paren=x;    y->parent=x->parent;        if(x==root)        root=y;    else if(x=x->parent->left)        x->parent->left=y;    else        x->parent->right=y;    y->right=x;    x->parent=y;}



原创粉丝点击