Hello! Welcome to your first lesson on graphs.
In our course so far, we've journeyed from simple linear data structures like arrays and linked lists to more complex hierarchical ones like trees and heaps. You've seen how a priority queue, built on a heap, can solve sophisticated selection and scheduling problems. We're now ready to generalize even further to graphs, one of the most powerful and versatile data structures in computer science.
Graphs are used to model networks of all kinds: social networks, road maps, the internet, and dependencies between tasks in a project. This lesson will focus on the first crucial step in working with graphs, which is your learning outcome for today: to represent graphs using adjacency matrices and adjacency lists, and to analyze their trade-offs. Getting this right is a foundational architectural decision for any application that relies on graph data.
1. What is a Graph?
At its core, a graph is simply a collection of vertices (or nodes) and edges that connect pairs of vertices. Unlike trees, graphs don't have a root or a strict parent-child hierarchy. Any node can be connected to any other node, and these connections can even form cycles.
To get a quick and practical introduction to graph terminology, please watch the beginning of the following video.
Graphs: Edge List, Adjacency Matrix, Adjacency List, DFS, BFS - DSA Course in Python Lecture 11
This video, from the 'DSA Course in Python' by Greg Hogg, provides a concise overview of what a graph is, the key terminology (vertices, edges), and different types of graphs you'll encounter.
Watch the first 3 minutes and 49 seconds (00:00 - 03:49). Pay attention to the distinction between directed and undirected graphs, and the concept of a cycle.
As you saw in the video, we primarily distinguish between:
- Undirected Graphs: Edges are two-way. If A is connected to B, B is also connected to A (like a Facebook friendship).
- Directed Graphs: Edges are one-way, represented by arrows. If A is connected to B, it doesn't mean B is connected to A (like a Twitter follow).
Now, how do we store this structure in a computer's memory? A drawing is intuitive for us, but a program needs a concrete data structure.
2. Adjacency Matrix
The first common representation is the adjacency matrix. It's a two-dimensional array (a matrix) of size , where is the number of vertices. We typically label our vertices from 0 to .
The rule is simple:
matrix[i][j] = 1if there is an edge from vertexito vertexj.matrix[i][j] = 0if there is no edge.
For a weighted graph, we can store the edge weight instead of 1. For an undirected graph, the matrix will be symmetric (matrix[i][j] == matrix[j][i]).
6.1 Graph Representation in Data Structure(Graph Theory)|Adjacency Matrix and Adjacency List
The following video by Jenny's Lectures CS IT clearly explains how to construct an adjacency matrix from a given graph.
Watch from 01:09 to 05:33. Notice how the presence of an edge between two nodes corresponds to a '1' at the intersection of that row and column in the matrix.

Analysis of Adjacency Matrix
- Space Complexity: It always requires space, regardless of the number of edges. This is because we must allocate memory for every possible pair of vertices.
- Time Complexity of Operations:
- Check for an edge (u, v):
O(1). This is its greatest strength. We just look upmatrix[u][v]. - Add/remove an edge (u, v):
O(1). We just set the value atmatrix[u][v]. - Find all neighbors of a vertex u:
O(V). We must iterate through the entire rowmatrix[u]to see which columns have a1.
- Check for an edge (u, v):
3. Adjacency List
The second major representation is the adjacency list. Instead of a matrix, we use an array (or a hash map) where each entry corresponds to a vertex. Each entry stores a list (like a linked list or dynamic array) of that vertex's neighbors.
adjList[i]contains a list of all verticesjsuch that there is an edge fromitoj.
Given your background, you can think of this as an object or map where keys are vertex IDs and values are arrays of their neighbors.
6.1 Graph Representation in Data Structure(Graph Theory)|Adjacency Matrix and Adjacency List
Let's return to Jenny's video to see how to build an adjacency list for the same graph.
Watch from 05:33 to 08:16. Observe how this representation only stores existing connections, which has important implications for memory usage.
The image above also shows an example of an adjacency list on the right.
Analysis of Adjacency List
- Space Complexity: It requires space, where
Eis the number of edges. We needVspace for the main array/map and then space proportional to the number of edges to store all the neighbor lists. For an undirected graph, each edge appears twice, so it's , which is still . - Time Complexity of Operations:
- Check for an edge (u, v):
O(degree(u)), wheredegree(u)is the number of neighbors ofu. In the worst case, this isO(V). We have to scan the neighbor list ofuto see ifvis in it. - Add an edge (u, v):
O(1). We just appendvto the list atadjList[u]. - Find all neighbors of a vertex u:
O(degree(u)). This is very efficient as we can just retrieve the list directly.
- Check for an edge (u, v):
4. Trade-offs and When to Use Each
The choice between an adjacency matrix and an adjacency list is a classic space-time trade-off that depends on the characteristics of the graph.

