如何将节点插入2-3树

时间:2013-12-13 08:39:34

标签: c++

我正在尝试为我的2-3树构建一个插入函数,无论我到目前为止做了什么,它都没有正确插入。

例如:我试图将P,T,E,G,S和R插入树中。一切都工作正常,直到R.当R插入树中时,它完全破坏了树的平衡,我无能为力是什么导致它以及如何解决问题

有人请看看我的代码并告诉我我做错了什么吗?谢谢

BNode类

template<class E>
class BNode
{
public:
    struct Entry
    {
        E _value;
        BNode<E>* _left;
        Entry()
        {
            _left = nullptr;
        };
    };

    //2-node
    BNode()
    {
        _right = nullptr;
        _three = false;
    }

    // 2-node
    BNode(E& x)
    {
        set_LValue(x);
        _right = nullptr;
        _three = false;
    }

    // overload 2-node constructor
    BNode(BNode<E>* left, E val, BNode<E>* right)
    {
        set_left(left);
        set_LValue(val);
        set_right(right);
        _three = false;
    }


    BNode<E>* GetRight() const {return _right;}
    BNode<E>* GetLeft() const {return _first._left;}
    BNode<E>* GetMiddle() const {return _second._left;}

    void set_right(BNode<E>* r) {_right = r;}
    void set_left(BNode<E>* l) {_first._left = l;}
    void set_middle(BNode<E>* m)
    {
        _second._left = m;
        _three = true;
    }

    void set_threeNode(bool val) {_three = false;}

    E LValue() const {return _first._value;}
    E RValue() const {return _second._value;}

    void set_LValue(E val)  {_first._value = val;}
    void set_RValue(E val) {_second._value = val;}

    bool IsThree() 
    {
        return _three;
    }

    bool IsLeaf()
    {
        bool valid;
        valid = (((GetLeft() == nullptr) && (GetRight() == nullptr)) ||  ((IsThree()) && (GetMiddle() == nullptr)));

        return valid;
    }

private:
    bool _three;
    Entry _first, _second;
    BNode<E>* _right;
};

添加功能

void add(E& x)  
{
    assert(!contains(x));
    if(_root == nullptr)
        _root = new BNode<E>(x);
    else
        add_helper(x, _root);  

    _size++;
}

add_helper功能

BNode<E>* add_helper(E& x, BNode<E>* root)
{
    // BASE CASES
    E currFirst = root->LValue();
    E currSecond = root->RValue();

    BNode<E>* smallest = nullptr;
    BNode<E>* largest = nullptr;

    // if curr is leaf node
    if(root->IsLeaf())
    {
        // if root is 2-node
        if(!root->IsThree())
        {
            if(x < currFirst)
            {
                root->set_RValue(currFirst);
                root->set_LValue(x);
                root->set_left(nullptr);
                root->set_middle(nullptr);
                root->set_right(nullptr);
            }
            else
            {
                root->set_RValue(x);
                root->set_left(nullptr);
                root->set_middle(nullptr);
                root->set_right(nullptr);
            }
            //_parent = root;
            return nullptr;
        }
        // leaf and 3-node
        // whoever gets kicked up gotta be the root
        else            
        {           
            if(x < currFirst)
            {                   
                smallest = new BNode<E>(x);
                largest = new BNode<E>(currSecond);

                _parent = root;
                root = new BNode<E>(smallest, currFirst, largest);

                if(_parent == _root)
                {
                    _root = nullptr;
                    _parent = root;
                    _root = _parent;
                }
                else
                    root->set_right(root);
            }
            else if(x < currSecond)
            {
                _parent = root;
                largest = new BNode<E>(nullptr, currSecond, nullptr);

                root->set_left(nullptr);
                root->set_right(nullptr);
                root->set_threeNode(false);
                _parent->set_left(root);
                _parent->set_right(largest);
                _parent->set_LValue(x);
                _parent->set_threeNode(false);
            }
            else
            {
                smallest = new BNode<E>(currFirst);
                largest = new BNode<E>(x);

                root->set_left(smallest);
                root->set_right(largest);
                root->set_LValue(currSecond);
                root->set_threeNode(false);

                _parent = root;
                //delete root;              
            }
            return _parent;
        }
    }

    // DOWNWARD PHASE
    BNode<E>* below = nullptr;
    BNode<E>* pleft = root->GetLeft();
    BNode<E>* pright = root->GetRight();
    BNode<E>* pmiddle = root->GetMiddle();

    _parent = root;

    if(x < currFirst)
        below = add_helper(x, pleft);
    else if(root->IsThree() && x < currSecond)
        below = add_helper(x, pmiddle);
    else
        below = add_helper(x, pright);

    // UPWARD PHASE
    if(below == nullptr)
        return nullptr;
    else if(!root->IsThree())
    {
        if(below->LValue() < currFirst)
        {
            root->set_RValue(currFirst);
            root->set_LValue(below->LValue());
            root->set_left(below->GetLeft());
            root->set_middle(below->GetRight());
        }
        else
        {
            root->set_RValue(below->LValue());
            root->set_middle(below->GetLeft());
            root->set_right(below->GetRight());
        }
        return nullptr;
    }

0 个答案:

没有答案