import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.LinkedHashSet; import java.util.Set; public class UndirectedGraph { private ArrayList vertices; private List verticesView; private HashMap> neighbors; private HashMap> neighborsView; private int edgeCount; public UndirectedGraph() { vertices = new ArrayList(); verticesView = Collections.unmodifiableList(vertices); neighbors = new HashMap>(); neighborsView = new HashMap>(); } public int getVertexCount() { return vertices.size(); } public V getVertex(int index) { return vertices.get(index); } public List getVertices() { return verticesView; } public void addVertex(V vid) { vertices.add(vid); LinkedHashSet vneighb = new LinkedHashSet(); neighbors.put(vid, vneighb); neighborsView.put(vid, Collections.unmodifiableSet(vneighb)); } public void removeVertex(V vid) { if(vertices.remove(vid)) { LinkedHashSet vneighb = neighbors.remove(vid); for(V uid : vneighb) { LinkedHashSet uneighb = neighbors.get(uid); uneighb.remove(vid); --edgeCount; } neighborsView.remove(vid); } } public int getEdgeCount() { return edgeCount; } public int getNeighborCount(V vid) { LinkedHashSet vneighb = neighbors.get(vid); return vneighb == null ? 0 : vneighb.size(); } public Set getNeighbors(V vid) { return neighborsView.get(vid); } public boolean isConnected(V uid, V vid) { LinkedHashSet uneighb = neighbors.get(uid); return uneighb != null && uneighb.contains(vid); } public void addEdge(V uid, V vid) { LinkedHashSet uneighb = neighbors.get(uid); LinkedHashSet vneighb = neighbors.get(vid); if(uneighb != null && vneighb != null && uneighb.add(vid) && vneighb.add(uid)) { ++edgeCount; } } public void removeEdge(V uid, V vid) { LinkedHashSet uneighb = neighbors.get(uid); LinkedHashSet vneighb = neighbors.get(vid); if(uneighb != null && vneighb != null && uneighb.remove(vid) && vneighb.remove(uid)) { --edgeCount; } } }