我写了一种从二叉搜索树中删除节点的方法。我为我的算法提供了16个测试用例,它们全部通过,除了测试16会生成空指针异常。我已将异常的源确定为方法的最后两行。
当我注释掉这两行时,空指针异常消失了,但是该节点没有被正确删除。当我重新添加这些行时,据我所知,该节点已删除,但是当程序在删除该节点后尝试定位该节点时,会生成空指针异常。
public void remove(BinaryNode r,Location key) throws InexistentKeyException{
Pixel p = get(r,key);
if (p==null) {
throw new InexistentKeyException();
}
BinaryNode nodeDel = r;
while(nodeDel.getData().getLocation().compareTo(key) != 0) {
if (key.compareTo(nodeDel.getData().getLocation())==-1) {
nodeDel = nodeDel.getLeft();
}
else if (key.compareTo(nodeDel.getData().getLocation())==1){
nodeDel = nodeDel.getRight();
}
}
if (nodeDel.getLeft().isleaf()==true && nodeDel.getRight().isleaf()==true) {
nodeDel.setData(null);
}
else if (nodeDel.getLeft().isleaf()==true || nodeDel.getRight().isleaf()==true) {
if (nodeDel.getLeft().isleaf()==true) {
BinaryNode parent = nodeDel.getParent();
BinaryNode child = nodeDel.getRight();
if (nodeDel.equals(root)) {
root = child;
child.setParent(null);
}
else {
if (parent.getLeft().equals(nodeDel)) {
parent.setLeft(child);
}
if (parent.getRight().equals(nodeDel)) {
parent.setRight(child);
}
}
}
else if (nodeDel.getRight().isleaf()==true) {
BinaryNode parent = nodeDel.getParent();
BinaryNode child = nodeDel.getLeft();
if (nodeDel.equals(root)) {
root = child;
child.setParent(null);
}
else {
if (parent.getLeft().equals(nodeDel)) {
parent.setLeft(child);
}
if (parent.getRight().equals(nodeDel)) {
parent.setRight(child);
}
}
}
}
else {
BinaryNode rightChild = nodeDel.getRight();
Pixel s = smallest(rightChild);
BinaryNode snode = r;
while(snode.getData().getLocation().compareTo(s.getLocation()) != 0) {
if (s.getLocation().compareTo(snode.getData().getLocation())==-1) {
snode = snode.getLeft();
}
else{
snode = snode.getRight();
}
}
nodeDel.setData(s);
remove(snode,snode.getData().getLocation());
}
}
我所指的行是“ nodeDel.setData(s)”和“ remove(s,s.getData()。getLocation())”。我几天来一直在尝试解决此问题,感觉好像我已经尝试了一切。