 : A Graph as a Collection of Lists
: A Graph as a Collection of Lists
Adjacency list representations of graphs take a more vertex-centric
approach.  There are many possible implementations of adjacency lists.
In this section, we present a simple one.  At the end of the section,
we discuss different possibilities.  In an adjacency list representation,
the graph  is represented as an array,
 is represented as an array, 
 , of lists.  The list
, of lists.  The list
![$ \mathtt{adj[i]}$](img5373.png) contains a list of all the vertices adjacent to vertex
 contains a list of all the vertices adjacent to vertex 
 .
That is, it contains every index
.
That is, it contains every index 
 such that
 such that 
 .
.
int n; List *adj;(An example is shown in Figure 12.3.) In this particular implementation, we represent each list in
 as a
subclass of
 as a
subclass of 
 , because we would like constant time access
by position. Other options are also possible.  Specifically, we could
have implemented
, because we would like constant time access
by position. Other options are also possible.  Specifically, we could
have implemented 
 as a
 as a 
 .
.
| ![\includegraphics[scale=0.90909]{figs/graph}](img5381.png)  
 | 
The 
 operation just appends the value
 operation just appends the value 
 to the list
 to the list 
![$ \mathtt{adj[i]}$](img5384.png) :
:
  void addEdge(int i, int j) {
    adj[i].add(j);
  }
This takes constant time.
The 
 operation searches through the list
 operation searches through the list 
![$ \mathtt{adj[i]}$](img5386.png) until it finds
until it finds 
 and then removes it:
 and then removes it:
  void removeEdge(int i, int j) {
    for (int k = 0; k < adj[i].size(); k++) {
      if (adj[i].get(k) == j) {
        adj[i].remove(k);
        return;
      }
    }
  }
This takes 
 time, where
 time, where 
 (the degree
of
 (the degree
of
 ) counts the number of edges in
) counts the number of edges in  that have
 that have 
 as their source.
 as their source.
The 
 operation is similar;  it searches through the list
 operation is similar;  it searches through the list
![$ \mathtt{adj[i]}$](img5394.png) until it finds
 until it finds 
 (and returns true), or reaches the end of
the list (and returns false):
 (and returns true), or reaches the end of
the list (and returns false):
  bool hasEdge(int i, int j) {
    return adj[i].contains(j);
  }
This also takes 
 time.
 time.
The 
 operation is very simple;
it copies the values in
 operation is very simple;
it copies the values in 
![$ \mathtt{adj[i]}$](img5398.png) into the output list:
 into the output list:
  void outEdges(int i, LisT &edges) {
    for (int k = 0; k < adj[i].size(); k++)
      edges.add(adj[i].get(k));
  }
This clearly takes 
 time.
 time.
The 
 operation is much more work.  It scans over every
vertex
 operation is much more work.  It scans over every
vertex  checking if the edge
 checking if the edge 
 exists and, if so, adding
 exists and, if so, adding 
 to the output list:
to the output list:
  void inEdges(int i, LisT &edges) {
    for (int j = 0; j < n; j++)
      if (adj[j].contains(i))  edges.add(j);
  }
This operation is very slow. It scans the adjacency list of every vertex,
so it takes 
 time.
 time.
The following theorem summarizes the performance of the above data structure:
 data structure implements the
 data structure implements the 
 interface.
An
 interface.
An 
 supports the operations
 supports the operations
 in constant time per operation;
 in constant time per operation;
 and
 and 
 in
 in 
 time
    per operation;
 time
    per operation;
  
 in
 in 
 time per operation; and
 time per operation; and
 in
 in 
 time per operation.
 time per operation.
 is
 is  
 .
.As alluded to earlier, there are many different choices to be made when implementing a graph as an adjacency list. Some questions that come up include:
 ?  One could use an array-based list,  a linked-list, or even
  a hashtable.
?  One could use an array-based list,  a linked-list, or even
  a hashtable.
 , that stores,
  for each
, that stores,
  for each 
 , the list of vertices,
, the list of vertices, 
 , such that
, such that 
 ?
  This can greatly reduce the running-time of the
?
  This can greatly reduce the running-time of the 
 operation, but requires slightly more work when adding or removing
  edges.
  operation, but requires slightly more work when adding or removing
  edges.
 in
 in 
![$ \mathtt{adj[i]}$](img5425.png) be linked by
  a reference to the corresponding entry in
 be linked by
  a reference to the corresponding entry in 
![$ \mathtt{inadj[j]}$](img5426.png) ?
?
 would contain lists of edges rather than lists of vertices (integers).
 would contain lists of edges rather than lists of vertices (integers).
opendatastructures.org