Sparround

Tree basics and traversal

A tree is a hierarchical structure without cycles: every node has one parent (except the root) and any number of children.

The terminology gets asked directly in interviews, so know it precisely:

  • Root — the single node with no parent.
  • Leaf — a node with no children.
  • Parent / child / sibling — parent, child, and children of the same parent.
  • Depth — the length of the path from the root down to that node. The root has depth 0.
  • Height — the length of the path from a node down to its furthest leaf. A tree's height is the root's height. An empty tree's height is usually taken as −1.
  • Degree — the number of a node's children.
  • Subtree — any node together with all of its descendants.

Confusing depth and height is the most common mistake: depth is measured top-down, height bottom-up.

A binary tree has at most two children per node (left, right). An n-ary tree keeps children in a list (children: Node[]) — the DOM, a file system, and a UI widget tree all look like this.

Traversal means visiting every node exactly once. There are two families.

DFS (depth-first) — walk one branch to the end, then backtrack. Three variants, depending on when the node itself is "processed":

  • Preorder (node → left → right): copying a tree, serialisation, printing a hierarchy top-down.
  • Inorder (left → node → right): on a BST this yields the sorted sequence — the single most-asked fact here.
  • Postorder (left → right → node): children are processed before the parent; deletion, computing folder sizes, evaluating an expression tree.

BFS (breadth-first, level-order) — visits the tree level by level. It needs a queue. Questions about "shortest path", "group by level", or "the nearest matching node" are BFS work.

TraversalOrderStructureMemoryTypical use
Preordernode → left → rightStack (or recursion)O(h)Copying, serialisation
Inorderleft → node → rightStack (or recursion)O(h)Sorted output from a BST
Postorderleft → right → nodeStack (or recursion)O(h)Deletion, aggregation (folder size)
BFS / level-orderLevel by levelQueueO(w) — the widest levelShortest path, grouping by level

Complexity. Every traversal visits each node exactly once, so time is always O(n). The difference is in memory:

  • DFS memory is the depth of the call stack: O(h), where h is the tree height. In a balanced tree h ≈ log n, so O(log n); in a degenerate (chain-like) tree h = n and memory becomes O(n).
  • BFS memory is the size of the widest level: O(w). In a complete binary tree the last level holds roughly half of all nodes, so O(n).

The practical consequence: BFS is cheaper on a narrow, deep tree; DFS is cheaper on a wide, shallow one.

Recursive vs iterative. Recursion is short and readable, but the call stack is bounded — on a very deep tree (say a 100k-node chain) you get RangeError: Maximum call stack size exceeded or a StackOverflowError. The iterative version does the same work with its own stack array and never hits that limit: heap memory is far larger than the call stack. In production code walking a tree of uncontrolled depth (user data, JSON, the DOM), the iterative version is safer.

Interview tip. The most frequent question here: "How do you choose between DFS and BFS?" The weak answer is "DFS is recursive, BFS uses a queue" — that describes the mechanics, not the choice.

A strong answer reasons from the requirement: "If I need the shortest path or the nearest matching node, BFS, because it visits levels in order and the first hit is the closest. If I need to walk all paths, build a hierarchy, or aggregate over subtrees, DFS. On memory, BFS is cheaper on a deep narrow tree and DFS on a wide one."

A second classic: "What does inorder traversal give you?" — the sorted sequence on a BST. Not knowing this shows up immediately in BST questions.

The most commonly missed detail: mentioning recursion's stack limit. "I would write it recursively, but if the tree depth is not controlled I would go iterative to avoid a stack overflow" — that one sentence separates you from a junior.