C ++-Red-Black Tree的重载[]运算符

时间:2018-06-28 10:24:49

标签: c++

我正在为红黑树重载[]。每个节点包含四个元素:键,性别,身高和体重。 “键”值将被随机分配,并且应该是唯一的,因此我想通过遍历每个节点以查看“键”值是否已存在来重载[]。但是,它仅在只有一个节点的情况下起作用。这是代码:

#include<iostream>
#include<string>
using namespace std;

enum COLOR { RED, BLACK };

class Node
{
    public:
        Node(int key, string gender, int height, int weight, const COLOR & color = RED)
            :pLeft(NULL), pRight(NULL), pParent(NULL), key(key), gender(gender), height(height), weight(weight), color(color)
        {}
        ~Node();

        string getGender();
        int getHeight();
        int getWeight();

        Node* pLeft;
        Node* pRight;
        Node* pParent;
        int key;
        string gender;
        int height;
        int weight;
        COLOR color;
};

class RBTree
{
    public:
        RBTree() :pRoot(NULL) {}

        Node &operator[](int key);
        bool insert(int key, string gender, int height, int weight);
        void RotateL(Node* parent);
        void RotateR(Node* parent);
        void InOrder();
        void InOrder(Node* pRoot);
        Node* searchTree(Node* pRoot, int key);
        bool CheckRBTree();
        bool CheckRBTree(Node* pRoot,int counter,int k);

    private:
        Node* pRoot;
};

string Node::getGender()
{
    return gender;
}

int Node::getHeight()
{
    return height;
}

int Node::getWeight()
{
    return weight;
}

Node &RBTree::operator[](int key)
{
    Node* ptr = searchTree(pRoot, key);
    return *ptr;
}

bool RBTree::insert(int key, string gender, int height, int weight)
{
    // create root
    if (pRoot == NULL)
    {
        pRoot = new Node(key, gender, height, weight);
        pRoot->color = BLACK;
        return true;
    }

    // find loc to insert
    Node* pCur = pRoot;
    Node* parent = NULL;
    while (pCur)
    {
        if (key < pCur->key)
        {
            parent = pCur;
            pCur = pCur->pLeft;
        }
        else if (key > pCur->key)
        {
            parent = pCur;
            pCur = pCur->pRight;
        }
        else
            return false;
    }

    // insert
    pCur = new Node(key, gender, height, weight);
    if (key < parent->key)
        parent->pLeft = pCur;
    else
        parent->pRight = pCur;

    pCur->pParent = parent;

    // discuss 3 cases
    while (pRoot != pCur&&pCur->pParent->color == RED)
    {
        Node* gf = parent->pParent;

        if (gf->pLeft == parent)
        {
            Node* uncle = gf->pRight;
            if (uncle&&uncle->color == RED)
            {
                parent->color = BLACK;
                uncle->color = BLACK;
                gf->color = RED;

                pCur = gf;
                parent = pCur->pParent;
            }
            else // turn case 3 into case 2
            {
                if (parent->pRight == pCur)
                {
                    RotateL(parent);
                    std::swap(parent, pCur);
                }

                gf->color = RED;
                parent->color = BLACK;
                RotateR(gf);
            }
        }
        else
        {
            Node*uncle = gf->pLeft;
            if (uncle && uncle->color == RED)  //case 1
            {
                parent->color = BLACK;
                uncle->color = BLACK;
                gf->color = RED;

                pCur = gf;
                parent = pCur->pParent;
            }
            else // turn case 3 into case 2
            {
                if (parent->pLeft == pCur)
                {
                    RotateR(parent);
                    std::swap(parent, pCur);
                }

                gf->color = RED;
                parent->color = BLACK;
                RotateL(gf);
            }
        }
    }

    pRoot->color = BLACK;
    return true;
}

// rotate left 
void RBTree::RotateL(Node* parent)
{
    Node* subR = parent->pRight;
    Node* subRL = subR->pLeft;

    parent->pRight = subRL;
    if (subRL)
        subRL->pParent = parent;

    subR->pLeft = parent;
    Node* gparent = parent->pParent; 
    parent->pParent = subR;
    subR->pParent = gparent;

    if (gparent == NULL)
        pRoot = subR;
    else if (gparent->pLeft == parent)
        gparent->pLeft = subR;
    else
        gparent->pRight = subR;

}

void RBTree::RotateR(Node* parent)
{
    Node* subL = parent->pLeft;
    Node* subLR = subL->pRight;

    parent->pLeft = subLR;
    if (subLR)
        subLR->pParent = parent;

    subL->pRight = parent;
    Node* gparent = parent->pParent;
    parent->pParent = subL;
    subL->pParent = gparent;

    if (gparent == NULL)
        pRoot = subL;
    else if (gparent->pLeft == parent)
        gparent->pLeft = subL;
    else
        gparent->pRight = subL;
}

void RBTree::InOrder()
{
    cout << "InOrder:  ";
    InOrder(pRoot);
    cout << endl;
}

void RBTree::InOrder(Node* pRoot)
{
    if (pRoot)
    {
        InOrder(pRoot->pLeft);
        cout << pRoot->key << "  ";
        InOrder(pRoot->pRight);
    }
}

Node* RBTree::searchTree(Node* pRoot, int key)
{
    if(pRoot->key == key)
        return pRoot;

    if(pRoot)
    {
        cout << "current node is " << pRoot->key << endl;
        searchTree(pRoot->pLeft, key);
        searchTree(pRoot->pRight, key);
    }
    return NULL;
}

bool RBTree::CheckRBTree()
{
    if (pRoot == NULL)
        return true;
    if (pRoot->color == RED)
        return false;
    int blackcount = 0;

    Node* pCur = pRoot;
    while (pCur)
    {
        if (pCur->color == BLACK)
            blackcount++;
        pCur = pCur->pLeft;
    }

    return CheckRBTree(pRoot, blackcount, 0);
}

bool RBTree::CheckRBTree(Node* pRoot, int counter, int k)
{
    if (pRoot == NULL)
        return true;
    if (pRoot->color == BLACK)
        k++;

    Node* parent = pRoot->pParent;
    if (parent && parent->color == RED && pRoot->color == RED)
        return false;

    if (pRoot == NULL)
    {
        if (k != counter)
            return false;
    }

    return CheckRBTree(pRoot->pLeft, counter, k)
        && CheckRBTree(pRoot->pRight, counter, k);
}

int main()
{
    int a[] = { 10, 7, 8, 15, 5, 6, 11, 13, 12 };

    RBTree t;
    for (int index = 0; index < sizeof(a) / sizeof(a[0]); index++)
    {
        cout << a[index] << "  ";
        t.insert(a[index], "male", 12, 3);
    }
    cout << endl;
    cout << t[7].getGender() << endl;

    return 0;
}

有人知道如何解决此问题吗?预先感谢。

1 个答案:

答案 0 :(得分:1)

您似乎还没有实现searchTree。

Node* RBTree::searchTree(Node* pRoot, int key)
{
    if(pRoot->key == key)
        return pRoot;

    if(pRoot)
    {
        cout << "current node is " << pRoot->key << endl;
        searchTree(pRoot->pLeft, key);
        searchTree(pRoot->pRight, key);
    }
    return NULL;
}

如果根匹配,则返回根,而所有其他情况均返回NULL。那行不通。

注意:您使用pRoot->key,并且仅在此之后检查if(pRoot)。如果pRoot为NULL,那么您已经崩溃了。