AlgoMaster Logo

Introduction to Graphs

High Priority10 min readUpdated May 30, 2026
Listen to this chapter
Unlock Audio

A graph is a data structure used to model relationships between objects. The objects are called vertices (or nodes), and the connections between them are called edges.

Graphs appear across many real-world systems:

  • Social networks, where users are vertices and friendships are edges.
  • Road maps, where intersections are vertices and roads are edges.
  • Web pages, where each page is a vertex and each hyperlink is a directed edge.
  • Dependency resolvers, where packages are vertices and "depends on" is a directed edge.
  • Recommendation engines, where products and users form a bipartite graph.

Graphs are also one of the most asked topics in coding interviews. Many problems that look unrelated, such as finding the shortest delivery route, scheduling courses with prerequisites, or detecting deadlocks, all reduce to the same underlying graph patterns.

In this chapter, we will cover:

  • What a graph is and the basic terminology
  • Different types of graphs (directed, undirected, weighted, cyclic, and acyclic)
  • How graphs are represented in code (adjacency matrix, adjacency list, edge list)
  • Common graph operations and their time complexities
  • A preview of the algorithms that build on these foundations

What is a Graph?

A graph is formally defined as a pair G = (V, E), where:

  • V is a set of vertices.
  • E is a set of edges, where each edge connects two vertices.

Here is a small graph with 5 vertices and 6 edges:

In this graph, vertex A is connected to B and C. Vertex B is connected to A, C, and D. The line connecting two vertices is the edge.

Everything else in graph theory builds on this structure of vertices and edges.

Graph Terminology

Before we discuss graph types and representations, here are the terms used throughout the chapter and the rest of the course.

TermMeaning
Vertex (Node)A single point in the graph.
EdgeA connection between two vertices.
Adjacent / NeighborTwo vertices are adjacent if an edge connects them.
DegreeThe number of edges touching a vertex.
PathA sequence of vertices connected by edges.
CycleA path that starts and ends at the same vertex without reusing edges.
ConnectedA graph is connected if there is a path between every pair of vertices.
Connected ComponentA maximal connected subgraph in a disconnected graph.
Self-loopAn edge from a vertex to itself.
Parallel edgesTwo or more edges between the same pair of vertices.

In the diagram above, the path A → B → D → E has length 3 (counting edges). The cycle A → B → C → A has length 3. The degree of vertex B is 3 because three edges touch it.

A graph without self-loops or parallel edges is called a simple graph. Simple graphs are the common assumption when none is stated.

Types of Graphs

Graphs come in a few important variations. The choice of variation affects which algorithms apply and what the time complexity looks like.

1. Directed vs Undirected

In an undirected graph, edges have no direction. If A is connected to B, then B is also connected to A. Friendships on Facebook are undirected, because if Alice is friends with Bob, Bob is friends with Alice.

In a directed graph (also called a digraph), each edge has a direction. An edge from A to B does not imply an edge from B to A. Twitter follows are directed, because Alice following Bob does not mean Bob follows Alice.

When you describe an algorithm or write code, the first question to ask is whether the graph is directed. The answer changes how edges are stored and how traversals behave.

2. Weighted vs Unweighted

In an unweighted graph, every edge is treated equally. We only care whether two vertices are connected.

In a weighted graph, each edge carries a number called its weight or cost. Road networks use distance as the weight. Flight networks use price or duration. Capacity networks use bandwidth.

Shortest-path algorithms like Dijkstra and minimum-spanning-tree algorithms like Kruskal and Prim only make sense on weighted graphs.

3. Cyclic vs Acyclic

A graph that contains at least one cycle is cyclic. A graph with no cycles is acyclic.

A directed acyclic graph, or DAG, is one of the most useful structures in computer science. Build systems, course prerequisites, task schedulers, and version-control histories are all DAGs. Topological sorting only works on DAGs.

This graph is a DAG. There is no way to start at any vertex, follow the arrows, and return to where you started.

4. Connected vs Disconnected

A graph is connected if there is a path between every pair of vertices. Otherwise it is disconnected, and it consists of two or more connected components.

This graph has two connected components: {A, B, C} and {D, E}.

For directed graphs, the analogous idea is strongly connected (every vertex can reach every other vertex) versus weakly connected (the underlying undirected graph is connected).

5. Sparse vs Dense

If V is the number of vertices, the maximum possible number of edges in a simple undirected graph is V * (V - 1) / 2. A graph close to this maximum is called dense. A graph with far fewer edges (often closer to V) is called sparse.

This distinction matters for choosing a representation. Social networks are sparse: each user has hundreds of friends, far below V. Road networks are sparse too, because each intersection has only a handful of roads.

Graph Representations

A graph is an abstract idea. To work with it in code, we need a way to store the vertices and edges. The three common representations are the adjacency matrix, the adjacency list, and the edge list.

To make the comparisons concrete, we will use the same small graph throughout this section.

The graph has 5 vertices labeled 0 to 4 and 6 edges. Let us see how each representation stores this graph.

1. Adjacency Matrix

An adjacency matrix is a V x V 2D array where the entry at row i and column j is 1 if there is an edge from vertex i to vertex j, and 0 otherwise.

For our example graph:

Scroll
01234
001100
110110
211001
301001
400110

For an undirected graph, the matrix is symmetric along the diagonal. For a directed graph, it is not.

For a weighted graph, instead of storing 0 or 1, we store the weight at matrix[i][j], and a sentinel value like Infinity or -1 for "no edge".

