データ構造コースのジェネリックを保持する AVL ツリーを作成します。私の add() メソッドでは、実際に要素を挿入した後、スコアをチェックしている先祖に戻ります。最初の数回の追加では機能しますが、(おそらくバランス調整を行う必要がある時点で) パスをバックアップするループが終了しません。ツリーの親のルートが別のノードなどに設定されていないことを確認するために、考えられるすべてのことを試しました。バランス スコアは右マイナス左として計算しているため、正は木が右に重く、負は左に重くなることを意味します。ここに私の add() があります:
public void add(T e){
if (e == null)
return;
if (root == null) {
root = new TNode<T>(null, e);
return;
}
boolean added = false;
TNode<T> current = root;
while (current != null && added != true) { //insertion loop
if (current.compareTo(e) == 0)
return;
else if (current.compareTo(e) < 0) {
if (current.getRight() == null) {
current.setRight(new TNode<T>(current, e));
added = true;
}
else
current = current.getRight();
}
else if (current.compareTo(e) > 0) {
if (current.getLeft() == null) {
current.setLeft(new TNode<T>(current, e));
added = true;
}
else
current = current.getLeft();
}
}
if (useAVL == false)
return;
//balancing, checking up from added node to find where tree is unbalanced; currently loop does not terminate
//current is now parent of inserted node
while (current.hasParent()) {
if (current.getAvl() > 1) {
if (current.getRight().getAvl() > 0)
current = rotateLeft(current);
else if (current.getRight().getAvl() < 0) {
current.setRight(rotateRight(current.getRight()));
current = rotateLeft(current);
}
}
if (current.getAvl() < -1) {
if (current.getLeft().getAvl() < 0)
current = rotateRight(current);
else if (current.getLeft().getAvl() > 0) {
current.setLeft(rotateLeft(current.getLeft()));
current = rotateRight(current);
}
}
current = current.getParent();
}
root = current;
root.setParent(null);
}
そして、ここに正しい回転方法があります:
private TNode<T> rotateRight(TNode<T> old) {
TNode<T> oldRoot = old;
TNode<T> newRoot = old.getLeft();
TNode<T> rightChildNewRoot = newRoot.getRight(); //was right child of what will become root, becomes left child of old root
newRoot.setRight(oldRoot);
oldRoot.setParent(newRoot);
oldRoot.setLeft(rightChildNewRoot);
if (rightChildNewRoot != null)
rightChildNewRoot.setParent(oldRoot);
newRoot.setParent(oldRoot.getParent());
return newRoot;
}