Home DSA Height and Depth of a Binary Tree Explained — With Code and Visuals

Height and Depth of a Binary Tree Explained — With Code and Visuals

In Plain English 🔥
Picture a family tree hanging on a wall. The great-grandparent at the top is the root. The depth of any person on that tree is simply how many generations down they sit from the top — grandchildren are deeper than children. The height of the whole tree is just how many generations tall it is from top to bottom. That's it. Height and depth are just ways of measuring position and size inside a tree structure.
⚡ Quick Answer
Picture a family tree hanging on a wall. The great-grandparent at the top is the root. The depth of any person on that tree is simply how many generations down they sit from the top — grandchildren are deeper than children. The height of the whole tree is just how many generations tall it is from top to bottom. That's it. Height and depth are just ways of measuring position and size inside a tree structure.

Binary trees show up everywhere in software — from how your operating system organises files, to how databases run lightning-fast searches, to how compilers parse your code. Before you can work with any of those systems, you need to be able to answer two deceptively simple questions: 'How deep is this node?' and 'How tall is this tree?' Those two questions have precise answers, and knowing them unlocks a huge chunk of tree-related problem solving.

The confusion beginners run into is that height and depth sound like the same thing — and in everyday English they almost are. But in binary trees they measure opposite directions. Depth is measured top-down (root toward leaves). Height is measured bottom-up (leaves toward root). Mix them up and your algorithms silently produce wrong answers, which is one of the most frustrating kinds of bug to track down.

By the end of this article you'll be able to define height and depth precisely, calculate both by hand on any tree you draw, write a clean recursive Java implementation from memory, and explain the difference confidently in an interview. We'll build everything from zero — no prior tree knowledge assumed.

What Is a Binary Tree? (Building the Foundation)

Before we measure anything, let's make sure we agree on what we're measuring.

A binary tree is a collection of nodes where each node stores a value and can have at most two children — a left child and a right child. The topmost node (with no parent) is called the root. Nodes with no children at all are called leaf nodes.

Think of it like a tournament bracket. There's one champion at the top (the root). That champion beat two finalists (left and right children). Each finalist beat two semi-finalists, and so on, all the way down to the first-round players who never won a match (the leaves).

Here's the tree we'll use throughout this entire article. Keep this picture in your head:

`` 10 <- Root (Level 0) / \ 5 20 <- Level 1 / \ \ 3 7 25 <- Level 2 / 1 <- Level 3 (deepest leaf) ``

Every measurement we make in the following sections uses exactly this tree. No surprises.

BinaryTreeNode.java · JAVA
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
// A single node in a binary tree.
// Each node holds a value and optional references to a left and right child.
public class BinaryTreeNode {

    int value;                  // The data stored at this node
    BinaryTreeNode leftChild;   // Reference to the left subtree (null if none)
    BinaryTreeNode rightChild;  // Reference to the right subtree (null if none)

    // Constructor: create a new node with a value and no children yet
    public BinaryTreeNode(int value) {
        this.value = value;
        this.leftChild = null;
        this.rightChild = null;
    }

    // Helper method so we can print a node nicely (useful for debugging)
    @Override
    public String toString() {
        return "Node(" + value + ")";
    }

    // --- Build the example tree from the article ---
    public static BinaryTreeNode buildExampleTree() {
        //          10
        //         /  \
        //        5    20
        //       / \     \
        //      3   7    25
        //     /
        //    1

        BinaryTreeNode root    = new BinaryTreeNode(10);
        BinaryTreeNode node5   = new BinaryTreeNode(5);
        BinaryTreeNode node20  = new BinaryTreeNode(20);
        BinaryTreeNode node3   = new BinaryTreeNode(3);
        BinaryTreeNode node7   = new BinaryTreeNode(7);
        BinaryTreeNode node25  = new BinaryTreeNode(25);
        BinaryTreeNode node1   = new BinaryTreeNode(1);

        root.leftChild          = node5;   // 10's left child is 5
        root.rightChild         = node20;  // 10's right child is 20
        node5.leftChild         = node3;   // 5's left child is 3
        node5.rightChild        = node7;   // 5's right child is 7
        node20.rightChild       = node25;  // 20's right child is 25
        node3.leftChild         = node1;   // 3's left child is 1

        return root; // hand back the top of the tree
    }

