Java 递归计算二叉树中没有给定参数的叶子数

Java 递归计算二叉树中没有给定参数的叶子数,java,algorithm,recursion,Java,Algorithm,Recursion,我正在努力找出如何编写递归算法来计算二叉树(不是完整树)中的叶子数。我一直走到最左边的叶子,不知道从那里返回什么。我试图通过将叶子加载到列表中并获得该列表的大小来获得计数。这可能是一种不好的计数方式 public int countLeaves ( ) { List< Node<E> > leafList = new ArrayList< Node<E> >(); //BinaryTree<Node<E>

我正在努力找出如何编写递归算法来计算二叉树(不是完整树)中的叶子数。我一直走到最左边的叶子,不知道从那里返回什么。我试图通过将叶子加载到列表中并获得该列表的大小来获得计数。这可能是一种不好的计数方式

    public int countLeaves ( ) {

    List< Node<E> > leafList = new ArrayList< Node<E> >();
    //BinaryTree<Node<E>> treeList = new BinaryTree(root);

    if(root.left != null) 
    {
        root = root.left;
        countLeaves();
    }
    if(root.right != null) 
    {
        root = root.right;
        countLeaves();
    }
    if(root.left == null && root.right == null) 
    {
        leafList.add(root);
    }


        return();
}
public int countLeaves(){
ListleafList=newarraylist();
//BinaryTree树列表=新的BinaryTree(根);
if(root.left!=null)
{
root=root.left;
数叶();
}
if(root.right!=null)
{
root=root.right;
数叶();
}
if(root.left==null&&root.right==null)
{
添加(根目录);
}
return();
}

您的实现的问题在于,它无法将成员变量
root
的值恢复到输入方法之前的状态。可以通过将值存储在局部变量中来实现,即

Node<E> oldRoot = root;
... // your method goes here
root = oldRoot;
节点oldRoot=root;
... // 你的方法在这里
根=旧根;
但是,更好的方法是将
节点
作为参数,而不是依赖共享变量:

public int countLeaves() {
    return countLeaves(root);
}

private static int countLeaves (Node<E> node) {
    ... // Do counting here
}
public int countLeaves(){
返回叶(根);
}
私有静态int countLeaves(节点){
…你在这里数吗
}

您的实现的问题在于,它无法将成员变量
root
的值恢复到输入方法之前的状态。可以通过将值存储在局部变量中来实现,即

Node<E> oldRoot = root;
... // your method goes here
root = oldRoot;
节点oldRoot=root;
... // 你的方法在这里
根=旧根;
但是,更好的方法是将
节点
作为参数,而不是依赖共享变量:

public int countLeaves() {
    return countLeaves(root);
}

private static int countLeaves (Node<E> node) {
    ... // Do counting here
}
public int countLeaves(){
返回叶(根);
}
私有静态int countLeaves(节点){
…你在这里数吗
}

详细阐述@dasblinkenlight的想法。您希望递归地调用根节点上的countleaves并将#传递回调用者。下面几行

public int countLeaves() {
 return countLeaves(root);
 }

/**
 * Recursively count all nodes
 */
private static int countLeaves (Node<E> node) {
 if(node==null)
   return 0;

 if(node.left ==null && node.right == null)
  return 1;
 else {
    return countLeaves(node.left) + countLeaves(node.right);
   }
}
public int countLeaves(){
返回叶(根);
}
/**
*递归地计算所有节点
*/
私有静态int countLeaves(节点){
if(node==null)
返回0;
if(node.left==null&&node.right==null)
返回1;
否则{
返回countLeaves(node.left)+countLeaves(node.right);
}
}

编辑:似乎之前也有人问过类似的问题

详细阐述了@dasblinkenlight的想法。您希望递归地调用根节点上的countleaves并将#传递回调用者。下面几行

public int countLeaves() {
 return countLeaves(root);
 }

/**
 * Recursively count all nodes
 */
private static int countLeaves (Node<E> node) {
 if(node==null)
   return 0;

 if(node.left ==null && node.right == null)
  return 1;
 else {
    return countLeaves(node.left) + countLeaves(node.right);
   }
}
public int countLeaves(){
返回叶(根);
}
/**
*递归地计算所有节点
*/
私有静态int countLeaves(节点){
if(node==null)
返回0;
if(node.left==null&&node.right==null)
返回1;
否则{
返回countLeaves(node.left)+countLeaves(node.right);
}
}

编辑:似乎之前也有人问过类似的问题

是否确实要更改根节点以计算假期数?是否确实要更改根节点以计算假期数?您不认为这太冗长了吗?如果s.@hustmphrr,应该只有2个
,谢谢你指出这一点。这肯定是非常冗长的。我根据您的建议进行了编辑。事实上,由于您允许传入一个空节点,因此此问题的分支应该只能减少到该空检查。另外,你的else案例是错误的。缺少一个
1
@hustmphrr,现在因为我们只想计算叶子,所以我唯一想计算+1的时间应该是node.left和node.right为空时对吗?是的,你是对的。我觉得计算节点数太多了。你不觉得太冗长了吗?如果
s.@hustmphrr,应该只有2个
,谢谢你指出这一点。这肯定是非常冗长的。我根据您的建议进行了编辑。事实上,由于您允许传入一个空节点,因此此问题的分支应该只能减少到该空检查。另外,你的else案例是错误的。缺少一个
1
@hustmphrr,现在因为我们只想计算叶子,所以我唯一想计算+1的时间应该是node.left和node.right为空时对吗?是的,你是对的。我认为计算节点数太多了。