我正在编写一个二叉搜索树,并且快完成了。我在删除节点时遇到问题。
每个节点都有一个对其左、右和父节点的引用(给根节点一个虚拟父节点)、一个数据元素和一个整数计数(称为副本)。当一个人输入一个已经存在的元素时,节点只会增加它的副本,当他们调用 decrementCopies() 时,该方法会减少副本数,如果副本数低于 1,则返回 false。 setLeft() 和 setRight () 方法将给定节点的父节点设置为被调用节点(即,node1.setLeft(node2) 将节点2 的父节点设置为节点1)。
下面是删除方法:
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;
}
它适用于大多数输入,但偶尔当我转储大量单词然后按顺序删除相同的单词时,我会遇到循环引用和丢失节点的问题。我一直在试图找出问题出在哪里,但我似乎无法在较小的范围内复制错误条件(我必须转储相当大的文件以使其发生以进行调试),我也看不到任何东西显然错了。
希望有人可以帮助我阐明一些观点。谢谢