Java中的二叉树和递归

时间:2012-09-20 04:49:13

标签: java recursion

我有一个Node类,如下所示:

public class Node {

    private int value;
    private Node leftNode;
    private Node rightNode;

    public Node(Node leftNode, Node rightNode, int value){
        this.leftNode = leftNode;
        this.rightNode = rightNode;
        this.value = value;
    }

   //Getter and Setter methods for these variables are defined here
}

此Node类用于创建二叉树。我在JAVA中编写一个递归函数来计算所有节点的平均值。我在下面写的代码没有给出正确的答案。我认为这是因为参数average和nodeCount的值是传递的,而不是引用。

public double treeAverage(Node node, double average, int nodeCount){

    nodeCount ++;
    if(node == null) return Double.MAX_VALUE;
    if(node.getLeftNode()==null && node.getRightNode()==null){
        average = ( average + node.getValue() )/nodeCount;
    }

    if(node.getLeftNode()!=null){
        average = treeAverage(node.getLeftNode(), average, nodeCount); 
    }
    if(node.getRightNode()!=null){
        average = treeAverage(node.getRightNode(), average, nodeCount);
    }

    return average;

}

在Java中使用这个递归函数的正确方法是什么? (在C中我可以传递对这些参数的引用)。如果我错了,请纠正我。

5 个答案:

答案 0 :(得分:3)

我猜你可以使用辅助方法。像这样的东西(我没有编译这段代码,应该作为提示)

private static long count = 0L;
private static long sum = 0L;


public static int treeAverageHelper(Node node){

    if(node == null) return 0;
    count ++;
    return node.val + treeAverageHelper(node.left) + treeAverageHelper(node.right);
}

public static double treeAvg(Node n){
    sum = treeAverageHelper(n);
    if (count == 0)
        return 0D;
    else
        return (double)sum/count;
}

帮助程序,通过树聚合和计数。最后你将两者分开。

答案 1 :(得分:2)

我不是这两个部分的粉丝:

if(node == null) return Double.MAX_VALUE;
if(node.getLeftNode()==null && node.getRightNode()==null){
    average = ( average + node.getValue() )/nodeCount;
}

对于第一个语句,为什么空树的平均值是最高的Double?似乎是武断的。说它不存在,Double.NaN,甚至0.0会更简单 - 因为树中没有元素。

对于第二个语句,您的逻辑是正确的,如果两个子项都为null,则返回其值。但是,您将在整个过程中破坏平均值 - 如果您有12个节点,并且您已经在第三个节点上,那么当您移动到第四个节点时,您的平均值会有所不同。

nodeCount移到更高的范围,并且不必担心计算实际平均值,直到您计算了递归调用中所有节点的总和。最后,随着时间的推移传递节点的总和。

答案 2 :(得分:2)

我认为平均计算存在问题。 根据你的代码, 如果节点没有左子节点且没有右子节点,则添加average + node.getValue()并将此结果除以nodeCount。

事实上,

  

平均值是总值除以计数。

这意味着您应首先获得总节点值并将其除以nodeCount。

答案 3 :(得分:0)

您需要定义一个类,例如

class RecursionValues {
     int nodeCount;
     double average;
}

...然后在递归调用中传递此类的实例并修改其字段。

答案 4 :(得分:0)

这就是我能够让它发挥作用的方式。如果这不是一个好方法,请告诉我。

private double sum = 0;
private int nodeCount = 0;

public double treeAverage(Node node){

    if(node == null) return Double.NaN; //Null check

    sum = treeSum(node);
    double average = (sum/nodeCount);

    // before returning, reset the sum and nodeCount, so that same object can use the same function starting with correct/zero values of sum and nodeCount
    sum = 0; nodeCount = 0;

    return average;

}

public double treeSum(Node node){

    nodeCount ++; //update the nodeCount
    sum = sum + node.getValue(); //update the sum to include this node

    /* If the current node has children, recurse*/      
    if(node.getLeftNode()!=null){
        sum = treeSum(node.getLeftNode()); 
    }
    if(node.getRightNode()!=null){
        sum = treeSum(node.getRightNode());
    }

    return sum;

}