算法导论:c++实现红黑树

数据结构

性质
算法导论:c++实现红黑树_第1张图片

算法导论:c++实现红黑树_第2张图片
这里定义一个结构体保存颜色

enum colorRB
{
    black = 0,
    red,
};
struct TreeNode_RB {
    int val;
    colorRB color;
    TreeNode_RB *left;
    TreeNode_RB *right;
    TreeNode_RB *parent;
    TreeNode_RB(int x, colorRB c) : val(x), left(NULL), right(NULL), parent(NULL),color(c) {}
};

旋转

算法导论:c++实现红黑树_第3张图片

左旋

算法导论:c++实现红黑树_第4张图片

/*红黑树左旋*/
void left_roate(TreeNode_RB *root,TreeNode_RB *x) //x称为y的左子树,y的左子树成为x的右子树
{
    TreeNode_RB *y = x->right;  //右子树左旋
    x->right = y->left;
    if (y->left != NULL) {
        y->left->parent = x;    //y左子树非空
    }
    y->parent = x->parent;  //置y的父节点
    if (x->parent == NULL) {
        root = y;
    }
    else if(x->parent->left==x)
    {
        x->parent->left = y;
    }
    else
    {
        x->parent->right = y;
    }
    y->left = x;    //y成为x左子树
    x->parent = y;  //y称为x的父节点
}

右旋

void right_roate(TreeNode_RB *root, TreeNode_RB *y) //y成为x的右子树,x的右子树成为y的左子树
{
    TreeNode_RB *x = y->left;   //左子树右旋
    y->left = x->right;
    if (x->right != NULL) {
        x->right->parent = y;   //x右子树非空
    }
    x->parent = y->parent;  //置x的父节点
    if (y->parent == NULL) {
        root = x;
    }
    else if (y->parent->left == y)
    {
        y->parent->left = x;
    }
    else
    {
        y->parent->right = x;
    }
    x->right = y;   //x成为y右子树
    y->parent = x;  //x成为y的父节点
}

测试

int main()
{
    TreeNode_RB *r1 = new TreeNode_RB(15,black);
    TreeNode_RB *r2 = new TreeNode_RB(6,red);
    TreeNode_RB *r3 = new TreeNode_RB(18,black);
    TreeNode_RB *r4 = new TreeNode_RB(3,black);
    TreeNode_RB *r5 = new TreeNode_RB(7,black);

    r1->left = r2;
    r1->right = r3;
    r2->parent = r1;
    r2->left = r4;
    r2->right = r5;
    r3->parent = r1;

    r4->parent = r2;
    r5->parent = r2;
    right_roate(r1, r2);

}

插入

插入就比较复杂了,涉及红黑树性质的调整,插入节点一致置颜色为红色,后再调整
算法导论:c++实现红黑树_第5张图片

算法导论:c++实现红黑树_第6张图片

算法导论:c++实现红黑树_第7张图片

算法导论:c++实现红黑树_第8张图片

算法导论:c++实现红黑树_第9张图片

void RB_insert_fixup(TreeNode_RB *root, TreeNode_RB *z) {
    while (z->parent->color==red)
    {
        if (z->parent->parent->left==z->parent) //z的父节点是左子树
        {
            TreeNode_RB *y = z->parent->parent->right;  //叔叔节点
            if (y->color == red) //叔叔节点是红色,case 1
            {
                z->color = black;   //重新着色
                z->parent->color = black;
                z->parent->parent->color = red;
                z = z->parent->parent;  //指针上移
            }
            else if(z->parent->right==z)// 叔叔节点是黑色,且z是右子树,case 2
            {
                z = z->parent;
                left_roate(root, z);    //左旋
            }
            // 叔叔节点是黑色,且z是左子树,case 3
            z->parent->color = black;
            z->parent->parent->color = red;
            right_roate(root, z->parent->parent);
        }
        else
        {
            TreeNode_RB *y = z->parent->parent->left;   //叔叔节点
            if (y->color == red) //叔叔节点是红色,case 1
            {
                z->color = black;   //重新着色
                z->parent->color = black;
                z->parent->parent->color = red;
                z = z->parent->parent;  //指针上移
            }
            else if (z->parent->right == z)// 叔叔节点是黑色,且z是右子树,case 2
            {
                z = z->parent;
                right_roate(root, z);   //左旋
            }
            // 叔叔节点是黑色,且z是左子树,case 3
            z->parent->color = black;
            z->parent->parent->color = red;
            left_roate(root, z->parent->parent);
        }
    }
}

/*红黑树插入*/
void RB_insert(TreeNode_RB *root, TreeNode_RB *z) {
    TreeNode_RB *y = NULL;  //y标记node的父指针
    TreeNode_RB *x = root;  //x用于向下探测
    z->color = red; //将待插入节点颜色置为红色
    while (x != NULL)
    {
        y = x;
        if (root->val < x->val) {
            x = x->left;
        }
        else
        {
            x = x->right;
        }
    }
    z->parent = y;
    if (y == NULL) {
        root = z;
    }
    else if (z->valval)
    {
        y->left = z;
    }
    else
    {
        y->right = z;
    }
}

你可能感兴趣的:(C++,算法导论)