Tree Traversals

Week 8, Tuesday

February 24, 2026

Announcements

Today:

  • Implementing Trees in Python
  • Tree Traversals

Representing Trees in Python

A tree node has a value and children (which are themselves trees!).

from dataclasses import dataclass

@dataclass
class Node:
    value
    left: 'Node' = None   # Another Node (or None)
    right: 'Node' = None  # Another Node (or None)

This is a recursive definition: a Node contains Nodes!

Building a Tree

# Build leaf nodes first
leaf_b = Node('b')
leaf_c = Node('c')
leaf_a = Node('a')
leaf_d = Node('d')
leaf_e = Node('e')

# Build internal nodes bottom-up
div_node = Node('/', leaf_b, leaf_c)
minus_node = Node('-', leaf_a, div_node)
times_node = Node('*', leaf_d, leaf_e)

# Build root
root = Node('+', minus_node, times_node)

Or more concisely (inside-out):

root = Node('+',
    Node('-', Node('a'), Node('/', Node('b'), Node('c'))),
    Node('*', Node('d'), Node('e')))

Tree Traversal

A scheme for visiting every node in a tree.

+ - * a / d e b c

Three Natural Orders

When visiting a node, we have three choices for when to “process” it:

  1. Before visiting children
  2. Between visiting left and right children
  3. After visiting children

These give us three classic traversals.

Preorder Traversal

Preorder: Process the node before its children

preorder(node):
    if node is None: return
    process(node)        # Visit node FIRST
    preorder(node.left)
    preorder(node.right)

Order: + - a / b c * d e

Inorder Traversal

Inorder: Process the node between its children

inorder(node):
    if node is None: return
    inorder(node.left)
    process(node)        # Visit node IN THE MIDDLE
    inorder(node.right)

Order: a - b / c + d * e

Postorder Traversal

Postorder: Process the node after its children

postorder(node):
    if node is None: return
    postorder(node.left)
    postorder(node.right)
    process(node)        # Visit node LAST

Order: a b c / - d e * +

Traversal Practice

10 12 15 3 9 20 7

Preorder: ______________________

Inorder: ______________________

Postorder: ______________________

The Euler Tour Trick

Walk around the tree, hugging the edges:

  • Preorder: Record node when passing on the left
  • Inorder: Record node when passing below
  • Postorder: Record node when passing on the right
a b c d f Pre In Post

Traversal Applications

Traversal When to Use
Preorder Copy a tree, print directory structure
Inorder Get sorted order from BST, infix expression
Postorder Delete a tree, evaluate expression, compute sizes

Postorder: Deleting a Tree

Why postorder for deletion?

def delete_tree(node):
    if node is None:
        return
    delete_tree(node.left)   # Delete left subtree first
    delete_tree(node.right)  # Delete right subtree first
    del node                 # NOW safe to delete this node

Key insight: Must delete children before parent!

Preorder: Copying a Tree

Why preorder for copying?

def copy_tree(node):
    if node is None:
        return None
    new_node = Node(node.value)      # Create this node FIRST
    new_node.left = copy_tree(node.left)
    new_node.right = copy_tree(node.right)
    return new_node

Key insight: Must create parent before attaching children!

Level Order Traversal

What if we want to visit by level (top to bottom, left to right)?

This is not recursive in the same way!

We need a queue (coming soon…)

Order: 10, 12, 15, 3, 9, 20, 7

Traversal Running Time

For a tree with n nodes:

  • Each node is visited exactly once
  • Each visit does O(1) work

Total time: O(n) for all traversals

Tuesday Summary

  • Preorder: Node, then children (copy, print structure)
  • Inorder: Left, node, right (sorted order in BST)
  • Postorder: Children, then node (delete, evaluate)
  • Level order: Top to bottom, left to right (uses queue)
  • All traversals are O(n)

What’s Next

Wednesday: Binary Search Trees

How do we organize a tree so that finding a value is fast?

The key insight: impose an ordering property on the tree!