1

我正在用 C++ 实现一棵红黑树,并且在插入后我一直在修复颜色违规。

我的左右旋转似乎工作正常,但树右分支的颜色永远无法正确修复。我想我在我的 fixViolation(Node*n) 方法中涵盖了所有情况,但也许我错了。

我还将感谢有关我的代码的所有其他建议和技巧。pastebin 链接到我的代码

我的代码:

    #include "pch.h"
    #include <iostream>
    #include <random>
    #include <string>
    #include <functional>
    using namespace std;

enum Color { Black, Red };

template<typename T>
class RBTree;

template <typename T>
class Node
{
    friend class RBTree<T>;
    T data;
    Color color;
    Node* parent;
    Node* leftChild;
    Node* rightChild;
public:
    Node()
    {
        this->parent = nullptr;
        this->leftChild = nullptr;
        this->rightChild = nullptr;
        color = Red;
    }
    void gibColor(Node<T>*x)
    {
        if (x->color == Black)
            cout << "black";
        else
            cout << "red";
    }
};

template <typename T>
class RBTree
{
    Node<T>* root;
    int size;
public:
    RBTree()
    {
        root = nullptr;
        size = 1;
    }

    void leftRotate(Node<T>*child, Node<T>*parent)
    {
        child = parent->rightChild;
        parent->rightChild = child->leftChild;
        if (child->leftChild != nullptr)
        {
            child->leftChild->parent = parent;
        }

        child->parent = parent->parent;
        if (parent->parent == nullptr)
        {
            root = child;
        }
        else if (parent == parent->parent->leftChild)
        {
            parent->parent->leftChild = child;
        }
        else {
            parent->parent->rightChild = child;
        }

        child->leftChild = parent;
        parent->parent = child;
    }
    void rightRotate(Node<T>*child, Node<T>*parent)
    {
        child = parent->leftChild;
        parent->leftChild = child->rightChild;
        if (child->rightChild != nullptr)
        {
            child->rightChild->parent = parent;
        }
        child->parent = parent->parent;
        if (parent->parent == nullptr)
        {
            root = child;
        }
        else if (parent == parent->parent->rightChild)
        {
            parent->parent->rightChild = child;
        }
        else
        {
            parent->parent->leftChild = child;
        }

        child->rightChild = parent;
        parent->parent = child;
        }
        void fixViolation(Node<T>*n)
        {
            Node<T>*grandparent;
            Node<T>*parent;
            //Node<T>*uncle;
            parent = n->parent;
            while (parent != nullptr&& parent->color == Red)
            {
            Node<T>*uncle;
            grandparent = n->parent->parent;
            if (grandparent->leftChild == parent)
            {
                uncle = grandparent->rightChild;
                if (uncle != nullptr&&uncle->color == Red)
                {
                    parent->color = Black;
                    uncle->color = Black;
                    grandparent->color = Red;
                    n = grandparent;
                    parent = n->parent;
                }
                else
                {
                    if (parent->rightChild == n)
                    {
                        n = parent;
                        leftRotate(n->parent, n);
                    }

                    parent->color = Black;
                    grandparent->color = Red;
                    rightRotate(parent, grandparent);
                }
            }
            else
            {
                uncle = grandparent->leftChild;
                if (uncle != nullptr&&uncle->color == Red)
                {
                    uncle->color = Black;
                    parent->color = Black;
                    grandparent->color = Red;
                    n = grandparent;
                    parent = n->parent;
                }
                else
                {
                    if (parent->leftChild == n)
                    {
                        n = parent;
                        rightRotate(n->parent, n);
                    }

                    parent->color = Black;
                    grandparent->color = Red;
                    leftRotate(parent, grandparent);
                }
            }
        }
        root->color = Black;
    }


    void addElement(T el)
    {
        Node<T>*n = new Node<T>();
        n->data = el;
        n->leftChild = nullptr;
        n->rightChild = nullptr;
        n->color = Red;
        Node<T>*temp = this->root;
        Node<T>*y = nullptr;
        if (root == nullptr)
        {
            n->color = Black;
            root = n;
        }
        else
        {
            while (temp != nullptr)
            {
                y = temp;
                if (temp->data < n->data)
                {
                    temp = temp->rightChild;
                }
                else
                {
                    temp = temp->leftChild;
                }
            }
            n->parent = y;
            if (y->data == n->data)
            {
                cout << "Duplikaty won!" << endl;
                return;
            }
            if (y->data < n->data)
            {
                y->rightChild = n;
                size = size + 1;
            }
            else
            {
                y->leftChild = n;
                size = size + 1;
            }
            //InsertFixUp(n);
            fixViolation(n);
        }

    }
    void print(Node<T>*x)
    {

        //cout << "size: " << size << endl;
        if (x == nullptr)
        {
            return;
        }
        if (x->parent == nullptr)
        {
            cout << "(" << x->data << ")";
            cout << "[" << "kolor:";
            x->gibColor(x);
            cout << ", parent: NULL," << " l.child: ";
            if (x->leftChild == nullptr)
            {
                cout << "NIL";
            }
            else
                cout << x->leftChild->data;
            cout << ", r.child: ";
            if (x->rightChild == nullptr)
            {
                cout << "NIL";
            }
            else
                cout << x->rightChild->data;
            cout << "]";
            cout << "-root " << endl;
            //rodzic, l.dziecko, p.dziecko

        }
        else if (x->parent->leftChild == x)
        {
            //int c = x->gibColor(x);
            cout << "(" << x->data << ")";
            cout << "[" << "kolor:";
            x->gibColor(x);
            cout << ", parent: " << x->parent->data << ", l.child: ";
            if (x->leftChild == nullptr)
            {
                cout << "NIL";
            }
            else
                cout << x->leftChild->data;
            cout << ", r.child: ";
            if (x->rightChild == nullptr)
            {
                cout << "NIL" << "]" << endl;
            }
            else
                cout << x->rightChild->data << "]" << endl;
        }
        else
        {
            cout << "(" << x->data << ")";
            cout << "[" << "kolor:";
            x->gibColor(x);
            cout << ", parent: " << x->parent->data << ", l.child: ";
            if (x->leftChild == nullptr)
            {
                cout << "NIL";
            }
            else
                cout << x->leftChild->data;
            cout << ", r.child: ";
            if (x->rightChild == nullptr)
            {
                cout << "NIL" << "]" << endl;;
            }
            else
                cout << x->rightChild->data << "]" << endl;
        }    
        print(x->leftChild);
        print(x->rightChild);

    }
    void printTree()
    {

    if (root == nullptr)
    {
        cout << "Empty tree!" << endl;

    }
    else
        print(root);
    }
};
int randomInt()
{
    uniform_int_distribution<int> rozklad{ 0, 11000000 };
    default_random_engine generator{ 11 };
    function<int()> los{ bind(rozklad, generator) };
    int l = los();
    return l;
}

int main()
{
    RBTree<int>* d1 = new RBTree<int>();
    d1->addElement(55);
    d1->addElement(69);
    d1->addElement(62);
    d1->addElement(71);
    d1->addElement(70);
    d1->addElement(14);
    d1->printTree();
}
4

0 回答 0