import java.util.ArrayList; import java.util.Iterator; /* An instance of this graph represents a directed graph whose vertices ** are identified by the natural numbers 0..N-1 (for some N). */ public class Digraph { // instance variables // ------------------ protected ArrayList[] edges; // edges[i] is an ArrayList of the // vertices to which i has an edge, // with their IDs in increasing order // constructor // ----------- /* Initializes this digraph to be one having the specified number of ** vertices (numbered starting at zero) and no edges. */ public Digraph(int numVertices) { //edges = new ArrayList[numVertices]; //Note: The Java compiler does not allow the line above but does // allow the one below. Arrays and generics do not mix well. //edges = new ArrayList[numVertices]; edges = (ArrayList[]) (new ArrayList[numVertices]); for (int i=0; i != numVertices; i++) { edges[i] = new ArrayList(); } } // observers // --------- /* Prints a description of the graph. */ public void printDescription() { final int N = numVertices(); System.out.println("Graph has " + N + " vertices."); for (int i=0; i != N; i++) { System.out.println("Edges from vertex " + i + " go to " + edges[i]); } } /* Returns the number of vertices in this digraph. */ public int numVertices() { return edges.length; } /* Reports whether or not there is an edge from vertex u to vertex v. */ public boolean hasEdge(int u, int v) { return edges[u].indexOf(v) != -1; } /* Returns an array containing the IDs of the vertices to which ** the specified vertex (u) has an edge. That is, the array ** that is returned contains v iff (u,v) is an edge in this digraph. */ public Integer[] neighbors(int u) { ArrayList edgesFromU = edges[u]; Integer[] result = new Integer[edgesFromU.size()]; for (int i=0; i != result.length; i++) { result[i] = (Integer)(edgesFromU.get(i)); } return result; //RWM: Class cast exception! //return (Integer[])(edges[u].toArray()); } /* Returns an Iterator that can iterate through the ID's of the vertices ** to which the specified vertex has an edge. That is, the returned ** iterator will contain v among the elements yielded by its next() ** method iff (u,v) is an edge in this digraph. */ public Iterator neighborIterator(int u) { return edges[u].iterator(); } // mutators // -------- /* Inserts the edge (u,v) into this graph, unless it is already there. */ public void addEdge(int u, int v) { ArrayList neighborsOfU = edges[u]; final int NUM_NEIGHBORS = neighborsOfU.size(); int i = 0; // Search for v in u's neighbor list to determine where in that list // v should be inserted, assuming that it's not already there. while (i != NUM_NEIGHBORS && neighborsOfU.get(i) < v) { i = i+1; } if (i == NUM_NEIGHBORS || neighborsOfU.get(i) != v) { // v belongs at position i in u's neighbor list neighborsOfU.add(i, v); } else { // v is already in u's neighbor list, so do nothing } } /* Removes the edge (u,v) from this graph, unless it is not already there. */ public void removeEdge(int u, int v) { ArrayList neighborsOfU = edges[u]; int k = neighborsOfU.indexOf(v); if (k != -1) { neighborsOfU.remove(k); } } }