C ++红黑树左旋错误

时间:2018-03-12 18:15:50

标签: c++

您好我正在尝试用c ++创建一个红黑树,问题在于left_rotate方法。我使用递归方法按顺序打印树,并包含一些额外的std :: cout来查看发生了什么。问题是,当我从1-8向树中插入值时,根应该是数字4.相反,由于某种原因,根被卡在数字2上,当我从10-1右边尝试它时,右旋转方法奇迹般有效。我还添加了一些cout来查看修复1违规后迭代器的位置。它走向了正确的道路。当插入8号时它会重新处理,然后上升到第6位,它应该执行一个left_rotate,但它不是出于某种原因....这里是代码

p.s:请原谅我的英语:)

struct Node
{
    int value;
    bool isBlack;
    bool isLeft;
    Node *parent, *left, *right;
};

class RBtree
{

private:

    Node *root;

protected:

    void inorder(Node *t)
    {
        if (t == nullptr)
            return;
        inorder(t->left);
        if (t == root)
            cout << "ROOT: \n";
        cout << "value: " << t->value << " color: ";
        if (t->isBlack)
            cout << " B \n";
        else
            cout << " R \n";

        if (!t->isLeft)
        {
            cout << "ITS A RIGHT CHILD \n";
        }
        else
        {
            cout << "ITS A LEFT CHILD \n";
        }

        if (t->parent)
            cout << "PARENT: " << t->parent->value << "\n";
        else
            cout << "NONE\n";

        if (t->left)
            cout << "LEFT CHILD IS: " << t->left->value << "\n";
        else
            cout << "LEFT CHILD IS NULL \n";

        if (t->right)
            cout << "RIGHT CHILD IS: " << t->right->value << "\n\n";
        else
        {
            cout << "RIGHT CHILD IS NULL \n\n";
        }

        cout << "--------------------- \n\n";

        inorder(t->right);
    }

    void fix_violations(Node *);
    void recolor(Node *t);
    void left_rotate(Node *);
    void right_rotate(Node *);

public:

    RBtree()
    {
        root = nullptr;
    }
    void insert(int);
    void remove(int);
    void print_inorder()
    {
        inorder(root);
    }

};

void RBtree::insert(int v)
{
    Node * t = new Node(); // temp node

    t->value = v;
    t->isBlack = false;
    t->isLeft = false;
    t->parent = nullptr;
    t->left = nullptr;
    t->right = nullptr;

    if (root == nullptr)
    {
        root = t;
        root->isBlack = true;
        return;
    }

    Node *it = root; // create iterator to root

    while (it)
    {
        if (v < it->value)
        {
            if (!it->left)
            {
                it->left = t;
                t->parent = it;
                t->isLeft = true;
                //cout << "inserted ";
                break;
            }

            it = it->left;
        }
        else if (v > it->value)
        {
            if (!it->right)
            {
                it->right = t;
                t->parent = it;
                t->isLeft = false;
                //cout << "inserted ";
                break;
            }

            it = it->right;
        }
        else
        {
            break;
        }
    }

    fix_violations(t);

}

// check violations method
void RBtree::fix_violations(Node *t)
{
    cout << "Iterated on: ";
    while (t != root)
    {

        cout << t->value << " ";
        if (!t->parent || !t->parent->parent)
        {
            break;
        }

        if (!t->isBlack && !t->parent->isBlack)
        {

            bool u_isBlack = true;

            if (!t->isLeft)
            {
                if (t->parent->parent->left)
                    u_isBlack = t->parent->parent->left->isBlack;
            }
            else
            {
                if (t->parent->parent->right)
                    u_isBlack = t->parent->parent->right->isBlack;
            }

            if (!t->isBlack && !u_isBlack)
            {
                cout << " recolor ";
                recolor(t);
            }
            else if (!t->isBlack && u_isBlack)
            {

                if (t->isLeft && t->parent->isLeft)
                {
                    cout << " right-rotation ";
                    right_rotate(t);
                }
                else if (!t->left && !t->parent->isLeft)
                {
                    cout << " left-rotation ";
                    left_rotate(t);

                }
                else if (t->isLeft && !t->parent->isLeft)
                {
                    //right_left_rotate(t);
                }
                else if (!t->isLeft && t->parent->isLeft)
                {
                    // left_right_rotate(t);
                }
                else
                    ;

            }

        }
        t = t->parent;

    }

    cout << "\n\n";

    root->isBlack = true;
}

void RBtree::recolor(Node *t)
{
    Node *u; // uncle;

    if (!t->isLeft)
        u = t->parent->parent->left;
    else
        u = t->parent->parent->right;

    t->parent->isBlack = true;
    t->parent->parent->isBlack = false;
    u->isBlack = true;

}

void RBtree::left_rotate(Node *t)
{

    Node *p = t->parent;
    Node *g = p->parent;

    if (!g->parent) // if grand parent has no parent then it is root
    {
        // disconnect nodes
        g->right = nullptr;
        p->parent = nullptr;

        // parents left child
        Node *p_left = p->left;

        if (p_left)
        { // if left child of parent exists disconnect it
            p->left = nullptr;
            p_left->parent = nullptr;
        }

        root = p;
        root->left = g;
        g->parent = p;
        g->isLeft = true;

        if (p_left)
        {
            g->right = p_left;
            p_left->parent = g;
            p_left->isLeft = false;
        }

    }
    else
    {
        Node *pg = g->parent; // grand parent's parent

        pg->right = nullptr;
        g->right = nullptr;
        g->parent = nullptr;
        p->parent = nullptr;

        Node *p_left = p->left;

        if (p_left)
        {
            p->left = nullptr;
            p_left->parent = nullptr;
        }

        pg->right = p;
        p->parent = pg;
        p->left = g;
        g->parent = p;
        g->isLeft = true;

        if (p_left)
        {
            g->right = p_left;
            p_left->parent = g;
            p_left->isLeft = false;
        }

    }

    // recolor
    p->isBlack = true;
    t->isBlack = false;
    g->isBlack = false;

}

void RBtree::right_rotate(Node *t)
{
    Node * p = t->parent; // parent
    Node * g = p->parent; // grand-parent
    Node * u = g->right; // uncle

    if (!g->parent) // if grand-parent's parent is null then g is root
    {
        g->left = nullptr;
        p->parent = nullptr;

        Node *p_right = p->right;

        if (p_right)
            p_right->parent = nullptr;

        root = p;
        root->right = g;
        g->parent = p;
        g->isLeft = false;

        if (p_right)
        {
            g->left = p_right;
            p_right->parent = g;
            p_right->isLeft = true;
        }

    }
    else
    {

        Node *pg = g->parent;

        pg->left = nullptr;
        g->parent = nullptr;
        g->left = nullptr;

        Node *p_right = p->right;

        if (p_right)
            p_right->parent = nullptr;

        pg->left = p;
        p->parent = pg;

        p->right = g;
        g->parent = p;
        g->isLeft = false;

        if (p_right)
        {
            g->left = p_right;
            p_right->parent = g;
            p_right->isLeft = true;
        }

    }

// recolor
    p->isBlack = true;
    t->isBlack = false;
    g->isBlack = false;
}

int main()
{

    RBtree a;

    a.insert(1);
    a.insert(2);
    a.insert(3);
    a.insert(4);
    a.insert(5);
    a.insert(6);
    a.insert(7);
    a.insert(8);

    a.print_inorder();

}

0 个答案:

没有答案