二叉搜索树删除方法错误

时间:2017-01-26 15:19:38

标签: java recursion binary-search-tree

我正在尝试编写一个从二叉搜索树中递归删除节点的方法。我理解算法,但我的代码当前返回错误。当我尝试删除叶子节点,即没有子节点的节点时,它会删除该节点,但也删除树的最顶层节点。

我已经有方法可以找到节点的头部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());
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

此方法返回空树而不是将左或右设置为空。这就是您认为它删除顶级节点的原因。此外,它似乎不会处理删除节点本身,只处理子节点。

答案 1 :(得分:0)

你永远不会删除任何东西。有两种方法可以做到这一点。

  1. 制作树的结构副本,直到要删除的节点,然后将其中一个子节点插入另一个子节点,插入的结果是树的结果。

  2. 查找要删除的节点的父节点,并将该节点的访问者变为子节点之一,然后将另一个子子树添加到父树。基本上你在这里有一个处理插入的树类,它有一个根。删除根是重新绑定而不是更改节点的特殊情况。

  3. 如果您正在制作回溯算法,需要返回到先前的树#1是唯一的选择,它将与之前版本的树共享尽可能多的结构。如果您想迭代并更新数据结构以反映您从未需要的东西,那么#2是最佳选择。