Trees and graphs are just nodes connected by edges. A tree has no cycles. Most tree and graph problems reduce to "visit every node in some order."
DFS goes deep before going wide. BFS goes wide before going deep. The three DFS orderings differ only in when you process the current node relative to its children.
Pre-order: visit, left, right.
The DOM is a tree. document.querySelector walks it depth-first, pre-order, left to right. That's why it returns the first match in document order.
Unlike a tree, a graph can have cycles. BFS explores level by level and finds the shortest path in an unweighted graph. A visited set prevents revisiting nodes.
click any node to change target
Start BFS from A. Target: F.
Tree DFS — recursive
function dfs(node: TreeNode | null) { if (!node) return // pre-order: process here dfs(node.left) // in-order: process here dfs(node.right) // post-order: process here }
Tree BFS — iterative with queue
function bfs(root: TreeNode) { const queue = [root] while (queue.length) { const node = queue.shift()! // process node if (node.left) queue.push(node.left) if (node.right) queue.push(node.right) } }
Graph BFS — with visited set
function bfs(graph: number[][], start: number) { const visited = new Set([start]) const queue = [start] while (queue.length) { const node = queue.shift()! // process node for (const nb of graph[node]) if (!visited.has(nb)) { visited.add(nb) queue.push(nb) } } }
O(V + E) time