Skip to content
PrepMint

Data Structures & Algorithms

Trees & Graphs

Tree and graph traversal fundamentals

3 questions
Medium· 3

Last reviewed

Recommended

Trees & Graphs — Timed Test (3 questions)

TimedMedium3 questions · 3 min
Start test

No account needed. Answers and explanations arrive when you submit.

What this topic tests

The mix every Trees & Graphs set is built to, and the questions published against it so far. Nothing here is hidden before you start.

Trees & Graphs — target difficulty mix and published question count per level
LevelTarget sharePublished
Easy40%0
Medium40%3
Hard20%0
Total3

Trees & Graphs — the theory

Trees and graphs are data structures used to represent hierarchical or networked relationships between elements, and traversing them correctly is a common focus in technical interviews.

Trees. A tree is a hierarchical structure with a single root node, where each node can have child nodes, and there are no cycles (no path leads back to an ancestor). Binary trees, where each node has at most two children, are a particularly common special case, with binary search trees adding an ordering property that makes searching efficient.

Tree traversal. Common ways of visiting every node in a tree include depth-first traversal (going as deep as possible along each branch before backtracking, with common variants like pre-order, in-order, and post-order depending on when a node is processed relative to its children) and breadth-first traversal (visiting all nodes at the current depth level before moving to the next level).

Graphs. A graph is a more general structure than a tree, consisting of nodes (vertices) connected by edges, without the restriction against cycles that trees have. Graphs can be directed (edges have a specific direction) or undirected, and weighted (edges have an associated cost or value) or unweighted.

Graph traversal. Similar to trees, graphs are commonly traversed using depth-first search or breadth-first search, adapted to handle the possibility of cycles (typically by tracking which nodes have already been visited, to avoid infinite loops).

Common applications. Trees are commonly used to represent hierarchical data (like a file system or an organizational structure), while graphs are commonly used to represent networks (like social connections, road networks, or dependency relationships between tasks).

Binary search trees and the balance problem. A binary search tree maintains the invariant that everything in a node's left subtree is smaller than the node and everything in its right subtree is larger, which is what allows search, insertion, and deletion to follow a single path from the root rather than examining every node. That path is short only when the tree is balanced: inserting already-sorted values produces a tree that is effectively a linked list, and operations degrade from O(log n) to O(n). Self-balancing variants exist precisely to guarantee the tree stays shallow, and this degradation is the reason most standard library ordered containers use one.

In-order traversal as a sorting property. The three depth-first orders are not interchangeable, and choosing the right one is often the whole solution. In-order traversal of a binary search tree visits values in sorted order, which makes it the natural way to validate a BST, find the kth smallest element, or emit contents in order. Pre-order suits copying or serializing a structure, since a node is handled before its children exist. Post-order suits deletion and any computation where a node's result depends on results from its children, such as computing height or aggregating subtree totals.

Recursion, explicit stacks, and depth. Depth-first traversal is naturally recursive, and the recursive form is almost always clearer. The cost is stack space proportional to the depth of the structure, so a deep or degenerate tree can exhaust the call stack on large inputs. Converting to an iterative traversal with an explicit stack removes that limit at the cost of readability. Breadth-first traversal is the mirror image: it uses an explicit queue rather than recursion, and its memory cost is proportional to the widest level rather than the depth.

Representing a graph. The two standard representations are an adjacency list, which stores each vertex's neighbors, and an adjacency matrix, which stores a value for every possible pair. Adjacency lists use space proportional to the number of vertices plus edges and make iterating a vertex's neighbors efficient, which suits the sparse graphs that dominate real applications. Adjacency matrices use space proportional to the square of the vertex count but answer "is there an edge between these two?" in constant time, which suits dense graphs. Choosing the wrong representation can turn a linear algorithm quadratic, so it is a decision worth making deliberately.

BFS, DFS, and shortest paths. On an unweighted graph, breadth-first search finds the shortest path in terms of edge count, because it reaches every vertex at the earliest possible level — a property depth-first search does not have, since it can arrive at a vertex by a long path first. Depth-first search is the natural fit for questions about reachability, connected components, cycle detection, and topological ordering of a directed acyclic graph. When edges carry weights, neither suffices unmodified, and weighted shortest-path algorithms such as Dijkstra's are the appropriate tool. Both traversals run in O(V + E) time on an adjacency list.

