Graph Representation
Graph Representation
structure Graph is
objects: a nonempty set of vertices and a set of undirected edges, where each edge is a
pair of vertices.
functions:
for all graph g Graph, v, v j, and V2 Vertices
Graph Create() return an empty graph.
Graph InsertVertex(gr6Zp/z, v) return a graph with v inserted.
V has no incident edges.
Graph InsertEdge(grap/2, Vi, V2) return a graph with a new edge
between Vj and
Graph DeleteVertex(grap/z, v) return a graph in which v and all
edges incident to it are removed,
Graph DeleteEdge(grap/z, vi, V2) return a graph in which the edge
(v ], V2) is removed. Leave
the incident nodes in the graph,
Boolean isEmpty(graph) if (graph == empty graph) return
TRUE else return FALSE.
List Adjacent(gra/7/2, v) return a list of all vertices that
are adjacent to v.
The operations in Structure 6.1 are a basic set in that they allow us to create any
arbitrary graph and do some elementary tests. In the later sections of this chapter we
will see functions that traverse a graph (depth first or breadth first search) and that deter
mine if a graph has special properties (connected, biconnected, planar).
While several representations for graphs are possible, we shall study only the three most
commonly used; adjacency matrices, adjacency lists, and adjacency multilists.
Adjacency Matrix
Let G = (V, E) be a graph with n vertices, m > 1. The adjacency matrix of G is a two-
dimensional n xn array, say adj-mat. If the edge (Vj, Vj) (<Vi, Vj> for a digraph) is in
264 Graphs
0 1 2 3 0 1 2
0 □ 1 1 1 0 0 1 0
1 1 0 1 1 1 1 0 1
2 1 1 0 1 2 0 0 0
3 1 1 1 0
G ®3
1
0 1 2 3 4 5 6 7
0 0 1 1 0 0 0 0 0
1 1 0 0 10 0 0 0
2 1 0 0 1 0 0 0 0
3 0 1 1 0 0 00 0 0
4 0 0000 1 0 0
5 000 □ 1 0 1 0
6 000 0 0 1 0 1
7 000 0 0 0 1 0
From the adjacency matrix, we can determine easily if there is an edge connecting
any two vertices. Determining the degree of a vertex is also a simple task. For an
undirected graph, the degree of any vertex, i, is its row sum:
n-i
For a directed graph, the row sum is the out-degree, while the column sum is the in
degree.
Suppose we wish to answering questions such as: How many edges are there in G?
or. Is G connected?. These require us to examine (potentially) all edges of the graph.
Using adjacency matrices, all algorithms that answer these questions require at least
O(n^) time since we must examine - n entries of the matrix (the n diagonal entries
equal zero and can be excluded; only half as many entries need to be examined in the
case of an undirected graph as in this case the adjacency matrix is symmetric) to deter
mine the edges of the graph. For sparse graphs (i.e., graphs that have a small number of
edges), most of the terms in the adjacency matrix equal zero and we would like to avoid
A
the overhead of examining O(n ) positioins in an adjacency matrix. In fact, we might
The Graph Abstract Data Type 265
expect that the former questions would be answerable in significantly less time, say O(c
+ n) time, where e is the number of edges in G and e « n^/2. For this, we must replace
the adjacency matrix representation with an adjacency list (either sequential or linked)
representation.
Adjacency Lists
In this representation, we replace the n rows of the adjacency matrix with n linked lists,
one for each vertex in G. The node structure for the lists must contain at least vertex and
link fields. For any given list, z, the nodes in the list contain the vertices that are adjacent
from vertex i. Figure 6.8 shows the adjacency lists for G i, G^, and G4. Notice that each
list has a head node, and that the lists are numbered sequentially. This allows us to
quickly access the adjacency list for any vertex.
The C declarations for the adjacency list representation are:
#define MAX—VERTICES 50 *
/
maximum /
*
number of vertices
typedef struct node *node—pointer;
typedef struct node {
int vertex;
struct node *link;
};
node—pointer graph[MAX—VERTICES];
int n = 0; / * vertices currently in use
/
* */
In the case of an undirected graph with n vertices and e edges, this representation
requires n head nodes and 2e list nodes. Each list node has two fields. Often, you can
sequentially pack the nodes on the adjacency lists, thereby eliminating the use of
pointers. In this case, an array node [ ] may be used, node [z ] gives the starting point of
the list for vertex z, 0<z <n and node [zi ] is set to n + 2e + 1. The vertices adjacent
from vertex i are stored in node [z ], • • •, node [z + !]-!, 0 < z < n. Figure 6.9 gives
such a sequential representation for the graph G4 of Figure 6.5.
We can determine the degree of any vertex in an undirected graph by simply
counting the number of nodes in its adjacency list. This also gives us the number of
edges incident on the vertex. This means that if there are n vertices in the graph G, we
can determine the total number of edges in G in O(n + e) time. For a digraph, we can
determine the out-degree of any vertex by counting the number of nodes in its adjacency
list. This means that we also can determine the total number of edges in a digraph in O(zz
+ e) time. Unfortunately, finding the in-degree of a vertex in a digraph is more complex.
We handle this problem and the related problem of finding all vertices adjacent to a ver
tex by maintaining a second set of lists. These lists are called inverse adjacency lists.
As was true of adjacency lists, the inverse adjacency lists contain one list for each ver
tex. However, each list contains a node for each vertex adjacent to the vertex that the
list represents. Figure 6.10 shows the inverse adjacency list for G3.
266 Graphs
0 2 > 3 NULL
1 > 3 NULL
2 1 > 3 NULL
3 1 > 2 NULL
0 1 NULL
1 0 > 2 NULL
2
NULL
0 1 > 2 NULL
1 0 > 3 NULL
2 0 > 3 NULL
3 1 > 2 NULL
4 5 NULL
S 4 > 6 NULL
6 5 7 NULL
7 6 NULL
Changing the node structure of the adjacency lists is a second approach to the
problem of finding the in-degree of vertices. Figure 6.11 shows a simplified version of
the node structure used in the sparse matrix representation of Section 4.7. Each node
now has four fields and represents one edge. Figure 6.12 shows the representation of G3
using the structure of Figure 6.11. We assume that the head nodes are stored sequen
tially.
Before discussing the third representation, we would like to quickly reconsider the
lists displayed in Figure 6.8. For each graph, we arranged the nodes in each of the lists
so that the vertices were in ascending order. This is not necessary, and, in fact, vertices
may appear in any order. Thus, the adjacency lists of Figure 6.13 are just as valid a
The Graph Abstract Data Type 267
0 1 NULL
1 0 NULL
2
1 NULL
tail head column link for head row link for tail
Adjacency Multilists