您好我正在尝试用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();
}