我有一个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中我可以传递对这些参数的引用)。如果我错了,请纠正我。
答案 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;
}