1

データ構造コースのジェネリックを保持する 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;
}
4

0 に答える 0