我正在尝试编写一个从二叉搜索树中递归删除节点的方法。我理解算法,但我的代码当前返回错误。当我尝试删除叶子节点,即没有子节点的节点时,它会删除该节点,但也删除树的最顶层节点。
我已经有方法可以找到节点的头部getValue()
,以及查找左右子树getLeft()
和getRight()
。我还有方法isEmpty()
,它检查树是否为空。
这是我目前的代码,其中x是要删除的节点,a是二叉搜索树:
public static Tree delete(int x, Tree a) {
if (a.isEmpty()) {
return new Tree();
} if (x>a.getValue()) {
return delete(x, a.getRight());
} else if (x<a.getValue()) {
return delete(x, a.getLeft());
} else {
if (a.getLeft().isEmpty()&&a.getRight().isEmpty()) {
return new Tree();
} if (a.getRight().isEmpty()) {
return delete(x, a.getLeft());
} if (a.getLeft().isEmpty()) {
return delete(x, a.getRight());
} else {
return new Tree(); //not yet completed
}
}
}
任何人都可以给我任何关于为什么会发生这种情况的线索吗?提前致谢
编辑:如果有人碰巧遇到这个问题,这里的代码最终会有效
public static Tree delete(int x, Tree a) {
if (a.isEmpty()) {
return new Tree();
} if (x>a.getValue()) {
return new Tree(a.getValue(), a.getLeft(), delete(x, a.getRight()));
} else if (x<a.getValue()) {
return new Tree(a.getValue(), delete(x, a.getLeft()), a.getRight());
} else {
if (a.getLeft().isEmpty()&&a.getRight().isEmpty()) {
return new Tree();
} if (a.getRight().isEmpty()) {
return new Tree(a.getLeft().getValue(), delete(a.getLeft().getValue(), a.getLeft()), a.getRight());
} if (a.getLeft().isEmpty()) {
return new Tree(a.getRight().getValue(), a.getLeft(), delete(a.getRight().getValue(), a.getRight()));
} else {
return new Tree(max(a.getLeft()), delete(max(a.getLeft()), a.getLeft()), a.getRight());
}
}
}
答案 0 :(得分:1)
此方法返回空树而不是将左或右设置为空。这就是您认为它删除顶级节点的原因。此外,它似乎不会处理删除节点本身,只处理子节点。
答案 1 :(得分:0)
你永远不会删除任何东西。有两种方法可以做到这一点。
制作树的结构副本,直到要删除的节点,然后将其中一个子节点插入另一个子节点,插入的结果是树的结果。
查找要删除的节点的父节点,并将该节点的访问者变为子节点之一,然后将另一个子子树添加到父树。基本上你在这里有一个处理插入的树类,它有一个根。删除根是重新绑定而不是更改节点的特殊情况。
如果您正在制作回溯算法,需要返回到先前的树#1是唯一的选择,它将与之前版本的树共享尽可能多的结构。如果您想迭代并更新数据结构以反映您从未需要的东西,那么#2是最佳选择。