Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 递归查找二叉树中的节点高度之和_Java_Recursion_Binary Tree - Fatal编程技术网

Java 递归查找二叉树中的节点高度之和

Java 递归查找二叉树中的节点高度之和,java,recursion,binary-tree,Java,Recursion,Binary Tree,如何递归地求二叉树中节点的高度之和 例如: public int totalHeight() { return totalHeight(root); } private int totalHeight(BinaryNode<AnyType> n) { int totalHeight = 0; if (n.left == null && n.right == null) return totalHeight; if

如何递归地求二叉树中节点的高度之和

例如:

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

private int totalHeight(BinaryNode<AnyType> n) {

    int totalHeight = 0;

    if (n.left == null && n.right == null)
        return totalHeight;
    if (n.left != null && n.right != null)
        return totalHeight + 1
                + Math.max(totalHeight(n.left), totalHeight(n.right));
    if (n.left != null)
        return totalHeight + 1 + Math.max(totalHeight(n.left), -1);
    if (n.right != null)
        return totalHeight + 1 + Math.max(-1, totalHeight(n.right));

    return totalHeight;
}

public int totalHeight(){
返回总高度(根);
}
专用整数总高度(二进制节点n){
int totalHeight=0;
如果(n.left==null&&n.right==null)
返回总高度;
如果(n.left!=null&&n.right!=null)
返回总高度+1
+数学最大值(总高度(n.左),总高度(n.右));
如果(n.left!=null)
返回totalHeight+1+数学最大值(totalHeight(n.左侧),-1);
如果(n.right!=null)
返回totalHeight+1+数学最大值(-1,totalHeight(右侧));
返回总高度;
}
我已经试过了,但是它只得到树的高度,而不是所有节点高度的总和

我觉得很难在递归中跟踪计数器,似乎每次递归调用时,
totalHeight
都设置为0。这不好。

private int maxHeight(二进制节点n){
 private  int maxHeight(BinaryNode<AnyType> n) {
  if (n ! = null) return 0;
  int leftheight = maxHeight(n.left);
   int rightheight = maxHeight(n.right);
  return (leftheight > rightheight) ? leftheight + 1 : rightheight + 1;
}
如果(n!=null)返回0; int leftheight=maxHeight(n.left); int rightheight=最大高度(n.right); 返回(leftheight>rightheight)?leftheight+1:rightheight+1; }
到目前为止,你已经知道了4种计算高度的方法

本质是如果左子节点或右子节点存在,则继续向左或向右移动节点。 如果存在,则返回1

计数函数位于最后一条语句中。这是为了得到最大的高度计数


主要课程是在方法工作时熟悉递归和编程堆栈

循环查找每个节点的高度并不断添加到静态变量。或者,您可以记住高度并存储在每个节点中,然后执行另一个递归将它们相加


递归应该返回节点n的高度,而不是子树中每个节点的总高度。

给定节点高度的实现,我们简单地称之为
高度(BinaryNode)
,您可以:

如果您有权访问集合中的所有节点:

int sumHeight(List<BinaryNode<?>> nodes) {
    int sum = 0;
    for (BinaryNode<?> node: nodes) {
        sum += height(node);
    }
    return sum;
}
int sumHeight(列表节点:节点){
总和+=高度(节点);
}
回报金额;
}
如果您只能访问树结构中的节点:

int sumHeight(BinaryNode<?> node) {
    if (node == null) return 0;
    return height(node) + sumHeight(node.left) + sumHeight(node.right);
}
int-sumHeight(二进制节点){
如果(node==null)返回0;
返回高度(节点)+sumHeight(节点左)+sumHeight(节点右);
}

看看是否有算法可以在一次递归中进行计算(可能是一些回溯算法?)会很有趣。

一个简单的版本是执行两次遍历过程,首先记录每个节点的高度,然后遍历节点求和。此方法可以进行递归,但在计算高度时,通过求和,只需一次即可轻松实现

public static int totalHeightSum = 0;

private int calculateHeightAndAdd ( Node n )
{
     if ( n == null )
        return 0;

     int leftHeight = calculateHeightAndAdd ( n.left );
     int rightHeight= calculateHeightAndAdd ( n.right);

     int myHeight = 1 + Math.max ( leftHeight, rightHeight );

     totalHeightSum += myHeight;

     return myHeight;
}

嗯。我已经想出了一个解决办法

a) 如果
n==null
返回
0

b) 如果
n.left==null&&n.right==null
返回
0

c) 总高度为
左侧总高度
+
右侧总高度
+
自身高度

  • 它本身的高度是:
1) 若左侧较大,则左侧的总高度减去左侧的总高度

2) 若右侧较大,则右侧总高度减去右侧总高度

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

private int totalHeight(BinaryNode<AnyType> n) {
    if (n == null)
        return 0;
    else if (n.left == null && n.right == null)
        return 0;
    else
        return totalHeight(n.left)
                + totalHeight(n.right)
                + (totalHeight(n.left) > totalHeight(n.right) ? totalHeight(n.left)
                        - (n.left == null ? 0 : totalHeight(n.left.left))
                        : totalHeight(n.right)
                                - (n.right == null ? 0
                                        : totalHeight(n.right.right))) + 1;
}
public int totalHeight(){
返回总高度(根);
}
专用整数总高度(二进制节点n){
如果(n==null)
返回0;
else if(n.left==null&&n.right==null)
返回0;
其他的
返回总高度(n.左)
+总高度(右侧)
+(总高度(n.左)>总高度(n.右)→总高度(n.左)
-(n.left==null?0:总高度(n.left.left))
:总高度(右侧)
-(n.right==null?0
:总高度(n.右.右))+1;
}

我假设您在插入过程中没有更新高度

解决方案: 我会以更有序的方式穿过这棵树。所以我首先声明root.height=0

然后说

BinaryNode right;
BinaryNode left;
BinaryNode parent;
static int level;
int height;


if(left!=null)
{
    left.height=left.parent.height+1;
    level=level+left.height;
    left.yourMethod();
}

if(right!=null)
{
    right.height= right.parent.height+1; 
    level=level+right.height;
    right.yourMethod();
}
现在,您将拥有存储所有高度的标高

另一种方法是使用队列进行广度优先搜索遍历,但答案是相同的。 希望这有帮助。

void addHeights(类树*根、整数深度、整数和) { 如果(根) { 添加高度(根->左,深度+1,总和);
添加高度(根->右,深度+1,总和); 总和+=深度; } }

public int sum(){
返回和(根);
}
私有整数和(二进制节点n){
如果(n==null)
返回0;
其他的
返回n.data+sum(n.left)+sum(n.right);
}
我需要更多的数据来评估代码,尽管我假设您将节点内的数据称为“数据”


因此,如果节点为null,则表示已到达树的末尾并返回0。否则,它将获取数据并向左然后向右遍历。每次递归都会添加这些节点,直到它们不再是要添加的节点。

我想你误解了我的问题,我想得到所有节点高度的总和,而不是找到树的高度。作为左子节点输入参数如何,右键单击子节点,然后添加所有高度结果?此方法提供单个节点的高度。如果创建另一个函数,将其应用于树中的每个节点并添加结果,会怎么样?这将是O(n^2*logn)(这很糟糕),但会起作用。使用全局变量来跟踪总数。不需要回溯算法;只需在计算高度时将其存储在地图中即可;应该有-1而不是返回0。
public int sum(){
    return sum(root);
}
private int sum(BinaryNode <?> n){
    if(n == null)
        return 0;
    else
        return n.data + sum(n.left) + sum(n.right);

}