Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 54

In-Order Traversal for Sorted BST Elements

Recommended resources

Hello! Welcome to the final lesson in our module on Binary Search Trees.

In our last session, we explored how to validate if a given binary tree is a BST. We touched upon an elegant method using in-order traversal, noting that for a valid BST, this traversal visits nodes in ascending order. Today, we're going to dive deep into that very concept.

This lesson is dedicated to mastering in-order traversal. It's a fundamental tree algorithm and one of the most powerful properties of a BST, frequently used in competitive programming to sort elements or find the k-th smallest element. You will learn to perform an in-order traversal on a BST to retrieve its elements in a sorted sequence, implementing it both recursively and, crucially, iteratively with a stack.

The "Left, Node, Right" Rule and Its Magic

First, let's formally define in-order traversal. It's a type of Depth-First Search (DFS) that follows a simple, recursive rule for any given node:

  1. Traverse the left subtree.
  2. Visit the node itself (e.g., print its value or add it to a list).
  3. Traverse the right subtree.

This is often remembered by the mnemonic LNR.

Now, recall the core property of a Binary Search Tree: for any node, all values in its left subtree are smaller, and all values in its right subtree are larger. When you combine the LNR traversal rule with this BST property, a remarkable outcome occurs: the nodes are visited in sorted, ascending order.

  • By recursively going to the leftmost descendant first, you guarantee you visit the smallest value.
  • After visiting all smaller values in the left subtree, you visit the current node.
  • Finally, you visit all the larger values in the right subtree.

This process ensures a naturally sorted output.

BST In-Order Traversal Illustration
This image illustrates the recursive "Left, visit Node, Right" logic of an in-order traversal applied to a BST. As you can see, following this rule ensures that the nodes are processed in their numerical order (1, 2, 3, 4, 5, 6, 7, 8).

To see a clear walkthrough and contrast in-order with pre-order and post-order traversals, the following video provides an excellent explanation.

Binary Tree Part 1 | BST | Binary Search Tree - Data Structures & Algorithms Tutorials In Python #10

Watch this segment from the 'codebasics' channel to solidify your understanding of the different DFS traversal types and see the in-order traversal logic explained.

Watch from 06:38 to 09:47. Focus on how the 'in-order' traversal rule (left, root, right) is applied recursively to produce a sorted list from the example BST.


1. The Recursive Implementation

Because the definition of in-order traversal is inherently recursive, implementing it with a recursive function is the most direct and intuitive approach. The function's logic directly mirrors the LNR rule.

Let's study a concise guide that explains the algorithm and presents a clean Python implementation.

Inorder Traversal: A Comprehensive Guide

This article from AlgoCademy provides a clear definition and a straightforward recursive implementation of in-order traversal.

Read the sections '1. What is Inorder Traversal?', '3. How Inorder Traversal Works', and the 'Recursive Approach' under section 4. Pay attention to how the Python code uses a helper function to build the result list.

Here is a typical implementation you might write in a competitive programming context. It uses a helper function to pass the result list by reference.

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def inorderTraversal_recursive(root: TreeNode) -> list[int]:
    result = []

    def traverse(node):
        # Base case: do nothing if the node is null
        if not node:
            return
        
        # 1. Traverse the left subtree
        traverse(node.left)
        
        # 2. Visit the node
        result.append(node.val)
        
        # 3. Traverse the right subtree
        traverse(node.right)

    traverse(root)
    return result

# Example usage with a BST:
#       4
#      / \
#     2   6
#    / \ / \
#   1  3 5  7
root = TreeNode(4, 
              TreeNode(2, TreeNode(1), TreeNode(3)), 
              TreeNode(6, TreeNode(5), TreeNode(7)))

print(inorderTraversal_recursive(root))
# Output: [1, 2, 3, 4, 5, 6, 7]
Test your understanding!

Imagine a BST with the root 20, left child 10, and right child 30. Trace the traverse function calls. In what order are the append operations executed?

