我正在尝试为我的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;
}