Here is how to build an adjacency matrix:

Pros

  • Checking whether an edge exists between two vertices takes O(1) time.
  • Simple to implement.
  • Easy to read and debug.

Cons

  • Uses O(V²) space, even when most pairs of vertices are not connected.
  • Iterating over the neighbors of a vertex takes O(V) time, since we must scan an entire row.
  • Adding a new vertex is expensive because the entire matrix must be resized.

The adjacency matrix is a good fit for dense graphs and for problems that frequently ask "is there an edge between u and v?".

2. Adjacency List

An adjacency list stores a list of neighbors for each vertex. It is usually implemented as an array (or hash map) of lists.

For our example graph:

For a weighted graph, each entry stores the neighbor and the edge weight together, often as a pair or a small object.

Here is how to build an adjacency list:

Pros

  • Uses O(V + E) space, which is much smaller than O(V²) for sparse graphs.
  • Iterating over the neighbors of a vertex takes O(degree) time, which is exactly what graph traversals need.

Cons

  • Checking whether a specific edge exists between u and v takes O(degree(u)) time in the worst case.
  • Slightly more code to maintain than a single 2D array.

The adjacency list is the most common representation for interview problems, because most graphs are sparse and most algorithms iterate over neighbors rather than test individual edges.

3. Edge List

An edge list stores the graph as a flat list of edges. Each entry is a pair (u, v) for unweighted graphs, or a triple (u, v, w) for weighted graphs.

For our example graph:

Edge lists use O(E) space. Iterating over all edges is trivial. Looking up neighbors of a specific vertex requires scanning the whole list, which is O(E).

This representation shows up in algorithms that process edges as the primary unit, such as Kruskal's algorithm for the minimum spanning tree, where edges are sorted by weight and processed in order.

Comparison

Scroll
OperationAdjacency MatrixAdjacency ListEdge List
SpaceO(V²)O(V + E)O(E)
Check if edge (u, v) existsO(1)O(degree(u))O(E)
Get all neighbors of uO(V)O(degree(u))O(E)
Add edgeO(1)O(1)O(1)
Remove edgeO(1)O(degree(u))O(E)
Add vertexO(V²) (resize)O(1)O(1)
Best forDense graphs, fast edge lookupsSparse graphs, traversalEdge-centric algorithms

Use an adjacency matrix when the graph is dense or when constant-time edge checks are needed. Use an edge list when the algorithm processes edges as its main operation.

One row not shown above matters most for algorithm analysis: a full graph traversal (BFS/DFS) touches every vertex and every edge once, so the time complexity is O(V + E) with an adjacency list. With an adjacency matrix, it becomes O(V²) because finding neighbors requires scanning a full row for each vertex.

Common Graph Algorithms

Once a graph is in memory, a small set of core algorithms solves a large variety of problems. Here is a preview of what the core algorithms do and when to use them.

Scroll
AlgorithmWhat it doesCommon problems
Breadth-First Search (BFS)Explores level by level from a starting vertex.Shortest path in unweighted graphs, level-order traversal, connected components.
Depth-First Search (DFS)Explores as deep as possible before backtracking.Cycle detection, path finding, topological sort, connected components.
DijkstraFinds the shortest path in a weighted graph with non-negative weights.GPS routing, network latency, cheapest flight.
Bellman-FordFinds the shortest path even with negative edge weights.Currency arbitrage, networks with penalties.
Floyd-WarshallFinds the shortest path between every pair of vertices.All-pairs shortest path on small graphs.
Topological SortLinear ordering of vertices in a DAG.Build systems, course scheduling, task ordering.
Union-Find / DSUTracks connected components efficiently.Kruskal's MST, cycle detection in undirected graphs.
Kruskal / PrimFinds the minimum spanning tree of a weighted graph.Network design, cluster analysis.

Each of these algorithms relies on the representations covered in this chapter. Choosing the wrong representation can turn an O(V + E) algorithm into an O(V²) one, which slows it down significantly on large graphs.

Key Takeaways

  • A graph is defined as G = (V, E), where V is a set of vertices and E is a set of edges that connect pairs of vertices, and it models relationships such as friendships, road maps, and dependencies.
  • Graphs vary along several axes: directed or undirected, weighted or unweighted, cyclic or acyclic, and connected or disconnected. A directed acyclic graph (DAG) supports topological sorting, and weighted graphs are required for shortest-path algorithms like Dijkstra and minimum-spanning-tree algorithms like Kruskal and Prim.
  • The three common representations are the adjacency matrix, the adjacency list, and the edge list, and each makes different operations cheap or expensive.
  • The adjacency matrix uses O(V²) space and checks whether an edge (u, v) exists in O(1), but iterating over the neighbors of a vertex takes O(V). It fits dense graphs and problems that need fast edge lookups.
  • The adjacency list uses O(V + E) space and iterates over a vertex's neighbors in O(degree) time, while checking a specific edge takes O(degree(u)). It fits sparse graphs and traversal-heavy algorithms, which covers most interview problems. The edge list uses O(E) space and suits edge-centric algorithms such as Kruskal's.
  • A full BFS or DFS traversal touches every vertex and edge once, so it runs in O(V + E) with an adjacency list but O(V²) with an adjacency matrix, since the matrix requires scanning a full row to find each vertex's neighbors.

Quiz

Introduction to Graphs Quiz

10 quizzes