此方法应该从二进制(没有左右分支)树中删除所有叶子,但由于某种原因,它只从二叉树中删除一个叶子的一个实例。这是为什么?我虽然基本案例负责通过将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;
}
}
答案 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)。树中的节点数在哪里。