    public static void main(String[] args) {
        BinaryTreeNode root = buildExampleTree();
        System.out.println("Root node: " + root);
        System.out.println("Root's left child: " + root.leftChild);
        System.out.println("Root's right child: " + root.rightChild);
        System.out.println("Deepest leaf: " + root.leftChild.leftChild.leftChild);
    }
}
▶ Output
Root node: Node(10)
Root's left child: Node(5)
Root's right child: Node(20)
Deepest leaf: Node(1)
🔥
Quick Vocab Check:Root = top node (no parent). Leaf = bottom node (no children). Edge = the line connecting a parent to a child. These three words are all you need for the next two sections.

Depth of a Node — How Far Down Are You?

The depth of a node is the number of edges (connections) you travel from the root to reach that node.

The root itself has depth 0 — you're already there, no travel needed. Its direct children have depth 1. Their children have depth 2, and so on.

Using our example tree: - Node 10 (root): depth 0 - Node 5, Node 20: depth 1 - Node 3, Node 7, Node 25: depth 2 - Node 1: depth 3

The rule is beautifully simple: depth(node) = depth(parent) + 1.

To calculate depth in code, you walk down from the root, counting each step until you find the target node. This is naturally a recursive or iterative search — you don't know the depth until you've found the node.

One important mental model: depth is a property of a specific node relative to the root. Two nodes at the same level always have the same depth. You can't talk about 'the depth of the tree' — that would be the height (coming up next).

NodeDepthFinder.java · JAVA
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
public class NodeDepthFinder {

    // Finds the depth of the node containing 'targetValue' in the tree.
    // 'currentNode'  — the node we are currently visiting
    // 'targetValue'  — the value we are searching for
    // 'currentDepth' — how many edges we have already travelled from the root
    //
    // Returns -1 if the value is not found in the tree.
    public static int findDepth(BinaryTreeNode currentNode, int targetValue, int currentDepth) {

        // Base case 1: we fell off the edge of the tree — node doesn't exist
        if (currentNode == null) {
            return -1; // signal that we couldn't find the target
        }

        // Base case 2: we found the target node!
        if (currentNode.value == targetValue) {
            return currentDepth; // the depth is however far we've already travelled
        }

        // Recursive case: search the left subtree first
        int depthInLeftSubtree = findDepth(currentNode.leftChild, targetValue, currentDepth + 1);

        // If left subtree found it, no need to check right subtree
        if (depthInLeftSubtree != -1) {
            return depthInLeftSubtree;
        }

        // Otherwise, search the right subtree
        return findDepth(currentNode.rightChild, targetValue, currentDepth + 1);
    }

    public static void main(String[] args) {
        BinaryTreeNode root = BinaryTreeNode.buildExampleTree();

        // Test every node in our example tree
        int[] valuesToCheck = {10, 5, 20, 3, 7, 25, 1};

        System.out.println("Node Value | Depth");
        System.out.println("-----------|------");

        for (int value : valuesToCheck) {
            // Always start the search from the root at depth 0
            int depth = findDepth(root, value, 0);
            System.out.printf("    %2d     |   %d%n", value, depth);
        }

        // What happens when we search for a value that isn't in the tree?
        int missingDepth = findDepth(root, 99, 0);
        System.out.println("\nDepth of missing node (99): " + missingDepth);
    }
}
▶ Output
Node Value | Depth
-----------|------
10 | 0
5 | 1
20 | 1
3 | 2
7 | 2
25 | 2
1 | 3

Depth of missing node (99): -1
⚠️
Interview Gold:Interviewers love asking 'what does depth of the root equal?' The answer is always 0 — not 1. The root has travelled zero edges to reach itself. Saying '1' is the most common slip-up in interviews.

Height of a Node and Tree — How Tall Are You?

Height flips the direction. Where depth asks 'how far from the top?', height asks 'how far to the bottom?'

The height of a node is the number of edges on the longest path from that node down to any leaf below it.

