我在平衡AVL树方面遇到了困难。我已经搜寻了很多关于如何平衡AVL树的步骤,但是没有找到有用的信息。
我知道有以下四种方法:
- 单左旋转 - 单右旋转 - 双左右旋转 - 双右左旋转
但我无法确定选择哪一种方法以及在哪个节点上应用它!
非常感谢您提供任何帮助!
我知道有以下四种方法:
- 单左旋转 - 单右旋转 - 双左右旋转 - 双右左旋转
但我无法确定选择哪一种方法以及在哪个节点上应用它!
非常感谢您提供任何帮助!
private Node<T> rotate(Node<T> n) {
if(n.getBf() < -1){
if(n.getRight().getBf() <= 0){
return left(n);
}
if(n.getRight().getBf() > 0){
return rightLeft(n);
}
}
if(n.getBf() > 1){
if(n.getLeft().getBf() >= 0){
return right(n);
}
if(n.getLeft().getBf() < 0){
return leftRight(n);
}
}
return n;
}
/**
* Performs a left rotation on a node
*
* @param n The node to have the left rotation performed on
* @return The new root of the subtree that is now balanced due to the rotation
*/
private Node<T> left(Node<T> n) {
if(n != null){
Node<T> temp = n.getRight();
n.setRight(temp.getLeft());
temp.setLeft(n);
return temp;
}
return n;
}
/**
* Performs a right rotation on a node
*
* @param n The node to have the right rotation performed on
* @return The new root of the subtree that is now balanced due to the rotation
*/
private Node<T> right(Node<T> n) {
if(n != null){
Node<T> temp = n.getLeft();
n.setLeft(temp.getRight());
temp.setRight(n);
return temp;
}
return n;
}
/**
* Performs a left right rotation on a node
*
* @param n The node to have the left right rotation performed on
* @return The new root of the subtree that is now balanced due to the rotation
*/
private Node<T> leftRight(Node<T> n) {
n.setLeft(left(n.getLeft()));
Node<T> temp = right(n);
return temp;
}
/**
* Performs a right left rotation on a node
*
* @param n The node to have the right left rotation performed on
* @return The new root of the subtree that is now balanced due to the rotation
*/
private Node<T> rightLeft(Node<T> n) {
n.setRight(right(n.getRight()));
Node<T> temp = left(n);
return temp;
}
u (-2)
/ \
A v (-1)
/ \
B C
u h + 2
/ \
h-1 A v h + 1
/ \
h-1 B C h
v h+1
/ \
h u C h
/ \
h-1 A B h-1
嘿!树是平衡的。这棵树的镜像也可以通过单个左旋转进行修复。
所有AVL树的旋转都可以通过在一个小范围内列举可能的平衡因子,然后确定每一步应该应用哪些旋转来确定。我会把这个留给读者作为练习。:-) 如果你只想查找答案,维基百科关于AVL树有一张很好的图片总结了可能需要应用的所有旋转。
希望这对你有所帮助!