计算BST中左节点的数量

时间:2010-11-02 08:22:29

标签: binary-tree

鉴于BST,我需要找到树的左节点数。

示例:`

          +---+
          | 3 |
          +---+
         /     \
     +---+     +---+
     | 5 |     | 2 |
     +---+     +---+
    /         /     \
+---+     +---+     +---+
| 1 |     | 4 |     | 6 |
+---+     +---+     +---+
         /
     +---+
     | 7 |
     +---+`

答案应该是4,因为(5,1,4,7)都是树的左边节点。

我在想的是:

public int countLeftNodes() {
    return countLeftNodes(overallRoot, 0);
}

private int countLeftNodes(IntTreeNode overallRoot, int count) {
    if (overallRoot != null) {
        count += countLeftNodes(overallRoot.left, count++);    
        count = countLeftNodes(overallRoot.right, count);
    }
    return count;
}

我知道这是错的,但我不知道为什么。有人可以解释原因,并帮助我解答答案。

6 个答案:

答案 0 :(得分:6)

第二个递归分支将覆盖第一个递归分支。你也应该为左根添加1。

类似的东西:

private int countLeftNodes(IntTreeNode node) {
    int count = 0;
    if (node.left != null) 
        count += 1 + countLeftNodes(node.left);    

    if (node.right != null)
        count += countLeftNodes(node.right);


    return count;
}

答案 1 :(得分:3)

不需要在调用堆栈中传播累加器(count参数),因为您不依赖于尾递归。

public int countLeftNodes(IntTreeNode node) {
    // This test is only needed if the root node can be null.
    if (node == null) return 0;

    int count = 0;
    if (node.left != null) {
        count += 1 + countLeftNodes(node.left);
    }
    if (node.right != null) {
        count += countLeftNodes(node.right);
    }
    return count;
}

答案 2 :(得分:1)

在你的第二行

count += countLeftNodes(overallRoot.left, count++);    
count = countLeftNodes(overallRoot.right, count);

您丢弃之前的计数值。也许它应该是+=而不是=

然而,我会这样表达:

private int countLeftNodes(IntTreeNode root) {
    return (root.left  == null ? 0 : countLeftNodes(root.left) + 1) +
           (root.right == null ? 0 : countLeftNodes(root.right));
}

答案 3 :(得分:0)

我认为你必须重新调整你的代码。

,而不是传递左节点的当前计数,只需从两个孩子那里接收它

答案 4 :(得分:0)

我认为最优雅的解决方案就是这个。是的,当然我有偏见。我是人类: - )

def countLeft (node,ind):
    if node == null: return 0
    return ind + countLeft (node->left, 1) + countLeft (node->right, 0)

total = countLeft (root, 0)

通过传递左节点的指示符,它简化了必须传递的内容。下图显示了传递的每个总和 - 从底部开始,每个空值向上传递0.

左边的每个节点向上传递1加上来自下面两个分支的任何东西。右边的每个节点向上传递0加上来自下面两个分支的任何东西。

root没有添加任何东西,因为它既不是左边节点也不是右边节点(它的处理方式与右边节点相同)。

                        4
                        ^
                        |
                      +---+
                      | 3 |
            __________+---+__________
           /2                       2\
      +---+                           +---+
      | 5 |                           | 2 |
      +---+                           +---+
     /1                              /2   0\
 +---+                          +---+       +---+
 | 1 |                          | 4 |       | 6 |
 +---+                          +---+       +---+
/0   0\                        /1   0\     /0   0\
                          +---+
                          | 7 |
                          +---+
                         /0   0\

您可以在此完整程序中查看操作:

#include <stdio.h>

typedef struct sNode { int val; struct sNode *left, *right; } tNode;

#define setNode(N,V,L,R) N.val = V; N.left = L; N.right = R

int countLeft (tNode *node, int ind) {
    if (node == NULL) return 0;
    int x = ind + countLeft (node->left, 1) + countLeft (node->right, 0);
    printf ("Node %d passing up %d\n", node->val, x);
    return x;
}

int main (void) {
    tNode n3, n5, n1, n2, n4, n6, n7;
    setNode (n3, 3, &n5, &n2);
    setNode (n5, 5, &n1, NULL);
    setNode (n1, 1, NULL, NULL);
    setNode (n2, 2, &n4, &n6);
    setNode (n4, 4, &n7, NULL);
    setNode (n7, 7, NULL, NULL);
    setNode (n6, 6, NULL, NULL);

    printf ("countLeft is %d\n", countLeft (&n3, 0));
    return 0;
}

输出调试行:

Node 1 passing up 1
Node 5 passing up 2
Node 7 passing up 1
Node 4 passing up 2
Node 6 passing up 0
Node 2 passing up 2
Node 3 passing up 4
countLeft is 4

countLeft函数的非调试版本与本答案开头的伪代码一样简单:

int countLeft (tNode *node, int ind) {
    if (node == NULL) return 0;
    return ind + countLeft (node->left, 1) + countLeft (node->right, 0);
}

答案 5 :(得分:0)

计算左节点的函数(只有左子节点: 您可以使用递归方法做些什么,如果只存在左孩子,则返回 1。

    int count_left_nodes(tree_type* root)
     {

     if(root == NULL)       
        return 0;
     if(root->left != NULL && root->right==NULL)      
        return 1;            
     else 
        return count_left_nodes(root->left)+
            count_left_nodes(root->right); 

     }