Leaf nodes have height 0 — there are no edges below them, nowhere left to go. Their parents have height 1. The root's height equals the height of the entire tree.

Using our example tree: - Node 1 (leaf): height 0 - Node 3 (parent of 1): height 1 - Node 7, Node 25 (leaves): height 0 - Node 5 (path: 5→3→1 = 2 edges): height 2 - Node 20 (path: 20→25 = 1 edge): height 1 - Node 10 (root, path: 10→5→3→1 = 3 edges): height 3

The recursive formula is elegant: height(node) = 1 + max(height(leftChild), height(rightChild)).

You pick the taller of the two subtrees and add 1 for the edge connecting you to it. Recursion bottoms out at null nodes, which we define as having height -1 (so a single leaf correctly gets height 0).

TreeHeightCalculator.java · JAVA
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
public class TreeHeightCalculator {

    // Calculates the height of any given node.
    // Height = number of edges on the LONGEST path from this node to a leaf below it.
    //
    // Key insight: a null node has height -1 by convention.
    // This makes a single leaf node correctly return height 0:
    //   height(leaf) = 1 + max(-1, -1) = 1 + (-1) = 0  ✓
    public static int calculateHeight(BinaryTreeNode node) {

        // Base case: null means we've gone past a leaf — define as -1
        if (node == null) {
            return -1;
        }

        // Recursively find the height of the left subtree
        int leftSubtreeHeight  = calculateHeight(node.leftChild);

        // Recursively find the height of the right subtree
        int rightSubtreeHeight = calculateHeight(node.rightChild);

        // This node's height = 1 edge to the taller child + that child's height
        int tallestChildHeight = Math.max(leftSubtreeHeight, rightSubtreeHeight);

        return 1 + tallestChildHeight;
    }

    public static void main(String[] args) {
        BinaryTreeNode root = BinaryTreeNode.buildExampleTree();

        // Height of the whole tree (measured from root)
        int treeHeight = calculateHeight(root);
        System.out.println("Height of the entire tree: " + treeHeight);

        // Individual node heights
        System.out.println("\nNode Value | Height");
        System.out.println("-----------|-------");
        System.out.printf("    %2d     |   %d  (root — tallest point)%n",   root.value,                                   calculateHeight(root));
        System.out.printf("    %2d     |   %d  (has subtree of depth 2)%n", root.leftChild.value,                         calculateHeight(root.leftChild));
        System.out.printf("    %2d     |   %d  (only one child below it)%n",root.rightChild.value,                        calculateHeight(root.rightChild));
        System.out.printf("    %2d     |   %d  (one leaf child below it)%n",root.leftChild.leftChild.value,               calculateHeight(root.leftChild.leftChild));
        System.out.printf("    %2d     |   %d  (leaf — no children)%n",     root.leftChild.leftChild.leftChild.value,     calculateHeight(root.leftChild.leftChild.leftChild));
        System.out.printf("    %2d     |   %d  (leaf — no children)%n",     root.leftChild.rightChild.value,              calculateHeight(root.leftChild.rightChild));
        System.out.printf("    %2d     |   %d  (leaf — no children)%n",     root.rightChild.rightChild.value,             calculateHeight(root.rightChild.rightChild));

        // Edge case: what is the height of an empty tree?
        int emptyTreeHeight = calculateHeight(null);
        System.out.println("\nHeight of an empty tree (null root): " + emptyTreeHeight);
    }
}
▶ Output
Height of the entire tree: 3

Node Value | Height
-----------|-------
10 | 3 (root — tallest point)
5 | 2 (has subtree of depth 2)
20 | 1 (only one child below it)
3 | 1 (one leaf child below it)
1 | 0 (leaf — no children)
7 | 0 (leaf — no children)
25 | 0 (leaf — no children)

Height of an empty tree (null root): -1
⚠️
Watch Out:Some textbooks define height as the number of nodes on the longest path (not edges). That makes a single-node tree height 1 instead of 0. Always clarify which definition an interviewer is using before you start coding — it changes your base case from -1 to 0.

Putting It All Together — One Complete Program

