//gioel package graph; import arraylist.ArrayIndexList; import arraylist.IndexList; import position.NodePositionList; import position.PositionList; import exceptions.InvalidKeyException; public abstract class BFS { protected Graph graph; protected Vertex start; protected I info; protected R visitResult; protected static Object STATUS = new Object(); protected static Object VISITED = new Object(); protected static Object UNVISITED = new Object(); protected IndexList>> layers; public R execute(Graph g, Vertex s, I in) throws InvalidKeyException{ graph = g; layers = new ArrayIndexList>>( graph.numVertices()); start = s; info = in; for (Vertex v : graph.vertices()) unVisit(v); for (Edge e : graph.edges()) unVisit(e); setup(); return finalResult(bfsTraversal(start)); } protected void setup() { } protected R bfsTraversal(Vertex v) throws InvalidKeyException{ initResult(); if (!isDone()) startVisit(v); if (!isDone()) { visit(v); layers.add(0, new NodePositionList>()); layers.get(0).addLast(v); } int i = 0; while (!layers.get(i).isEmpty()) { layers.add(i + 1, new NodePositionList>()); for (Vertex vertexInLayer : layers.get(i)) { for (Edge e : graph.incidentEdges(vertexInLayer)) { if (!isVisited(e)) { visit(e); Vertex w = graph.opposite(vertexInLayer, e); if (!isVisited(w)) { traverseDiscovery(e, vertexInLayer); if (isDone()) break; visit(w); layers.get(i + 1).addLast(w); if (isDone()) break; } else { traverseCross(e, v); if (isDone()) break; } } } if (!isDone()) finishVisit(vertexInLayer); } i++; } return result(); } protected void initResult() { } protected void startVisit(Vertex v) { } protected void traverseCross(Edge e, Vertex v) { } protected void traverseDiscovery(Edge e, Vertex v) { } protected void finishVisit(Vertex v) { } protected boolean isDone() { return false; } protected R result() { return null; } protected R finalResult(R r) { return null; } protected void visit(DecorablePosition p) throws InvalidKeyException{ p.put(STATUS, VISITED); } protected void unVisit(DecorablePosition p) throws InvalidKeyException { p.put(STATUS, UNVISITED); } protected boolean isVisited(DecorablePosition p) throws InvalidKeyException { return p.get(STATUS) == VISITED; } }