Skip to content

Instantly share code, notes, and snippets.

@jeewamp
Created December 1, 2012 14:21
Show Gist options
  • Save jeewamp/4182553 to your computer and use it in GitHub Desktop.
Save jeewamp/4182553 to your computer and use it in GitHub Desktop.
Hierholzers' Algorithm to find Eulerian Trail
/**
* @param adjacencyList, oddVertices, EulerianPath.
*/
public <P extends Integer, Q extends ArrayList<P>> ArrayList<P>
hierholzersAlgorithm(HashMap<P, Q> adjacencyList, ArrayList<P> oddVertices, ArrayList<P> path) {
P currentVertex=null;
//If path is not empty, the start vertex should be in the path.
//Check if Semi-Eulerian. If yes, start traversing from one of them.
if(oddVertices.size()==2) {
if(path.isEmpty() || path.contains(oddVertices.get(0)))
currentVertex=oddVertices.get(0);
else if(path.contains(oddVertices.get(1)))
currentVertex=oddVertices.get(1);
}
//Check if Eulerian.
else {
Iterator iterator = adjacencyList.keySet().iterator();
while (iterator.hasNext()) {
P vertex = (P)iterator.next();
ArrayList adjacentVertices = adjacencyList.get(vertex);
//This edge is not visited. So let that vertex be the start vertex if that vertex is in the path.
//If the path is empty, i.e. trying to traverse for the first time, then just start from this vertex.
if(adjacentVertices.size()>0) {
if(path.isEmpty() || path.contains(vertex)){
currentVertex=vertex;
break;
}
}
}
}
//At this point currentVertex is the start vertex. If the currentVertex is null, then the graph is
//completely traversed.
if(currentVertex==null)
return path;
//Traverse the graph and find a sub path/trail until you come to the start point. Here the path
//is a sub path if you haven't traversed the entire graph.
ArrayList<P> subPath = new ArrayList<P>();
while (currentVertex!=null) {
subPath.add(currentVertex);
ArrayList nextHops = adjacencyList.get(currentVertex);
if(nextHops.size()>0) {
P nextVertex=(P)nextHops.get(0);
adjacencyList=removeEdge(adjacencyList,currentVertex,nextVertex);
currentVertex=nextVertex;
}
//We have come to the start point and there is nowhere else to go.
else
currentVertex=null;
}
//Add subPath to path.
if(path.isEmpty())
path=subPath;
//Connect the subPath to path to get a longer trail.
else if(subPath.size()>1) {
ArrayList<P> adjustedPath = new ArrayList<P>();
boolean subPathAdded = false;
for (int i = 0; i < path.size(); i++) {
adjustedPath.add(path.get(i));
if(!subPathAdded && path.get(i).equals(subPath.get(0))){
for (int j = 1; j < subPath.size(); j++) {
adjustedPath.add(subPath.get(j));
subPathAdded=true;
}
}
}
path=adjustedPath;
}
//get the oddVertices of the remaining graph (After removing some edges due to traversing)
oddVertices= checkEulerian(adjacencyList);
//Recursively call the method untill you traverse the entire graph.
path=hierholzersAlgorithm(adjacencyList, oddVertices, path);
return path;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment