我正在写一个二叉搜索树,差不多完成了。我在删除节点时遇到问题。
每个节点都有对其左,右和父节点的引用(根节点被赋予一个虚拟父节点),一个数据元素和一个整数计数(称为副本)。当一个人输入一个已存在的元素时,该节点只增加其副本,当他们调用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;
}
它适用于大多数输入,但偶尔当我转储大量单词然后按顺序删除相同的单词时,我遇到循环引用和丢失节点的问题。我一直试图找出问题所在,但我似乎无法在较小的范围内复制错误条件(我必须转储相当大的文件以使其发生以便调试它)我也看不到任何东西显然是错的。
希望有人能帮助我解决问题。感谢