WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Coding Interview Essentials · Data Structures · question 7 of 120

Describe how you would implement a graph data structure.?

📕 Buy this interview preparation book: 120 Coding Interview Essentials questions & answers — PDF + EPUB for $5

A graph data structure consists of a collection of nodes (also called vertices) and a collection of edges. Each edge connects a pair of nodes. Graphs may be either directed (edges have a direction) or undirected.

There are different ways you can implement a graph in code, each with their relative strengths and weaknesses. The two most common implementations are an adjacency matrix and an adjacency list. I will describe how to implement both of these.

#### 1. Adjacency Matrix

In an adjacency matrix implementation, the graph is represented by a matrix (usually a 2D array in code) where the cell at the i-th row and j-th column (denoted as M[i][j]) is true (or 1) if there’s an edge from node i to node j, or false (or 0) otherwise. This works for both directed and undirected graphs. If the graph is undirected, the matrix will be symmetric around the diagonal.

class Graph:
    def __init__(self, num_of_vertices):
        self.num_of_vertices = num_of_vertices
        self.adjMatrix = [[0]*num_of_vertices for i in range(num_of_vertices)]

The adjacency matrix representation is suitable when the graph is dense, i.e., the number of edges is close to the maximum possible number of edges. Its time complexity for checking the existence of an edge is constant, i.e., O(1).

However, it’s poor in terms of space complexity, i.e., O(V2), where V is the number of vertices.

#### 2. Adjacency List

In an adjacency list implementation, the graph is represented by a map from nodes to lists of nodes (usually array of lists or linked lists):

class Graph:
    def __init__(self, num_of_vertices):
        self.num_of_vertices = num_of_vertices
        self.adjList = [[] for i in range(num_of_vertices)]

    def add_edge(self, src, dest):
        self.adjList[src].append(dest)
        self.adjList[dest].append(src)  # For undirected graph

Each node i is associated with a list that contains the nodes to which i has an edge. The adjacency list representation is suitable when the graph is sparse, i.e., the number of edges is far less than the maximum possible number of edges.

Its time complexity for checking the existence of an edge is linear in the degree of the node, i.e., O(d), where d is the degree of a node. However, it’s efficient in terms of space complexity, i.e., O(V + E), where V is the number of vertices and E is the number of edges.

For example, if a graph data structure has five vertices and four edges in an undirected graph:

0 -- 1
|    |
3 -- 2 -- 4

The adjacency matrix and adjacency list representations will be:

For adjacency matrix:

  0 1 2 3 4
0[0 1 0 1 0]
1[1 0 1 0 0]
2[0 1 0 1 1]
3[1 0 1 0 0]
4[0 0 1 0 0]

For adjacency list:

0: 1, 3
1: 0, 2
2: 1, 3, 4
3: 0, 2
4: 2

In summary, choose the type of representation based on the expected graph’s density to achieve the best trade-off between time and space complexities.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Coding Interview Essentials interview — then scores it.
📞 Practice Coding Interview Essentials — free 15 min
📕 Buy this interview preparation book: 120 Coding Interview Essentials questions & answers — PDF + EPUB for $5

All 120 Coding Interview Essentials questions · All topics