JavaScript Coding Test Course, Counting the Number of Leaf Nodes

1. Problem Definition

The problem is to count the number of leaf nodes in a binary tree. A leaf node is a node that has no child nodes. Counting the number of nodes with no children is a good exercise for understanding the structure of the tree and utilizing exploration algorithms. To solve this problem, we can approach it using either recursive or iterative methods.

2. Problem Example

Let’s assume we are given the following binary tree:

             1
            / \
           2   3
          / \
         4   5
        

The leaf nodes of the above tree are 4, 5, and 3, totaling 3. We need to receive a tree like this as input and return the number of leaf nodes.

3. Algorithm Approach

There are several ways to determine the number of leaf nodes. The most common method we will use is Depth-First Search (DFS) utilizing recursion. This method involves exploring the tree in a depth-first manner to find leaf nodes and count them.

4. Algorithm Explanation

The following is a basic outline of the algorithm to count leaf nodes:

  1. Check if the given node is null. If it is null, return 0.
  2. If the node is a leaf node (i.e., both left and right children are null), return 1.
  3. Recursively call the left and right subtrees to determine the count of leaf nodes in each.
  4. Add the counts of the left and right leaf nodes and return the result.

5. JavaScript Implementation

Below is the code implementing the above algorithm using JavaScript:

            
                class TreeNode {
                    constructor(value) {
                        this.value = value;
                        this.left = null;
                        this.right = null;
                    }
                }

                function countLeafNodes(node) {
                    // Base case: null node
                    if (node === null) {
                        return 0;
                    }
                    // Leaf node condition
                    if (node.left === null && node.right === null) {
                        return 1;
                    }
                    // Count leaf nodes with a recursive call
                    return countLeafNodes(node.left) + countLeafNodes(node.right);
                }

                // Example tree construction
                const root = new TreeNode(1);
                root.left = new TreeNode(2);
                root.right = new TreeNode(3);
                root.left.left = new TreeNode(4);
                root.left.right = new TreeNode(5);

                console.log(countLeafNodes(root)); // Expected output: 3
            
        

6. Algorithm Analysis

The time complexity of this algorithm is O(n) because we need to visit every node in the tree once. Here, n refers to the number of nodes. The space complexity is O(h) in the worst case, where h represents the height of the tree. This is due to the depth of the recursive call stack.

If the tree is empty or if all nodes are skewed to one side, the stack depth may increase. If the tree is balanced, the height would be log(n).

7. Iterative Method

We can also implement DFS using an iterative approach. This involves using a stack to track the current node and count nodes with no children. Below is an example of an iterative implementation:

            
                function countLeafNodesIterative(root) {
                    if (root === null) {
                        return 0;
                    }

                    let stack = [root];
                    let leafCount = 0;

                    while (stack.length > 0) {
                        let node = stack.pop();

                        // Check if the node is a leaf node
                        if (node.left === null && node.right === null) {
                            leafCount++;
                        }

                        // Add child nodes to the stack
                        if (node.right !== null) {
                            stack.push(node.right);
                        }
                        if (node.left !== null) {
                            stack.push(node.left);
                        }
                    }

                    return leafCount;
                }

                console.log(countLeafNodesIterative(root)); // Expected output: 3
            
        

8. Conclusion

In this tutorial, we explored how to count leaf nodes in a binary tree. We confirmed that both recursive and iterative methods can be used to approach this problem. I hope this has helped deepen your understanding of tree data structures and DFS exploration algorithms. I want to emphasize that analyzing the performance of algorithms and considering efficiency is crucial in learning data structures and algorithms.