我正在练习一次考试,我有一个我无法弄清楚的例子。无论如何,任务是这样的:
您有一个看起来像Left Left Right Sibling树的数据结构 像这样:
public class TreeLCRSnode { public TreeLCRSnode parent, leftSon, rightSibling; }
你需要编写一个名为double avgH(TreeLCRSnode root)的函数 将返回平均叶高的结果。
为了确保每个人都明白,leaf是一个没有任何孩子的节点。例如,如果树看起来像这样,
4
|
2----7
|
3
然后有两个叶子,一个在高度1(第7个),一个在高度2(第3个)。
答案 0 :(得分:1)
我认为,对于此任务,您需要使用多个全局变量:
currentHeight
- 递归中的当前高度leafHeightSum
- 所有当前发现的叶子的高度之和leafNumber
- 所有找到的最新成绩然后解决方案可以这样:
int currentHeight, leafHeightSum, leafNumber;
double traverse(TreeLCRSnode node) {
currentHeight = 0;
leafHeightSum = 0;
leafNumber = 0;
traverseHelper(node);
// if the tree can be empty you might need a check here.
return (double)leafHeightSum / (double)leafNumber;
}
void traverseHelper(TreeLCRSnode node) {
while (node != null) {
if (node.leftSon) {
currentHeight++;
traverseHelper(node.leftSon);
currentHeight--;
} else {
leafHeightSum += currentHeight;
leafNumber++;
}
node = node.rightSibling;
}
}
答案 1 :(得分:1)
这是Boris Strandjev answer的略微修改。它的目标是多一点succint并避免全局变量,因为currentHeight
通过值传递,leafNumber
通过引用传递,叶高的总和是返回值。
double traverse(TreeLCRSnode node) {
int leafNumber=0;
return (double)traverseHelper(node,0,&leafNumber)/(double)leafNumber;
}
int traverseHelper(TreeLCRSnode node, int currentHeight, int *leafNumber) {
if(!node) return 0;
if(!node.leftSon) {
(*leafNumber)++;
return currentHeight + traverse(node.rightSibling, currentHeight, leafNumber);
} else {
return traverse(node.leftSon, currentHeight+1, leafNumber) + traverse(node.rightSibling, currentHeight, leafNumber);
}
}
答案 2 :(得分:0)
首先,您需要编写一个将遍历树的程序。类似的东西:
void traverse(TreeLCRSnode node) {
while (node != null) {
if (node.leftSon) traverse(node.leftSon);
node = node.rightSibling;
}
}
这会让你到达所有节点。然后你只需要确定节点是否是一个叶子,并弄清楚如何计算平均值(提示:绕过一个深度,跟踪到目前为止发现的叶子深度的总和,以及找到的总叶数#远)。