Binary trees are hierarchical data structures where each node has at most two children: a left child and a right child. Working with binary trees often involves visiting every node in the tree to perform some operation, which is called tree traversal.
The key insight for most tree problems is that trees have a recursive structure - every subtree is also a binary tree! This means we can solve tree problems by:
When working with tree traversal, you always need a base case to stop the recursion. For binary trees, this is typically when you encounter a None node (an empty subtree).
Recursion works well with trees because:
Let's look at a simple example of tree traversal - counting the total number of nodes:
1def count_nodes(root):
2 # Base case: empty tree has 0 nodes
3 if root is None:
4 return 0
5
6 # Count current node (1) plus nodes in left and right subtrees
7 left_count = count_nodes(root.left)
8 right_count = count_nodes(root.right)
9
10 return 1 + left_count + right_count