Show answer
  1. traverse(20) is called.
  2. It calls traverse(10) (left child of 20).
  3. traverse(10) tries to call traverse(None) (left child of 10), which returns.
  4. traverse(10) appends 10 to the result.
  5. traverse(10) tries to call traverse(None) (right child of 10), which returns.
  6. traverse(10) finishes. Control returns to traverse(20).
  7. traverse(20) appends 20 to the result.
  8. It calls traverse(30) (right child of 20).
  9. Following the same logic, traverse(30) eventually appends 30.
  10. The final appended order is 10, 20, 30.

2. The Iterative Implementation

While recursion is intuitive, it has drawbacks. In competitive programming, a very deep tree can cause a "RecursionError" (stack overflow). An iterative solution using an explicit stack avoids this and is often a required skill in technical interviews.

The goal is to simulate the recursive call stack manually. The core idea is:

  1. Keep pushing left children onto a stack until you can't go left anymore. The node at the top of the stack is the next one to be visited.
  2. Pop a node from the stack, process its value.
  3. Move to its right child and repeat the process.

This might seem tricky at first, but it perfectly mimics what the computer does during recursion. The following video provides one of the best explanations available for this process.

Iterative & Recursive - Binary Tree Inorder Traversal - Leetcode 94 - Python

This NeetCode video masterfully explains how to convert the recursive in-order traversal into an iterative one. It first simulates the call stack, then builds the iterative code from that logic.

Watch from 04:36 to 14:29. First, focus on the simulation (starting at 04:36) to understand how a manual stack can replicate recursion. Then, study the Python code (starting at 11:36) that implements this exact logic.

Here is a clean iterative implementation, similar to what you saw in the video and resources.

def inorderTraversal_iterative(root: TreeNode) -> list[int]:
    result = []
    stack = []
    current = root

    # Loop as long as there are nodes to process or nodes on the stack
    while current or stack:
        # 1. Go to the leftmost node
        while current:
            stack.append(current)
            current = current.left
        
        # At this point, `current` is None. Pop the last-seen node.
        # This is the next node to be visited in the in-order sequence.
        current = stack.pop()
        
        # 2. Visit the node
        result.append(current.val)
        
        # 3. Move to the right subtree to repeat the process
        current = current.right

    return result

print(inorderTraversal_iterative(root))
# Output: [1, 2, 3, 4, 5, 6, 7]

This pattern is extremely useful and can be adapted for pre-order and post-order iterative traversals as well. Mastering it is a significant step in your competitive programming preparation.


Complexity and Final Notes

  • Time Complexity: O(N), where N is the number of nodes. Both recursive and iterative approaches visit each node exactly once.
  • Space Complexity: O(H), where H is the height of the tree. This space is used by the recursion call stack (recursive) or the manual stack (iterative). In a balanced BST, H is approximately log(N). In the worst case (a skewed tree, like a linked list), H is N, making the space complexity O(N).

Finally, remember that this property holds for any comparable data types, not just integers. If you build a BST of strings, an in-order traversal will yield the strings in alphabetical order, as demonstrated in the codebasics video (LINK, section from 22:03).


Conclusion

You have now completed the module on Binary Search Trees! In this lesson, you mastered one of the most elegant properties of a BST.

Key Takeaways:

  • In-order traversal (LNR) on a Binary Search Tree always retrieves the elements in sorted ascending order.
  • The recursive implementation is intuitive and directly follows the LNR definition.
  • The iterative implementation using a stack is a crucial, non-trivial technique that avoids recursion limits and demonstrates a deeper understanding of stack-based algorithms.
  • Both methods have a time complexity of O(N) and a space complexity of O(H).

Up Next:
You've built a solid foundation in trees, a hierarchical data structure. We are now ready to generalize these concepts to more complex structures. In the next module, we will begin our study of Graph Traversal Algorithms. You will find that tree traversals like DFS are special cases of graph traversal, and concepts like queues and stacks will be just as critical.