The key factor is the density of the graph.
- A dense graph is one where the number of edges
Eis close to the maximum possible, . In this case, the space of an adjacency matrix is acceptable, and its fastO(1)edge lookup is a significant advantage. - A sparse graph is one where the number of edges
Eis much smaller than (e.g., closer toV). Most real-world graphs, like social networks and road systems, are sparse. For these, the space of an adjacency list is far more efficient.
6.1 Graph Representation in Data Structure(Graph Theory)|Adjacency Matrix and Adjacency List
Jenny's lecture concludes with an excellent discussion on this exact trade-off between sparse and dense graphs.
Watch from 08:16 to 11:52. This directly addresses the analysis part of our learning outcome.
To formalize this analysis and see how these representations translate into a more formal API, the following document from Carnegie Mellon University is a great resource.
Lecture 23: Representing Graphs
This lecture note, 'Representing Graphs,' provides a more formal analysis of the complexities. The C code examples illustrate the core logic in a way that is independent of high-level language features, which aligns with our focus on fundamentals.
Read sections 4 ('Adjacency Matrices') and 5 ('Adjacency Lists'). Pay special attention to the summary table at the beginning of section 6, which neatly compares the asymptotic costs.
Because most real-world graphs are sparse, the adjacency list is the most common representation used in practice. Its efficiency in storing and retrieving neighbors is crucial for the graph traversal algorithms we will study next.
Test your understanding!
Consider the following undirected graph:
- Vertices: {0, 1, 2, 3, 4}
- Edges: {(0, 1), (0, 2), (1, 2), (1, 3), (3, 4)}
- How would you represent this graph as an adjacency matrix?
- How would you represent it as an adjacency list?
- Imagine this graph now has 100 vertices but still only 5 edges. Which representation would be more space-efficient and why?
Show answer
-
Adjacency Matrix: A 5x5 matrix.
-
Adjacency List:
0: [1, 2]1: [0, 2, 3]2: [0, 1]3: [1, 4]4: [3]
-
For a graph with 100 vertices and 5 edges, the adjacency list would be far more space-efficient.
- The adjacency matrix would require cells, almost all of which would be zero. Its space is .
- The adjacency list would require space proportional to , which is . This is a dramatic difference. The graph is extremely sparse, making the adjacency list the clear choice.
Conclusion
You've now learned the two primary methods for representing graphs and the critical factors that guide the choice between them. This is a fundamental concept that underpins all graph algorithms.
Key Takeaways:
- Graphs model networks of vertices and edges. They can be directed or undirected.
- An Adjacency Matrix is a matrix with
O(1)edge lookup but requires space, making it suitable for dense graphs. - An Adjacency List is an array of neighbor lists with
O(degree(v))neighbor lookup and requires space, making it ideal for sparse graphs. - The choice of representation is an architectural decision based on graph density and the most frequent operations you need to perform. For most common applications, the adjacency list is preferred.
Preview of the Next Lesson:
Now that we know how to store a graph, we can start exploring it. In the next lesson, we will learn our first major graph traversal algorithm: Depth-First Search (DFS). You will learn how to implement it and see its applications in solving problems like finding a path between two nodes and checking for connectivity.