// Graph, implemented with an adjacency matrix // (c) 1998 McGraw-Hill package structure; abstract public class GraphMatrix implements Graph { protected int size; // allocation size for graph protected Edge data[][]; // matrix - array of arrays protected Dictionary dict; // translates labels->vertices protected List freeList; // available indices in matrix protected boolean directed; // graph is directed protected GraphMatrix(int size, boolean dir) // pre: size > 0 // post: constructs an empty graph that may be expanded to // at most size vertices. Graph is directed if dir true // and undirected otherwise { this.size = size; // set maximum size directed = dir; // fix direction of edges // the following constructs a size x size matrix data = new Edge[size][size]; // label to index translation table dict = new Hashtable(size); // put all indices in the free list freeList = new SinglyLinkedList(); for (int row = size-1; row >= 0; row--) freeList.add(new Integer(row)); } public void add(Object label) // pre: label is a non-null label for vertex // post: a vertex with label is added to graph. // if vertex with label is already in graph, no action. { // if there already, do nothing. if (dict.containsKey(label)) return; Assert.pre(!freeList.isEmpty(), "Matrix not full"); // allocate a free row and column int row = ((Integer) freeList.removeFromHead()).intValue(); // add vertex to dictionary dict.put(label, new GraphMatrixVertex(label, row)); } abstract public void addEdge(Object v1, Object v2, Object label); // pre: v1 and v2 are labels of existing vertices, v1 & v2 // post: an edge (possibly directed) is inserted between v1 and v2 // if edge is new, it is labeled with label (can be null) public Object remove(Object label) // pre: label is non-null vertex label // post: vertex with "equals" label is removed, if found { // find and extract vertex GraphMatrixVertex vert; vert = (GraphMatrixVertex)dict.remove(label); if (vert == null) return null; // remove vertex from matrix int index = vert.index(); // clear row and column entries for (int row=0; row=0; row--) { Edge e = data[vert.index()][row]; if (e != null) { if (e.here().equals(vert.label())) list.add(e.there()); else list.add(e.here()); } } return list.elements(); } abstract public Iterator edges(); // post: returns iterator across all edges of graph (returns Edges) public void clear() // post: removes vertices and edges from graph { dict.clear(); for (int row=0; row=0; row--) freeList.add(new Integer(row)); } public boolean isEmpty() // post: returns true iff graph is empty { return dict.isEmpty(); } public boolean isDirected() // post: returns true iff graph is directed { return directed; } } class GraphMatrixVertex extends Vertex { protected int index; public GraphMatrixVertex(Object label, int idx) // post: constructs a new augmented vertex { super(label); index = idx; } public int index() // post: returns index associated with vertex { return index; } public String toString() // post: returns string representation of vertex { return ""; } }