从二叉树中删除所有叶子

时间:2014-08-06 03:56:56

标签: java recursion binary-tree

此方法应该从二进制(没有左右分支)树中删除所有叶子,但由于某种原因,它只从二叉树中删除一个叶子的一个实例。这是为什么?我虽然基本案例负责通过将parent.left或parent.right设置为null来切断父节点的关系。如果它不是叶子,它会递归调用直到它碰到一片叶子。

这是我到目前为止所做的:

 private IntTreeNode overallRoot; // Beginning of the chain of nodes


    // post: Removes All leaves from a tree
     public void removeLeaves() {
     if (overallRoot == null) { // If empty tree
         return;
     } else {
         removeLeaves(overallRoot);
     }

 }

 // helper for removeLeaves
 private void removeLeaves(IntTreeNode root) {       
     if (root.left != null) { // tests left root
         if (root.left.left == null && root.left.right == null) { // if next left node is leaf (base case)
             root.left = null; // delete
         } else if (root.left.left != null && root.left.right == null) { // If next right is empty
             removeLeaves(root.left.left); // only check second left
         } else if (root.left.right != null && root.left.left == null) { // If next left is empty
             removeLeaves(root.left.right); 
         } else if (root.left.left != null && root.left.right != null) { // If next left/right isn't empty
             removeLeaves(root.left.left);
             removeLeaves(root.left.right);
         }
     }

     if (root.right != null) {
         if (root.right.left == null && root.right.right == null) { // if next left node is leaf (base case)
             root.right = null; // delete
         } else if (root.right.left != null && root.right.right == null) { // If next right is empty
             removeLeaves(root.right.left); // only check second left
         } else if (root.right.right != null && root.right.left == null) { // If next left is empty
             removeLeaves(root.right.right); 
         } else if (root.right.left != null && root.right.right != null) { // If next left/right isn't empty
             removeLeaves(root.right.left);
             removeLeaves(root.right.right);
         }
     }
 }

以下是单个节点类:

public class IntTreeNode {
     public int data;
     public IntTreeNode left;
     public IntTreeNode right;

     // constructs a leaf node with given data
     public IntTreeNode(int data) {
         this(data, null, null);
     }

     // constructs a branch node with given data, left subtree,
     // right subtree
     public IntTreeNode(int data, IntTreeNode left, IntTreeNode right) {
         this.data = data;
         this.left = left;
         this.right = right;
     }
}

5 个答案:

答案 0 :(得分:2)

以自下而上的方式接近树上的结构修改通常更清晰:

public IntTreeNode removeLeaves(IntTreeNode root) {
    if (root == null || root.isLeaf()) {
        return null;
    }
    root.left = removeLeaves(root.left);
    root.right = removeLeaves(root.right);
    return root;
}

答案 1 :(得分:0)

看起来你在每次传递过程中看起来都太过分了。如果左边有叶子,请调用removeLeaves(root.left)。用右边做同样的事。然后根据需要左右设置为空。

我认为这样做会:

public void removeLeaves(IntTreeNode root) {
if (root != null) {
    removeLeaves(root.left);
    removeLeaves(root.right);
    root.left = null;
    root.right = null;
}}

答案 2 :(得分:0)

如果在递归调用中,而不是执行

removeLeaves(root.left.left);
你做了

removeLeaves(root.left);

它应该有用。正如华莱士在评论中指出的那样,你的状态似乎一次下降两个级别。此外,代码可以通过以下方式减少(相当于右树)

if (root.left != null) { // tests left root
     if (root.left.left == null && root.left.right == null) { 
         root.left = null; // delete
     } else {
         removeLeaves(root.left);
     }
 }

另请注意,这并不能解决 root 本身就是假的问题!

答案 3 :(得分:0)

这将首先搜索树深度,然后删除遇到的叶节点。

公共类RemoveLeafNode {

public static void removeLeaves(Node root){
    if(root!=null){
        removeL(root.leftChild);
        removeL(root.rightChild);
    }
}

private static void removeL(Node node){
    if(node==null){
        return;
    }

    if(node.leftChild == null  && node.rightChild == null){
        node=null;//delete leaf
    }

    removeL(node.leftChild);
    removeL(node.rightChild);
}

}

答案 4 :(得分:0)

通过使用后期遍历,我们可以解决这个问题(其他遍历也可以)。

struct BinaryTreeNode* removeLeaves(struct BinaryTreeNode* root) {
    if (root != NULL)
    {
        if (root->left == NULL && root->right == NULL)
        {
            free(root);
            return NULL;
        }
        else
        {
            root->left = removeLeaves(root->left);
            root->right = removeLeaves(root->right);
        }
    }
    return root;
}

时间复杂度:O(n)。树中的节点数在哪里。