Now let's combine everything into a single runnable file that builds the tree, calculates both depth and height for every node, and prints a clean summary table.

This is the kind of code you'd actually write to verify your understanding before an interview. Running it and seeing the correct numbers builds real confidence — far more than just reading about it.

Notice the relationship between depth and height: for the root, depth is 0 and height is 3. For the deepest leaf (node 1), depth is 3 and height is 0. They're perfectly complementary — they always sum to the height of the tree for nodes on the longest path. That's a neat property worth remembering.

Also notice the time complexity: calculating height for a single node costs O(n) because you visit every node in its subtree. Calculating the depth of a single node costs O(d) where d is its depth — much cheaper if the tree is balanced.

HeightAndDepthDemo.java · JAVA
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
// Complete, self-contained demo.
// Builds the example tree and prints a full depth + height table.
public class HeightAndDepthDemo {

    // ── Node Definition ───────────────────────────────────────────
    static class TreeNode {
        int value;
        TreeNode left, right;

        TreeNode(int value) {
            this.value = value;
        }
    }

    // ── Tree Builder ───────────────────────────────────────────────
    //       10
    //      /  \
    //     5    20
    //    / \     \
    //   3   7    25
    //  /
    // 1
    static TreeNode buildTree() {
        TreeNode root   = new TreeNode(10);
        root.left       = new TreeNode(5);
        root.right      = new TreeNode(20);
        root.left.left  = new TreeNode(3);
        root.left.right = new TreeNode(7);
        root.right.right= new TreeNode(25);
        root.left.left.left = new TreeNode(1);
        return root;
    }

    // ── Height Calculation ─────────────────────────────────────────
    // Returns -1 for null (so a leaf correctly gets height 0)
    static int height(TreeNode node) {
        if (node == null) return -1;
        return 1 + Math.max(height(node.left), height(node.right));
    }

    // ── Depth Calculation ──────────────────────────────────────────
    // Returns -1 if targetValue is not found anywhere in the tree
    static int depth(TreeNode node, int targetValue, int currentDepth) {
        if (node == null)               return -1;            // not found
        if (node.value == targetValue)  return currentDepth;  // found it!

        int leftResult = depth(node.left,  targetValue, currentDepth + 1);
        if (leftResult != -1) return leftResult; // found in left subtree

        return depth(node.right, targetValue, currentDepth + 1); // try right
    }

    // ── Main ───────────────────────────────────────────────────────
    public static void main(String[] args) {
        TreeNode root = buildTree();

        int treeHeight = height(root);
        System.out.println("=== Binary Tree: Height and Depth Summary ===");
        System.out.println("Overall tree height: " + treeHeight + " edges");
        System.out.println();
        System.out.printf("%-12s %-8s %-8s %-10s%n", "Node Value", "Depth", "Height", "Depth+Height");
        System.out.println("----------------------------------------------");

        // All node values in our tree
        int[] allValues = {10, 5, 20, 3, 7, 25, 1};

        for (int val : allValues) {
            int d = depth(root, val, 0);   // depth from root
            int h = height(findNode(root, val)); // height from this node down
            System.out.printf("%-12d %-8d %-8d %-10d%n", val, d, h, d + h);
        }

        System.out.println("----------------------------------------------");
        System.out.println("Notice: depth + height = " + treeHeight + " for all nodes on the longest path.");
    }

    // Helper: returns the TreeNode with the given value (simple DFS search)
    static TreeNode findNode(TreeNode node, int targetValue) {
        if (node == null)              return null;
        if (node.value == targetValue) return node;
        TreeNode leftResult = findNode(node.left, targetValue);
        return (leftResult != null) ? leftResult : findNode(node.right, targetValue);
    }
}
▶ Output
=== Binary Tree: Height and Depth Summary ===
Overall tree height: 3 edges