Tracking visited nodes. The single most common graph bug is omitting or mishandling the visited set, which on a cyclic graph produces infinite recursion rather than a wrong answer. Marking a vertex as visited when it is first enqueued or first entered — rather than when it is finished — also prevents the same vertex being queued repeatedly, which otherwise degrades performance badly on dense graphs. Trees do not need this bookkeeping precisely because they are acyclic, which is why tree code adapted to graphs without adding it fails immediately.

How to approach these problems. Establish the structure first: is it a tree or a general graph, directed or undirected, weighted or unweighted, connected or possibly not. Those four answers determine the algorithm almost entirely. Then pick the traversal that matches the question — BFS for shortest hops or level-by-level work, DFS for exhaustive exploration and structural properties — and confirm the base cases: an empty structure, a single node, and a disconnected component that a traversal from one starting vertex would never reach.

Understanding trees and graphs — their structure, common traversal techniques, and the distinction between them — provides the foundation for a large category of algorithmic problems involving hierarchical or networked data.

Sample questions

Three questions from this topic, with the answer and the reasoning shown.

Q1MediumWhat distinguishes a tree from a general graph?
  • A tree is hierarchical with a single root and no cyclesCorrect
  • A tree must always contain exactly one node
  • A tree always has more edges than a graph
  • Trees and graphs are identical in every respect

Explanation

In graph terms a tree is a connected, undirected, acyclic graph, rooted and ordered unless stated otherwise. Connected means a path exists between every pair of vertices; acyclic means no path returns to its own start; together they force exactly one path between any two nodes and exactly n minus one edges across n nodes. A general graph promises none of this. It may be disconnected, it may loop, and two vertices may be joined by many distinct paths.

The difference shows up the moment code walks the structure. A recursive walk over a tree needs no visited set, because there is no way back to a node already left; run that same code over a graph and one cycle turns it into an endless descent. Every tree is a graph, and the reverse does not hold.

Two of the wrong answers invert real facts. A tree is not confined to a single node; it holds any number and may even be empty. And a tree does not carry more edges than a graph, since n minus one is the fewest edges a connected structure can have.

Open this question on its own page

Q2MediumWhat is the key difference between depth-first and breadth-first traversal?
  • Depth-first goes as deep as possible before backtracking; breadth-first visits all nodes at the current level firstCorrect
  • They are exactly the same algorithm with different names
  • Breadth-first can only be used on trees, never on graphs
  • Depth-first cannot be used on any tree structure

Explanation

Both algorithms pull a vertex from a pending set, visit it, and push its undiscovered neighbours back in. The only thing separating them is which pending vertex comes out next, and that is decided by the container. Depth-first takes the most recently discovered one, through an explicit stack or through recursion, so it drives to the end of one branch and backtracks only when it runs out of edges. Breadth-first takes the oldest pending vertex from a queue, so every vertex at distance k from the start is visited before any vertex at distance k plus one.

That single ordering choice is where the practical differences come from. On an unweighted graph, breadth-first finds a path with the fewest edges and depth-first offers no such guarantee. Memory trades the other way: depth-first holds one root-to-current path, breadth-first holds an entire level, which on a wide graph is far larger. Neither is limited by structure. Preorder, in-order and postorder tree walks are all depth-first searches, and breadth-first over a tree is exactly level-order traversal.

Open this question on its own page

Q3MediumWhy is tracking visited nodes important when traversing a graph?
  • To avoid infinite loops caused by cycles in the graphCorrect
  • It is never necessary for any graph traversal
  • To permanently delete nodes from the graph
  • To convert the graph into a tree automatically

Explanation

A graph may contain a cycle: a path that starts and ends at the same vertex. Walk along such a path keeping no record of where the traversal has already been, and it returns to that vertex and sets off around the loop again. Nothing inside the algorithm stops it. A breadth-first queue keeps receiving work it has already done, and a depth-first recursion runs until the call stack overflows. Marking is what makes the traversal terminate at all, which is why the standard formulation of depth-first search marks every vertex in the order it is discovered and finished.

The mark sits beside the graph, not in it: a hash set of identifiers, an array of flags, one colour per vertex. Nothing is deleted, so a traversal never removes nodes from the structure it is reading. Nor does it rewrite the graph into a tree, although the discovery edges do form a spanning forest while every back edge and cross edge stays where it was. Skipping the marking is safe only on input already known to be acyclic, and that is exactly the assumption a graph does not give you.

Open this question on its own page

More Data Structures & Algorithms topics

All of Data Structures & Algorithms