Close
Register
Close Window

Show Source |    | About   «  14.1. Graphs Chapter Introduction   ::   Contents   ::   14.3. Graph Traversals  »

14.2. Graph Implementations

We next turn to the problem of implementing a general-purpose graph class. There are two traditional approaches to representing graphs: The adjacency matrix and the adjacency list. In this module we will show actual implementations for each approach. We will begin with an interface defining an ADT for graphs that a given implementation must meet.

This ADT assumes that the number of vertices is fixed when the graph is created, but that edges can be added and removed. The init method sets (or resets) the number of nodes in the graph, and creates necessary space for the adjacency matrix or adjacency list.

Vertices are defined by an integer index value. In other words, there is a Vertex 0, Vertex 1, and so on through Vertex \(n-1\). We can assume that the graph’s client application stores any additional information of interest about a given vertex elsewhere, such as a name or application-dependent value. Note that in a language like Java or C++, this ADT would not be implemented using a language feature like a generic or template, because it is the Graph class users’ responsibility to maintain information related to the vertices themselves. The Graph class need have no knowledge of the type or content of the information associated with a vertex, only the index number for that vertex.

Interface Graph has methods to return the number of vertices and edges (methods n and e, respectively). Function weight returns the weight of a given edge, with that edge identified by its two incident vertices. For example, calling weight(0, 4) on the graph of Figure 14.1.1 (c) would return 4. If no such edge exists, the weight is defined to be 0. So calling weight(0, 2) on the graph of Figure 14.1.1 (c) would return 0.

Functions addEdge and removeEdge add an edge (setting its weight) and removes an edge from the graph, respectively. Again, an edge is identified by its two incident vertices. addEdge does not permit the user to set the weight to be 0, because this value is used to indicate a non-existent edge, nor are negative edge weights permitted. Functions getValue and setValue get and set, respectively, a requested value for Vertex \(v\). In our example applications the most frequent use of these methods will be to indicate whether a given node has previously been visited in the process of the algorithm

Nearly every graph algorithm presented in this chapter will require visits to all neighbors of a given vertex. The neighbors method returns an array containing the indices for the neighboring vertices, in ascending order. The following lines appear in many graph algorithms.

First, an array is generated that contains the indices of the nodes that can be directly reached from node v. The for loop then iterates through this neighbor array to execute some function on each.

It is reasonably straightforward to implement our graph ADT using either the adjacency list or adjacency matrix. The sample implementations presented here do not address the issue of how the graph is actually created. The user of these implementations must add functionality for this purpose, perhaps reading the graph description from a file. The graph can be built up by using the addEdge function provided by the ADT.

Here is an implementation for the adjacency matrix.

Array nodeValues stores the information manipulated by the setValue and getValue functions. The edge matrix is implemented as an integer array of size \(n \times n\) for a graph of \(n\) vertices. Position \((i, j)\) in the matrix stores the weight for edge \((i, j)\) if it exists. A weight of zero for edge \((i, j)\) is used to indicate that no edge connects Vertices \(i\) and \(j\).

Given a vertex \(v\), the neighbors method scans through row v of the matix to locate the positions of the various neighbors. If no edge is incident on \(v\), then returned neighbor array will have length 0. Functions addEdge and removeEdge adjust the appropriate value in the array. Function weight returns the value stored in the appropriate position in the array.

Here is an implementation of the adjacency list representation for graphs. Its main data structure is an array of linked lists, one linked list for each vertex. These linked lists store objects of type Edge, which merely stores the index for the vertex pointed to by the edge, along with the weight of the edge.

Implementation for GraphL member functions is straightforward in principle, with the key functions being addEdge, removeEdge, and weight. They simply start at the beginning of the adjacency list and move along it until the desired vertex has been found. Private method find is a utility for finding the last edge preceding the one that holds vertex \(v\) if that exists.

   «  14.1. Graphs Chapter Introduction   ::   Contents   ::   14.3. Graph Traversals  »

nsf
Close Window