我正在尝试使用我的AVLTree LeftRotation
。我将插入3,5和10然后它变成一个退化的树。当我遍历它时,它会给我3, 5, 10
但是当我进行轮换时,我得到5, 10
而不是预期的5, 3, 10
。
这与将a
设置为b
的{{1}}分支有关。我将逐步完成它,我的树的根将是left
,左边是5
,右边是3
,但是当我去遍历它会显示左边方为10
。
这是我的轮换代码:
null
我的void AVLTree::RotateLeft(Node *root)
{
Node a = *root;
Node b = *root->GetRight();
*root = b;
a.SetRight(b.GetLeft());
b.SetLeft(&a); //This is where the problem occurs
}
代码:
Traversal
提前致谢!
修改:将所有void AVLTree::Traverse(Node *node)
{
cout << node->GetValue() << ", ";
if (node->GetLeft() != nullptr)
Traverse(node->GetLeft());
if (node->GetRight() != nullptr)
Traverse(node->GetRight());
}
更改为0
,谢谢更正!
答案 0 :(得分:1)
将root
移动到指向新位置的方式存在问题。如果对此有疑问,请考虑以下两个陈述。请注意,上述原始代码中的变量命名约定用于一致性。
*root = b; // (1)
root = &b; // (2)
在(1)
中,修改根指针的内容以包含存储在b
变量中的值。 root
的地址未以任何方式修改。在root
完成后,执行(1)
之前的地址(1)
保持不变。
在(2)
中,root
现在指向b
变量的地址。由于root
所指向的地址已被修改,因此root
指针的内容现在等于b
变量中的值。
我强烈建议逐行逐步执行void AVLTree::RotateLeft(Node *root)
功能并检查所有变量&#39;地址和内容可以看到第一手资料。我已经对样本整数数据进行了上述操作的模拟,并使用(2)
按预期移动了指针。
在对样本数据进行旋转之前,应该安排非平衡树,使3
节点指向root
节点。然后root->right
指向5
,root->right->right
指向10
。 root->right->left
应为nullptr
,root->left
也应为nullptr
。
如果不是这种情况,那么AVL插入算法实现不正确或设计要求与预期不同(例如维基百科上的AVL tree,Data Structures and Algorithm Analysis in C++ (3rd Edition) [Hardcover]作者:Mark Allen Weiss,{{3}作者Julienne Walker)。
关于平衡树的移动,最终结果为root
指向5
,root->left
指向3
和root->right
指向10
,传入的root
指针的右指针将被设置为指向本地pB
指针的左指针(见下文),左指针{{1} }将指向传入的pB
指针,root
将设置为指向局部变量root
(在这种情况下最初设置为pB
指针)。
使用上面的示例数据,修改了函数体。请注意,这与root->right
和GetRight()
在上面的原始帖子中返回节点副本的方式不一致。下面修改的函数体与上面引用的Mark Allen Weiss实现的GetLeft()
一致。由于原始帖子没有高度变量,因此下面的代码也没有。
single AVL rotation with right child