What is a tree?
left and right.This section has a step-by-step animation in the interactive lesson.
Quick check
In the org chart, which nodes are the LEAVES?
Answer it in the interactive lesson to keep your progress.
The core operations
{ val, left, right } — its value plus up to two children, where each child is either another node or null (no child there). You hold a reference to the root; everything else is reached by stepping through children, exactly like following .next in a linked list, except now each step offers two directions.- reach a node — step child by child from the root:
root.left,root.right.left, … - traverse — visit every node. Because each subtree is itself a tree, traversal is a natural recursion (the previous lesson!): do something with the node, then recurse into
leftandright. - measure — count nodes, find the height, sum the values: each is a tiny recursion that combines answers from the two children.
buildTree and treeToArray are helpers this course provides in every tree exercise: they convert between the level-order array shorthand and real linked nodes — the representation section below shows what buildTree does by hand.)Building a Tree in JavaScript
const sample = buildTree([8, 3, 10, 1, 6, null, 14]);
console.log(sample.val); // 8 (the root)
console.log(sample.left.val, sample.right.val); // 3 10
console.log(treeToArray(sample)); // [8, 3, 10, 1, 6, null, 14]Quick check
In { val, left, right }, what does it mean when a node's left is null?
Answer it in the interactive lesson to keep your progress.
Your first tree problem: in-order traversal
5 and children 3 (left) and 8 (right), in-order visits 3, 5, 8.The steps
- If the node is
null, stop — nothing to visit (the base case). - Recurse into the left child first.
- Record this node's value.
- Recurse into the right child.
Trace it on the example tree
| step | where the walk is | recorded so far |
|---|---|---|
| 1 | dive left from 8 → 3 → 1 (1 has no left) | [1] |
| 2 | back up to 3, record it, then its right child 6 | [1, 3, 6] |
| 3 | 3's subtree done — record the root 8 | [1, 3, 6, 8] |
| 4 | into the right side: 10 (no left), then 14 | [1, 3, 6, 8, 10, 14] |
In-Order Traversal in JavaScript
const tree = buildTree([8, 3, 10, 1, 6, null, 14]);
function inorderVals(node, acc) {
if (!node) return acc; // base case: nothing to do
inorderVals(node.left, acc); // smaller values first
acc.push(node.val); // then this node
inorderVals(node.right, acc);// then larger values
return acc;
}
console.log(inorderVals(tree, [])); // [1, 3, 6, 8, 10, 14]Quick check
In-order traversal of a binary SEARCH tree visits values…
Answer it in the interactive lesson to keep your progress.
Where it breaks (and how not to get burned)
- An unbalanced tree is just a list. Insert already-sorted values into a plain BST and it degrades into a straight line — search back to
O(n). Real systems use self-balancing trees (AVL, red-black) to prevent this. - Missing the null base case. Recursing into a
nullchild and reading.valthrows. Every tree recursion needs anif (node === null) returnguard. - Confusing traversals. The four traversals differ only in WHEN each node is recorded relative to its children — but that tiny difference decides what the output is good for:
| traversal | order at each node | typical use |
|---|---|---|
| in-order | left → node → right | sorted output on a BST (this lesson) |
| pre-order | node → left → right | copying/serializing a tree — the root must come first |
| post-order | left → right → node | deleting or measuring — children must finish before the parent |
| level-order | whole levels, top to bottom | anything "by level" (the next section, with a queue) |
record line moves.Quick check
Tree recursion always starts with `if (!node) return …` because…
Answer it in the interactive lesson to keep your progress.
Take it further — level-order (breadth-first)
Level-Order Traversal in JavaScript
function levelOrder(root) {
const out = [];
const queue = [root];
while (queue.length) {
const node = queue.shift(); // take the front
if (!node) continue;
out.push(node.val);
queue.push(node.left, node.right); // children join the back
}
return out;
}
console.log(levelOrder(buildTree([8, 3, 10, 1, 6, null, 14]))); // [8, 3, 10, 1, 6, 14]Quick check
Level-order on root 5, children 3 and 8, and 3 has a child 1. Predict the visit order.
Answer it in the interactive lesson to keep your progress.
How fast is it? (complexity)
n, the node count, and h, the tree's height (the longest root-to-leaf path). A balanced tree — branches of roughly equal depth — has height about log n; a lopsided one can have height n:| Operation | Balanced tree | Skewed tree (worst) |
|---|---|---|
| traverse every node | O(n) | O(n) |
| walk root → leaf | O(log n) | O(n) — the tree is a list |
| recursion stack while traversing | O(log n) | O(n) |
O(n)) — no shape changes that. What the shape does change is the cost of any operation that walks one root-to-leaf path, which is exactly what the BST lesson exploits.- A tree stores hierarchy: root at the top, children below, leaves at the tips,
nullwhere a branch ends. - Tree work is recursion; every path bottoms out at a
nullbase case. - Height decides path costs: balanced ≈
log n, skewed ≈n.