我遇到了树的平衡部分的问题。我在递归插入后调用了checkBal。如果我尝试添加5,2和4,它会检查2的余额并继续返回到5,然后进入右旋转的rotateLeft部分,这是正确的。但第二行的rotateLeft函数错误。
此实施有什么问题?我一直在搜索,并将我所做的与人们谈论它如何完成的方式进行了比较。我终于把一切都搞定了。我忘记了最后将N设置为K.
//==============================================================================
//===== Set Balance ============================================================
sNode<T>* checkBal(sNode<T> *locRoot)
{
// Make sure to check the children are balanced as well.
if (locRoot->left != NULL)
locRoot->left = checkBal(locRoot->left);
if (locRoot->right != NULL)
locRoot->right = checkBal(locRoot->right);
if(getHeight(locRoot->left) - getHeight(locRoot->right) > 1)
{
if(getHeight(locRoot->left->right) > getHeight(locRoot->left->left))
locRoot->left = rotateRight(locRoot->left);
locRoot = rotateLeft(locRoot);
}
else if(getHeight(locRoot->right) - getHeight(locRoot->left) > 1)
{
if(getHeight(locRoot->right->left) > getHeight(locRoot->right->right))
locRoot->right = rotateLeft(locRoot->right);
locRoot = rotateRight(locRoot);
}
updateHeights(locRoot);
return locRoot;
}
/*
Extream cases of balancing a tree requires a double rotation
A
\
D
/
B
'A' is the current root
If right->left (grandchild) is larger then the right->right (grandchild)
First Right rotate the child then left rotate the parent
left > right by 2 or more
left.left < left.right (Double Right Rotation)
left.left >= left.right (Single Right Rotation)
right > left by 2 or more
right.right < right.left (Double Left Rotation)
right.right >= right.left (Single Left Rotation)
*/
sNode<T>* rotateRight(sNode<T> *N) const
{
/*
N K
/ \ / \
(a) K => N (c)
/ \ / \
(b) (c) (a) (b)
*/
// K is going to be our new Parent
// Move (c) from K->right to N->left
// Set K->right to be N
// Return the new parent node to update the one above.
sNode<T> *K = N->right;
N->right = K->left;
K->left = N;
return N = K;
}
答案 0 :(得分:2)
rotateRight(locRoot->left);
应该是,
rotateRight(locRoot->right);
但它仍然是一个错误的实现。 = P
对于root的左侧和右侧,您应该有不同的实现
试着看wikipedia animation。
答案 1 :(得分:0)
我把它搞砸了一段时间后才开始工作。我的解决方案如下。
//==============================================================================
//===== AVL Balance ============================================================
sNode<T>* checkBal(sNode<T> *locRoot)
{
// Go all the way down to the leaf nodes.
if (locRoot->left != NULL)
locRoot->left = checkBal(locRoot->left);
if (locRoot->right != NULL)
locRoot->right = checkBal(locRoot->right);
// Before we do anything lets update the parent/child heights
updateHeights(locRoot);
if(getHeight(locRoot->left) - getHeight(locRoot->right) > 1)
{
// If it needs a double left rotate first rotate the left child right
if(getHeight(locRoot->left->right) > getHeight(locRoot->left->left))
locRoot->left = rotateRight(locRoot->left);
locRoot = rotateLeft(locRoot);
}
else if(getHeight(locRoot->right) - getHeight(locRoot->left) > 1)
{
// If it needs a double right rotate first rotate the right child left
if(getHeight(locRoot->right->left) > getHeight(locRoot->right->right))
locRoot->right = rotateLeft(locRoot->right);
locRoot = rotateRight(locRoot);
}
// Update the new heights
updateHeights(locRoot);
return locRoot;
}
/*
Extream cases of balancing a tree requires a double rotation
A
\
D
/
B
'A' is the current root
If right->left (grandchild) is larger then the right->right (grandchild)
First Right rotate the child then left rotate the parent
left > right by 2 or more
left.left < left.right (Double Right Rotation)
left.left >= left.right (Single Right Rotation)
right > left by 2 or more
right.right < right.left (Double Left Rotation)
right.right >= right.left (Single Left Rotation)
*/
sNode<T>* rotateRight(sNode<T> *N) const
{
/*
N K
/ \ / \
(a) K => N (c)
/ \ / \
(b) (c) (a) (b)
*/
// K is going to be our new Parent
// Move (c) from K->right to N->left
// Set K->right to be N
// Return the new parent node to update the one above.
sNode<T> *K = N->right;
N->right = K->left;
K->left = N;
return N = K;
}
sNode<T>* rotateLeft(sNode<T> *N) const
{
/*
N K
/ \ / \
K (a) => (b) N
/ \ / \
(b) (c) (c) (a)
*/
sNode<T> *K = N->left;
N->left = K->right;
K->right = N;
return N = K;
}