Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine size of Integer Binary Tree via recursion

I have the classes BinaryTreeNode(int value) with its left and right child and BinaryTree(int rootVal) with BinaryTreeNode root with rootVal as its value. I developed a code to calculate the number of nodes in the tree (in class BinaryTreeNode), but it doesn't work because of a NullPointerException:

public int size(){
    if(this == null) {    // base case
        return 0;
    } else {
        return 1 + left.size() + right.size();
    }
}

However another solution I found, with a similar strategy, works:

public int size(BinaryTreeNode refNode){
    if(refNode == null) {    // base case
        return 0;       
    } else {
        return 1 + size(refNode.left) + size(refNode.right); 
    }
}

I have understood why my code throws an exception (it is because left/right would point to null). But I would like to understand why the second solution works with quasi the same principle. Thank you in advance!

like image 365
soupwaylee Avatar asked Dec 20 '15 18:12

soupwaylee


People also ask

How do you find the recursive size of a tree?

Size() function recursively calculates the size of a tree. It works as follows: Size of a tree = Size of left subtree + 1 + Size of right subtree.

What is the recursive formula to find the height of a binary tree?

The height of a binary tree is found using the recursive Depth-First Search (DFS) algorithm, as shown below: Base case: If there is no node, return 0. Else: If there are 1 or 2 children, return the maximum of the height of the left and right sub-trees, plus 1 to account for the current node.


2 Answers

In your first example you try to find the size before you check for null:

first you call

left.size()

and then inside the size() method you check to see if the object you just called the method on is null

if(this == null) {    // base case
    return 0;
...

so if left is null, you get the NPE before you get into the size() method.

The main thing to remember here, is that this can never be null. If it was, you couldn't be running a method on it in the first place. So you weren't actually terminating your recursion on a null case like you thought you were.


In the second you check for null first:

if refNode.left is null here

    return 1 + size(refNode.left) + size(refNode.right); 

the size() method does a pre-check

if(refNode == null) {    // base case
    return 0;
...

and safely returns 0.


You could make your first method work by explicitly putting the null-check first on each branch:

public int size(){
    return 1 
        + left == null ? 0 : left.size()    // check for null first
        + right == null ? 0 : right.size(); // check for null first
}
like image 91
azurefrog Avatar answered Oct 17 '22 17:10

azurefrog


The base case is organized in the wrong way; checking for null on the current instance makes no sense. The method should be rewritten as follows.

public int size(){
    int sizeLeft = 0;
    if (this.left != null)
        sizeLeft = left.size();
    int sizeRight = 0;
    if (this.right != null)
        sizeRight = right.size();
    return 1 + sizeLeft + sizeRight;
}
like image 36
Codor Avatar answered Oct 17 '22 19:10

Codor