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:
- Check if the given node is null. If it is null, return 0.
- If the node is a leaf node (i.e., both left and right children are null), return 1.
- Recursively call the left and right subtrees to determine the count of leaf nodes in each.
- 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.