Skip to content

Tree Traversal: Code Templates in 6 Languages

If you have not read the concept guide yet, start there for the intuition and complexity analysis. This page gives you the code you can memorize and adapt during an interview. Every template here runs in

O(N)
time. Space is
O(H)
for the depth-first versions and
O(W)
for level-order, where H is the tree height and W is the width of the widest level.

TreeNode Definition

The solutions on this page and on the practice problems page assume this node class, which is the same one LeetCode provides in its editor.

class TreeNode {
    constructor(val = 0, left = null, right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

Main Template: Recursive Inorder Traversal

This is the template to memorize first, because every depth-first traversal is this function with one line moved. Recurse left, process the node, recurse right. In a BST the output comes back sorted, which is the property that validation problems build on.

Use this for Binary Tree Inorder Traversal .

function inorderTraversal(root) {
    const result = [];

    function inorder(node) {
        if (!node) return;

        // The left subtree must finish before this node
        // so that smaller values appear first
        inorder(node.left);
        result.push(node.val);
        inorder(node.right);
    }

    inorder(root);
    return result;
}
Templates only help if you can recall them without staring at the screen. Turn these snippets into flashcards for daily mobile review.

Code Breakdown

Key Variables

VariablePurpose
nodeThe subtree currently being processed. Null means the subtree is empty and the recursion stops.
resultCollects node values in visit order.
stackIn the iterative version, remembers ancestors whose right subtree is still pending.
queueIn level-order, holds the next level while the current one is processed.
levelSizeSnapshot of the queue length taken before a level starts, so levels never merge.

Visual Mechanism

    flowchart TD
    A["inorder(node)"] --> B{"node is null?"}
    B -->|Yes| R["Return"]
    B -->|No| L["inorder(node.left)"]
    L --> P["Process node.val"]
    P --> RT["inorder(node.right)"]
    RT --> D["Return"]
  

Critical Sections

The base case is the null check at the top. Without it the recursion never stops and the first leaf throws. With it, an empty tree and a single node both work with no special cases.

The order of the three lines is the entire pattern. The left subtree must finish before the node is processed, and the node must be processed before the right subtree starts. For a BST that ordering is what turns the walk into a sorted sequence.

The result list is shared across all calls. Each recursive call appends its node and returns, so the list grows in visit order without any explicit combining step.

Variations

1. Iterative Inorder (Explicit Stack)

Use this when the tree can be deep enough to overflow the call stack. The behavior is identical to the recursive version. The stack plays the role the call stack played, so the traversal order does not change.

function inorderTraversalIterative(root) {
    const result = [];
    const stack = [];
    let current = root;

    while (current || stack.length) {
        // Push every left child on the way down. The
        // stack remembers ancestors whose right subtree
        // still needs processing.
        while (current) {
            stack.push(current);
            current = current.left;
        }

        // The top of the stack is the next node in
        // inorder order. Process it and move right.
        current = stack.pop();
        result.push(current.val);
        current = current.right;
    }

    return result;
}

2. Level-Order Traversal (BFS)

Use this when the answer depends on depth. Printing levels, finding shortest paths, and anything else that must see the tree one level at a time all need it. A queue holds the current level, and a size snapshot keeps levels from merging.

Use this for Binary Tree Level Order Traversal .

function levelOrder(root) {
    if (!root) return [];

    const result = [];
    const queue = [root];

    while (queue.length) {
        // Snapshot the size before the loop. Children
        // added during this level must wait for the next.
        const levelSize = queue.length;
        const currentLevel = [];

        for (let i = 0; i < levelSize; i++) {
            const node = queue.shift();
            currentLevel.push(node.val);
            if (node.left) queue.push(node.left);
            if (node.right) queue.push(node.right);
        }

        result.push(currentLevel);
    }

    return result;
}

3. Preorder and Postorder

Both are the recursive skeleton with the process line moved. Preorder processes the node before its children, so the root of every subtree arrives first. That is what serialization and cloning rely on. Postorder processes children first, which is what height and path-sum calculations rely on, because the parent needs both subtree answers before it can compute its own.

function preorderTraversal(root) {
    const result = [];

    function preorder(node) {
        if (!node) return;

        // Root before children, so the root of every
        // subtree arrives first. Serialization and
        // cloning rely on that order.
        result.push(node.val);
        preorder(node.left);
        preorder(node.right);
    }

    preorder(root);
    return result;
}

function postorderTraversal(root) {
    const result = [];

    function postorder(node) {
        if (!node) return;

        // Children before root, because the parent can
        // only be processed once both subtree answers exist.
        postorder(node.left);
        postorder(node.right);
        result.push(node.val);
    }

    postorder(root);
    return result;
}
Each variation above is a separate review card in the app. Drill them individually so you do not mix up the conditions under pressure.

Now head to the practice problems to apply these templates to real interview questions.

Now that you have the templates, the next step is application. Head to the practice problems or start reviewing these templates with spaced repetition .