0

私は二分探索木を書いていて、ほぼ完成しています。ノードの削除に問題があります。

各ノードには、左ノード、右ノード、および親ノードへの参照 (ルート ノードにはダミーの親が与えられます)、データ要素、および整数カウント (コピーと呼ばれます) があります。ユーザーが既に存在する要素を入力すると、ノードはそのコピーをインクリメントするだけで、ユーザーが decrementCopies() を呼び出すと、そのメソッドはコピーの数を減らし、コピーの数が 1 を下回ると false を返します。 setLeft() と setRight () メソッドは、指定されたノードの親を呼び出されるノードに設定します (つまり、node1.setLeft(node2) は node2 の親を node1 に設定します)。

削除方法は次のとおりです。

public void remove(T target) {
    if (target == null)
        throw new IllegalArgumentException();

    // cont is container, the node containing the
    // desired element.
    boolean rootRemoval;
    boolean contIsLeft;
    CountingNode<T> cont;
    CountingNode<T> parent;
    CountingNode<T> left;
    CountingNode<T> right;
    CountingNode<T> grad;

            assert root != null;
    if (root == null) {
        return;
    }
    else {
        cont = root.getNodeFor(target);
    }

    assert cont != null;
    if (cont == null) {
        return;
    }
    else if (cont.decrementCopies()) {
        words -= 1;
        return;
    }

    words -= 1;
    nodes -= 1;

    parent = cont.getParent();
    left = cont.getLeft();
    contIsLeft = parent.getLeft() == cont;
    rootRemoval = cont == root;

    if (cont.getNumChildren() < 2) {
        parent.setChild(cont.getOnlyChild(), contIsLeft);

        if (rootRemoval) {
            root = dummyParent.getOnlyChild();
        }

        return;
    }

    right = cont.getRight();
    grad = left.getRightMostNode();

    grad.getParent().setRight(grad.getLeft());

    if (grad != left) 
        grad.setLeft(left);
    else 
        grad.setLeft(null);

    grad.setRight(right);
    parent.setChild(grad, contIsLeft);

    if (rootRemoval) {
        root = dummyParent.getOnlyChild();
    }

    return;

}

ほとんどの入力で機能しますが、大量の単語をダンプしてから同じ単語を順番に削除すると、循環参照やノードの損失に問題が発生することがあります。問題がどこにあるかを追跡しようとしていますが、小さなスケールでエラー状態を再現できないようです (デバッグするには、かなり大きなファイルをダンプする必要があります)。また、何も表示されません。明らかに間違っています。

誰かが私に光を当てるのを手伝ってくれることを願っています。ありがとう

4

0 に答える 0