TutorChase logo
Login
AQA A-Level Computer Science

11.4.6 Comparison of adjacency matrix vs list

Adjacency matrices and adjacency lists are two key ways to represent graphs, each with unique strengths and weaknesses depending on the graph’s structure and how it is used.

Space complexity

Adjacency matrix

An adjacency matrix is a fixed-size, two-dimensional array (2D array) used to represent the connections between vertices in a graph. Each cell in the matrix represents an edge between a pair of vertices.

  • If a graph has n vertices, the matrix is of size n × n.

  • For an unweighted graph, each cell contains either:

    • 1, indicating the presence of an edge between two vertices.

    • 0, indicating the absence of an edge.

  • For a weighted graph, each cell contains the weight value of the edge (such as a distance or cost). If there is no edge, a special value such as 0 or -1 may be used to indicate absence.

This structure means that every possible connection between vertices has a reserved space in memory, whether or not an edge actually exists. This leads to consistent but often inefficient memory use when dealing with graphs that have relatively few edges.

Space usage:
The total memory used is n squared, or O(n²), regardless of the number of edges. Even in cases where the graph has only a few edges (a sparse graph), all the cells in the matrix must still be stored.

Best used for:

Take your grades to the next level!

UPGRADING TO PREMIUM UNLOCKS
AI Tutor
AI-powered study assistant
instant feedback and guidance
Predicted Papers
Examiner-style predicted papers
based on recent exam trends
Practice Questions
All exam practice questions
by topic for each subject
Study Notes
All detailed revision notes
written by expert teachers
Cheat Sheets
Quick revision summaries
perfect for last-minute review
Past Papers
Complete collection
of practice and past exam papers
Email
Password
Confirm Password
Already have an account?

Practice Questions

FAQ

The performance of graph algorithms is heavily influenced by how the graph is represented because the data structure determines how efficiently neighbours can be accessed and how much memory must be traversed. In an adjacency matrix, every vertex pair is stored in a 2D array, so algorithms that require frequent edge existence checks between arbitrary vertices (like Floyd–Warshall for all-pairs shortest paths) perform well due to O(1) access time. However, algorithms like Depth-First Search (DFS) or Breadth-First Search (BFS), which depend on visiting only the actual neighbours of each vertex, perform significantly better on an adjacency list, especially when the graph is sparse. The list skips over non-existent edges, reducing time wasted on scanning irrelevant data. Thus, adjacency matrices are better for algorithms needing rapid universal access to edges, while adjacency lists are better for neighbour-focused traversals. The structure directly impacts time complexity and computational overhead in practice.

Yes, one common method to reduce the space usage of an adjacency matrix in sparse graphs is to use a sparse matrix representation. Instead of storing the entire n × n matrix, only the non-zero entries (i.e. actual edges) are stored, often in a format such as a list of tuples or a dictionary of keys. Each entry typically consists of a pair of vertex indices and the weight or value of the edge. For example, a sparse adjacency matrix could be stored as a list of (row, column, value) triples. Alternatively, compressed sparse row (CSR) or compressed sparse column (CSC) formats can be used in more advanced implementations, especially in computational libraries. These structures reduce memory consumption drastically in sparse graphs by ignoring the zero entries that dominate a traditional matrix. However, they complicate access operations and increase the time needed for edge existence checks, making them suitable only where memory saving is prioritised over speed.

Graph representation significantly affects how well graph operations can be parallelised. With an adjacency matrix, because it is stored in a 2D array with fixed positions, it is easier to access individual edges independently, allowing for efficient parallel processing. For example, multiple threads can examine different rows or columns of the matrix simultaneously without interfering with each other, which is especially beneficial for parallel edge checking or matrix-based algorithms like Floyd–Warshall. In contrast, an adjacency list is built using dynamic data structures like linked lists or dictionaries, which are harder to access in parallel without the risk of race conditions or conflicts. If multiple threads modify or access the same vertex’s list of neighbours concurrently, synchronisation mechanisms must be used, which introduces overhead. This makes adjacency matrices more suitable for high-performance computing scenarios requiring concurrency, while adjacency lists are less scalable in multithreaded environments unless complex locking or thread-safe structures are used.

While adjacency lists are generally more memory-efficient and faster for traversal in sparse graphs, they are not always faster in every operation or context. There are exceptions, particularly when the algorithm frequently checks for the existence of edges between arbitrary pairs of vertices. In an adjacency list, checking whether vertex A is connected to vertex B requires a linear search through A’s adjacency list, which can be slow if A has many neighbours. In contrast, an adjacency matrix provides constant-time O(1) edge existence checks regardless of the graph’s density. Also, in cases where the graph is stored on disk or streamed, the predictable memory layout of an adjacency matrix allows for better cache utilisation and faster loading. Moreover, if the algorithm involves frequent edge deletions and the list is not indexed or sorted, the deletion can be slow. Thus, while adjacency lists are usually preferred for sparse graphs, they are not universally optimal for all sparse-graph operations.

The choice of representation affects how data is stored in memory and, in turn, how efficiently the CPU cache can be utilised. An adjacency matrix stores all values contiguously in memory in a flat 2D array format. This means that accessing neighbouring elements (especially when scanning rows) is cache-friendly — the processor can prefetch blocks of memory and reduce access time. Algorithms that iterate over large sections of the matrix benefit significantly from this memory locality. Conversely, adjacency lists are typically implemented using pointers to dynamically allocated lists or arrays. These are scattered throughout memory, which leads to poor cache performance due to frequent cache misses when jumping between non-contiguous memory locations. While this doesn’t always significantly degrade performance, for algorithms that involve high-volume data access, especially on large graphs, memory access patterns can become a limiting factor. Therefore, in performance-critical applications, adjacency matrices may provide better computational efficiency despite their higher memory usage.

Hire a tutor

Please fill out the form and we'll find a tutor for you.

1/2
Your details
Alternatively contact us via
WhatsApp, Phone Call, or Email