package graph; import java.util.*; /** * Represents a Graph G = (V,E), where V is a set of vertices and E is a set * of edges between the vertices. */ /* * TERMS OF USE: This Graph class for vertices of type T is essentially undocumented. * You are free to use and modify this for your CSE132 lab, but you must * add the required documentation for all methods. */ public class Graph implements Iterable { Map> out = new HashMap>(); Map> in = new HashMap>(); /* * Representation Invariant: * For all v1 and v2, out.get(v1).contains(v2) iff in.get(v2).contains(v1). * * Abstraction Function for Graph g: * AF(g) = (V,E), where * V = { v : g.out.containsKey(v) } and * E = { (v1,v2) : g.out.get(v1).contains(v2) }. */ public void addVertex(T v) { if (!containsVertex(v)) { out.put(v, new HashSet()); in.put(v, new HashSet()); } } public boolean containsVertex(T v) { return out.containsKey(v); } public void removeVertex(T v) throws NoSuchElementException { for (T neighbor : out.get(v)) in.get(neighbor).remove(v); for (T neighbor : in.get(v)) out.get(neighbor).remove(v); out.remove(v); in.remove(v); } public void addEdge(T from, T to) { addVertex(from); addVertex(to); out.get(from).add(to); in.get(to).add(from); } public boolean containsEdge(T from, T to) throws NoSuchElementException { return out.get(from).contains(to); } public void removeEdge(T from, T to) throws NoSuchElementException { out.get(from).remove(to); in.get(to).remove(from); } public void visitAll(Visitor agent) { for (T x : this) agent.visit(x); } public void visitDepthFirst(Visitor agent) throws CycleException { HashSet visited = new HashSet(); LinkedList path = new LinkedList(); for (T vertex : this) visitDepthFirstHelper(vertex, agent, visited, path); } private void visitDepthFirstHelper(T vertex, Visitor agent, Set visited, LinkedList path) throws CycleException { if (!visited.contains(vertex)) { if (path.contains(vertex)) throw new CycleException(path); path.addLast(vertex); if (out.get(vertex) != null) for (T neighbor : out.get(vertex)) visitDepthFirstHelper(neighbor, agent, visited, path); visited.add(vertex); agent.visit(vertex); path.removeLast(); } } public NonMutatingIterator edgesFrom(T vertex) throws NoSuchElementException { return new NonMutatingIterator(out.get(vertex).iterator()); } public NonMutatingIterator edgesTo(T vertex) throws NoSuchElementException { return new NonMutatingIterator(in.get(vertex).iterator()); } public NonMutatingIterator iterator() { return new NonMutatingIterator(out.keySet().iterator()); } static class CycleException extends java.lang.Exception { List cycle; public CycleException(List cycle) { super(cycle.toString()); } public List getCycle() { return cycle; } } }