我正在尝试用Java构建一个AVL树,但是我在旋转后更新高度时遇到了麻烦。这是我遇到问题的代码。
public void checkHeights(Node<T> u) {
if (u == nil) return;
checkHeights(u.left);
checkHeights(u.right);
System.out.println(u.h);
if (height(u) != 1 + Math.max(height(u.left), height(u.right)))
throw new RuntimeException("Check heights shows incorrect heights");
int dif = height(u.left) - height(u.right);
if (dif < -1 || dif > 1)
throw new RuntimeException("Check heights found height difference of " + dif);
}
/**
* Fix up
* @param u
*/
public void fixup(Node<T> u) {
while (u != nil) {
int dif = height(u.left) - height(u.right);
if(debug)System.out.println("Node dif at " + u.x + " is: " + dif);
if (dif > 1) {
if(debug)System.out.println("u.left is larger");
if(height(u.left.left) - height(u.left.right) < 0) {
if(debug)System.out.println("u.left dif is: " + (height(u.left.left) - height(u.left.right)));
rotateLeft(u.left);
}
rotateRight(u);
} else if (dif < -1) {
if(debug)System.out.println("u.right is larger");
if(height(u.right.left) - height(u.right.right) > 0) {
if(debug)System.out.println("u.right dif is: " + (height(u.right.left) - height(u.right.right)));
rotateRight(u.right);
}
rotateLeft(u);
}
if(debug) System.out.println("Height of " + u.x + " is " + height(u));
u = u.parent;
}
}
public void rotateLeft(Node<T> u) {
super.rotateLeft(u);
u.h = Math.max(height(u.left), height(u.right)) + 1;
u.parent.h = Math.max(height(u.parent.left), height(u.parent.right)) + 1;
if(debug)System.out.println("After left rotation, " + u.x + " has height " + u.h + " and " + u.parent.x + " has height " + u.parent.h);
}
public void rotateRight(Node<T> u) {
super.rotateRight(u);
u.h = Math.max(height(u.left), height(u.right)) + 1;
u.parent.h = Math.max(height(u.parent.left), height(u.parent.right)) + 1;
if(debug)System.out.println("After right rotation, " + u.x + " has height " + u.h + " and " + u.parent.x + " has height " + u.parent.h);
}
我已经完成了一系列单元测试,并且我一直在让checkHeights抛出异常。我几乎肯定发生的事情是当旋转发生在大于2的深度时,高度不会递归地更新到树上。例如,如果我添加从0到10的值,则第一个左旋转没有问题,并且值得到正确的高度,但是当我尝试向下旋转时,父节点不能准确地更新到它们的新高度,导致异常被抛出。
非常感谢任何帮助