Java 移除二叉树中未正确表示的叶子

Java 移除二叉树中未正确表示的叶子,java,binary-tree,Java,Binary Tree,我一直在从头开始创建二叉树,而不是使用内置库。我正在开发一个名为“pruneLeaves”的函数。这项工作是把树上的所有叶子都去掉;没有子节点的节点 当我使用断点单步执行函数时,它似乎正在删除叶子,甚至打印出它确实在删除正确的节点。然而,当我随后在主函数中显示树时,节点仍然存在 我花了几个小时想弄明白,我忽略了什么 程序输出: Num nodes = 9 Pruning. 12 Leaf removed 9 Leaf removed 4 Leaf removed Tree after pruni

我一直在从头开始创建二叉树,而不是使用内置库。我正在开发一个名为“pruneLeaves”的函数。这项工作是把树上的所有叶子都去掉;没有子节点的节点

当我使用断点单步执行函数时,它似乎正在删除叶子,甚至打印出它确实在删除正确的节点。然而,当我随后在主函数中显示树时,节点仍然存在

我花了几个小时想弄明白,我忽略了什么

程序输出:

Num nodes = 9
Pruning.
12
Leaf removed
9
Leaf removed
4
Leaf removed
Tree after pruning..
3 4 5 6 7 8 9 11 12 

使用链接:

我已经在我的代码中找到了错误,并使用链接中给出的答案进行了更正

更正代码如下:

private BinaryNode pruneLeaves (BinaryNode p) {

    // There is a left child
    if (p.left != null)
        if (isLeaf(p.left)) //Is that child a leaf?
            p.left = null;             
        else
            pruneLeaves(p.left);      // If it is not, recursive call

    // Is there a right child
    if (p.right != null)
        if (isLeaf(p.right))
            p.right = null;            
        else
            pruneLeaves(p.right);     // Recursive call
    return p;
}

// Main recursive call, passes the root of calling tree to the helper method
public void pruneLeaves () {
    pruneLeaves (this.getRoot());
}

// Returns true if child is a leaf
boolean isLeaf (BinaryNode t) {
    if (t.left == null && t.right == null) {
        return true;
    }
    return false;
}
+1作为正确答案(到目前为止,我只找到了一个),但是您忘记了根的null场景,并且如果根本身没有子级,您还需要删除根。我是这样做的-我使用了您的代码,然后确保它适合所有场景:

public void removeLeaves () {
    if (root != null) {
        removeLeaves (root);
    } else {
        return;
    }
}

private Node removeLeaves (Node node) {
    if (root.left == null && root.right == null) {
        root = null;
    } else {
        if (node.left != null) {
            if (node.left.left == null && node.left.right == null) {
                node.left = null;             
            } else {
                removeLeaves(node.left);
            }
        }
        if (node.right != null) {
            if (node.right.left == null && node.right.right == null) {
                node.right = null;      
            } else {
                removeLeaves(node.right);     
            }
        }
    }
    return node;
}

这段代码确保删除所有没有子节点的节点,同时也消除了对isLeaf()函数的需要。

remove()方法的内容是什么?从我的角度来看,整个remove函数是毫无意义的。使用参数t.element和t删除您的调用。因此,将t.element与x进行比较的if语句将始终落在最后一个else语句中。你的t.left和t.right总是为null,所以你的remove总是返回null。所以这个问题变成了“为什么设置t=null不改变BST?”@BoldAsLove,你完全正确。这是一个毫无意义的调用,在网站上搜索了一段时间后,我找到了一个解决我问题的答案。这是答案,但我必须指出,您的方法不起作用的原因是对设置为null的内容的误解。您正在将引用设置为null,而不是实际的节点。但是,如果我删除对该节点的引用,它不会被垃圾收集拾取吗?是的,如果您删除对父节点中的节点的引用,并且不存在其他引用,那么它将被拾取。该方法所做的是将本地引用设置为null,这根本不会影响父节点中的引用。上面发布的修复程序现在将父节点中的引用设置为null,这是正确的。感谢更新和修复程序提供答案!我很感谢你花时间和精力来发布这个!我将更新我的旧代码:)
private BinaryNode pruneLeaves (BinaryNode p) {

    // There is a left child
    if (p.left != null)
        if (isLeaf(p.left)) //Is that child a leaf?
            p.left = null;             
        else
            pruneLeaves(p.left);      // If it is not, recursive call

    // Is there a right child
    if (p.right != null)
        if (isLeaf(p.right))
            p.right = null;            
        else
            pruneLeaves(p.right);     // Recursive call
    return p;
}

// Main recursive call, passes the root of calling tree to the helper method
public void pruneLeaves () {
    pruneLeaves (this.getRoot());
}

// Returns true if child is a leaf
boolean isLeaf (BinaryNode t) {
    if (t.left == null && t.right == null) {
        return true;
    }
    return false;
}
public void removeLeaves () {
    if (root != null) {
        removeLeaves (root);
    } else {
        return;
    }
}

private Node removeLeaves (Node node) {
    if (root.left == null && root.right == null) {
        root = null;
    } else {
        if (node.left != null) {
            if (node.left.left == null && node.left.right == null) {
                node.left = null;             
            } else {
                removeLeaves(node.left);
            }
        }
        if (node.right != null) {
            if (node.right.left == null && node.right.right == null) {
                node.right = null;      
            } else {
                removeLeaves(node.right);     
            }
        }
    }
    return node;
}