Count number of left nodes in BST

爱⌒轻易说出口 提交于 2019-12-09 03:08:48

问题


Given a BST, I am required to find the number of left nodes of the tree.

Example: `

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

The answer should be 4, as (5, 1 , 4, 7) are all left nodes of the tree.

What I am thinking of doing is:

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;
}

I know it is wrong, but I don't know why. Could someone explain why, and also help me with the answer.


回答1:


The second recursion branch overwrites the value from the first. Also you should add 1 for the left root.

Something like:

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;
}



回答2:


There is no need to propagate an accumulator (the count parameter) down the call stack, since you aren't relying on tail-recursion.

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;
}



回答3:


In your second line here

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

you discard the previous value of count. Perhaps it should be += instead of =.

I would however express it like this:

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



回答4:


I think you have to restructure your code a little. Instead of passing current count for left nodes, just receive it from the two children and add them up.




回答5:


I think the most elegant solution is this one. Yes, of course I'm biased. I'm human :-)

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

total = countLeft (root, 0)

By passing down the indicator for left nodes, it simplifies what has to be passed up. The following diagram shows each sum being passed up - you start at the bottom and each null passes up 0.

Each node on the left passes up 1 plus whatever came from both branches below. Each node on the right passes up 0 plus whatever came from both branches below.

The root adds nothing since it is neither a left nor right node (it's treated the same as right).

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

You can see the operation from this complete program:

#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;
}

which outputs the debugging lines:

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

The non-debugging version of the countLeft function is as simple as the pseudo-code at the start of this answer:

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


来源:https://stackoverflow.com/questions/4075947/count-number-of-left-nodes-in-bst

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!