Node Value Depth Height Depth+Height
----------------------------------------------
10 0 3 3
5 1 2 3
20 1 1 2
3 2 1 3
7 2 0 2
25 2 0 2
1 3 0 3
----------------------------------------------
Notice: depth + height = 3 for all nodes on the longest path.
🔥
Pattern to Remember:For every node that sits on the tree's longest (deepest) path: depth + height = total tree height. Node 10: 0+3=3. Node 5: 1+2=3. Node 3: 2+1=3. Node 1: 3+0=3. This identity is a quick sanity check you can use to verify your code is correct.
AspectDepth of a NodeHeight of a Node / Tree
What it measuresDistance from root DOWN to this nodeDistance from this node DOWN to the farthest leaf
DirectionTop-down (root → node)Bottom-up (node → leaf)
Root's value0 (no edges traversed)Equals the height of the whole tree
Leaf node's valueVaries — depends on where the leaf sitsAlways 0 (no edges below a leaf)
Empty tree (null)N/A — no node to measure-1 (by convention, so single-node tree = 0)
Formuladepth(node) = depth(parent) + 1height(node) = 1 + max(height(left), height(right))
Algorithm directionSearch from root downwardRecurse to leaves, then bubble results back up
Time complexityO(d) where d = depth of target nodeO(n) — must visit every node in subtree
Used forLevel-order traversal, BFS layersBalancing checks, tree rotation decisions

🎯 Key Takeaways

  • Depth measures top-down: it counts edges from the root to a specific node. Root always has depth 0.
  • Height measures bottom-up: it counts edges on the longest path from a node down to any leaf below it. Leaf nodes always have height 0.
  • Define null nodes as height -1 in your code — this is the correct base case that makes all other height values work out cleanly without special-casing leaves.
  • The height of the entire tree equals the height of the root node — they are the same measurement. You don't need a separate function for 'tree height'.

⚠ Common Mistakes to Avoid

  • Mistake 1: Treating null as height 0 instead of -1 — This causes leaf nodes to report height 1 instead of 0, and a tree with only a root reports height 1 instead of 0. Fix it by returning -1 for null in your height function: 'if (node == null) return -1;'. Then height(leaf) = 1 + max(-1, -1) = 0, which is correct.
  • Mistake 2: Starting depth at 1 instead of 0 — Beginners naturally think 'the root is on level 1' because humans count from 1. This shifts every depth answer up by 1 and breaks any algorithm that relies on depth = 0 meaning 'this is the root'. Always initialise currentDepth to 0 when you start the search from the root.
  • Mistake 3: Confusing height of the tree with height of the root — They are the same thing, but beginners sometimes try to separately 'count levels' rather than just calling height(root). There's no need for a separate tree-height function — the height of the tree IS the height of its root node. Calling calculateHeight(root) gives you the full tree height directly.

Interview Questions on This Topic

  • QWhat is the difference between the height and depth of a node in a binary tree? Can you give an example using a tree you draw on the whiteboard?
  • QWrite a recursive function to find the height of a binary tree. What is its time and space complexity, and why?
  • QA balanced binary tree has n nodes. What is the relationship between its height and n? (Expected answer: height is O(log n). Follow-up: what happens to height in the worst case, a skewed tree, and why?)

Frequently Asked Questions

What is the height of a binary tree with only one node?

It's 0. A single node is both the root and a leaf. There are no edges below it, so the longest path to a leaf has 0 edges. This is why we define null nodes as height -1: height(single node) = 1 + max(-1, -1) = 0.

Is the height of a tree the same as the number of levels?

Almost — but off by one. A tree with height 3 has 4 levels (levels 0, 1, 2, and 3). Height counts edges; levels count nodes on each tier. So number of levels = height + 1. This off-by-one trips people up constantly, so keep it in mind.

What is the depth of a tree versus the height of a tree?

Strictly speaking, 'depth of a tree' isn't a standard term — depth applies to individual nodes. The correct term for how tall the whole tree is is the 'height of the tree', which equals the height of the root node. Some textbooks loosely use depth of tree to mean the same as height, so if you see it in the wild, they almost certainly mean height.

🔥
TheCodeForge Editorial Team Verified Author

Written and reviewed by senior developers with real-world experience across enterprise, startup and open-source projects. Every article on TheCodeForge is written to be clear, accurate and genuinely useful — not just SEO filler.

← PreviousLevel Order Traversal of Binary TreeNext →AVL Tree
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged