私は二分探索木を書いていて、ほぼ完成しています。ノードの削除に問題があります。
各ノードには、左ノード、右ノード、および親ノードへの参照 (ルート ノードにはダミーの親が与えられます)、データ要素、および整数カウント (コピーと呼ばれます) があります。ユーザーが既に存在する要素を入力すると、ノードはそのコピーをインクリメントするだけで、ユーザーが 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;
}
ほとんどの入力で機能しますが、大量の単語をダンプしてから同じ単語を順番に削除すると、循環参照やノードの損失に問題が発生することがあります。問題がどこにあるかを追跡しようとしていますが、小さなスケールでエラー状態を再現できないようです (デバッグするには、かなり大きなファイルをダンプする必要があります)。また、何も表示されません。明らかに間違っています。
誰かが私に光を当てるのを手伝ってくれることを願っています。ありがとう