我已经实现了一个红黑树,然后在其中插入了1,2,3,4,5,6,7,8,9,10
。但似乎我的树不平衡,因为预订遍历如下所示:4,2,1,3,6,5,8,7,9,10
和有序遍历:1,2,3,4,5,6,7,8,9,10
。这意味着根是4
,树不平衡!这是我的代码。
void RedBlackTree::leftRotate(RedBlackTreeNode * x){
RedBlackTreeNode *y = x->right; //set y
y = x->right;
x->right = y->left;
if (y->left != nilLeaf)
y->left->p = x;
y->p = x->p;
if (x->p == nilLeaf)
root = y;
else if (x == x->p->left)
x->p->left = y;
else x->p->right = y;
y->left = x;
x->p = y;
}
void RedBlackTree::rightRotate(RedBlackTreeNode * x){
RedBlackTreeNode *y = x->left; //set y
y = x->left;
x->left = y->right;
if (y->right != nilLeaf)
y->right->p = x;
y->p = x->p;
if (x->p == nilLeaf)
root = y;
else if (x == x->p->right)
x->p->right = y;
else x->p->left = y;
y->right = x;
x->p = y;
}
void RedBlackTree::insert(const Point &newItem){
size++;
if (empty){
root->key = newItem;
empty = false;
return;
}
RedBlackTreeNode * z = new RedBlackTreeNode;
z->key = newItem;
z->right = z->left = z->p = nilLeaf;
RedBlackTreeNode *y = nilLeaf;// = new RedBlackTreeNode;
RedBlackTreeNode *x = root;// = new RedBlackTreeNode;
while (x != nilLeaf)
{
y = x;
if (z->key < x->key)
x = x->left;
else
x = x->right;
}
z->p = y;
if (y == nilLeaf)
root = z;
else if (z->key < y->key)
y->left = z;
else
y->right = z;
z->left = nilLeaf;
z->right = nilLeaf;
z->color = RedBlackTreeNode::Red;
insertFixUp(z);
}
void RedBlackTree::insertFixUp(RedBlackTreeNode* z){
while (z->p->color == RedBlackTreeNode::Red)
{
if (z->p == z->p->p->left)
{
RedBlackTreeNode* y = z->p->p->right;
if (y->color == RedBlackTreeNode::Red)
{
z->p->color = RedBlackTreeNode::Black;
y->color = RedBlackTreeNode::Black;
z->p->p->color = RedBlackTreeNode::Red;
z = z->p->p;
}
else if (z == z->p->right)
{
z = z->p;
leftRotate(z);
}
else{
z->p->color = RedBlackTreeNode::Black;
z->p->p->color = RedBlackTreeNode::Red;
rightRotate(z->p->p);
}
}
else if (z->p == z->p->p->right)
{
RedBlackTreeNode* y = z->p->p->left;
if (y->color == RedBlackTreeNode::Red)
{
z->p->color = RedBlackTreeNode::Black;
y->color = RedBlackTreeNode::Black;
z->p->p->color = RedBlackTreeNode::Red;
z = z->p->p;
}
else if (z == z->p->left)
{
z = z->p;
rightRotate(z); //**
}
else{
z->p->color = RedBlackTreeNode::Black;
z->p->p->color = RedBlackTreeNode::Red;
leftRotate(z->p->p); //**
}
}
}
root->color = RedBlackTreeNode::Black;
}
但我很确定insertFixUp
有问题。因为此代码适用于大多数示例,但在某些情况下(如上例所示),节点高度之间的差异将大于2。
编辑:如果我在其中插入一些随机数,这段代码就可以了。当我在其中插入已排序的数字时会出现问题。
答案 0 :(得分:2)
此代码没有任何问题。根据{{3}}:
'这些约束强制执行红黑树的关键属性:从根到最远叶子的路径不超过从根到最近叶子的路径的两倍。结果是树大致高度平衡'
所以4作为根是没有错的。尝试在树中插入更多数字,您将看到,根将发生变化,并且提到的属性将始终保持。