我必须为我的数据结构课程编写AVL树,并坚持计算子树的平衡因子,以便我知道在哪里以及如何旋转树。
谢谢, 埃里克
编辑:
我知道必须计算二叉树中的节点数。
private int countTotalNodes(AVLNode<T> start){
AVLNode<T> current = start;
if(current.getLeft() != null){
return countTotalNodes(current.getLeft());
}
if(current.getRight() != null){
return countTotalNodes(current.getRight());
}
return 1;
}
答案 0 :(得分:1)
通常的方法是将平衡因子字段添加到树节点的数据结构中。对插入和删除进行平衡因子的更改,并且在进行轮换时传播更改以保持平衡。有一个很好的解释,使用伪代码here。
计算每次插入或删除时的余额(而不是将余额保留为每个节点的额外簿记)会使这些操作更加昂贵。
答案 1 :(得分:1)
我认为AVL树的通常实现将节点的高度存储在节点本身中,并在插入,剪切和链接操作中进行更新。在这些操作之后,我们必须检查较高节点的高度是否仍然正确,如下所示:
/**
* Recursively updates heights starting with given node.
* If height of given node is already correct we know
* that we can stop.
*/
private void updateHeights(AvlNode<T> node){
if(node == null) return;
int heightLeft = node.left != null ? node.left.height : -1;
int heightRight = node.right != null ? node.right.height : -1;
int height = heightLeft > heightRight ? heightLeft + 1 : heightRight + 1;
if(node.height != height){
node.height = height;
updateHeights(node.parent);
}
}
可以这么说,总是调用最高节点的父节点。好日子 - 实现一个AVL树是一个有趣的小项目 - 祝你好运..并彻底测试它!
答案 2 :(得分:0)
编写方法来计算树的深度,然后将其应用于左右子树。
这就是树数据结构的美妙之处:它自然是自相似的和递归的。
答案 3 :(得分:0)
节点数的计数功能是错误的(非常退化的树除外) - 它会计算左子树或右子树,但不会同时计算两者。首先尝试纠正这个问题。
然后考虑如何使用类似的算法来构建深度。
但正如其他答案所述,不要用它来平衡你的树,因为这样做的性能损失将超过拥有平衡树的所有好处。而是将您的深度存储在节点中,并考虑何时需要进行调整。