I am implementing Prim's algorithm in java, and would like to determine the time complexity of my method. I am using hash maps as the structure for the tree, and looking at my code, I think the complexity is quadratic in relation to the number of edges, O(E^2).
First, here is my code:
abstract class Graph{
abstract void insertEdge(String v,String u,int w);
abstract void printGraph();
static HashMap<String,Vertex> vertex=new HashMap<>();
static Vertex vertex(String s){
if(!vertex.containsKey(s))vertex.put(s,new Vertex(s));
return vertex.get(s);
}
Collection<Vertex> vertices(){return vertex.values();}
abstract Collection<Edge> edges();
abstract Collection<Edge> outEdge(Vertex v);
// the algorithm for checking that the graph is connected
void visitDepthFirst(Vertex v, Set<Vertex> visited){
if(visited.contains(v))return;
System.out.println("visited "+ v);
visited.add(v);
for(Edge e:outEdge(v))visitDepthFirst(e.to,visited);
}
}
class Vertex{
String name;
Vertex(String s){name=s;}
public String toString(){return name;}
}
class Edge{
Vertex from,to;
int weight;
Edge(Vertex from,Vertex to,int w){this.from=from; this.to=to; weight=w;}
public String toString(){return from.name+" - "+weight+" -> "+to.name; }
}
class AdjListGraph extends Graph {
HashMap<Vertex, Set<Edge>> outEdge = new HashMap<>();
void insertEdge(String u, String v, int w) {
Edge e = new Edge(vertex(u), vertex(v), w);
if (!outEdge.containsKey(e.from))
outEdge.put(e.from, new HashSet<Edge>());
outEdge.get(e.from).add(e);
}
Collection<Edge> edges() {
Set<Edge> edges = new HashSet<>();
for (Vertex v : outEdge.keySet()) edges.addAll(outEdge.get(v));
return edges;
}
void printGraph() {
for (Vertex v : outEdge.keySet()) {
System.out.println("vertex " + v);
for (Edge e : outEdge.get(v)) System.out.println(" " + e);
}
}
Collection<Edge> outEdge(Vertex v) {
return outEdge.get(v);
}
// implementation of the minimum spanning tree
public HashSet<Edge> minimumSpanningTree(){
Collection<Vertex> vertices = vertices();
Collection<Edge> edges = null;
HashSet<Edge> mst = new HashSet<>();
HashSet<Vertex> frontier = new HashSet<>();
for (Vertex v : vertices) {
frontier.add(v);
edges = outEdge(v);
break;
}
while (true) {
Edge nearest = null;
for (Edge e : edges) { // Linear complexity
if (nearest == null || nearest.weight > e.weight)
nearest = e;
}
if (nearest == null) break;
mst.add(nearest);
frontier.add(nearest.to);
edges.addAll(outEdge(nearest.to));
edges.remove(nearest);
edges.removeIf(e -> frontier.contains(e.to));
if (frontier.size() == vertices().size()) break;
}
System.out.println("Frontier: " + frontier);
return mst;
}
}
I believe that the complexity is O(E^2) because all of the operations in the method operate on constant time due to the use of hash sets, so the only opportunity for increased complexity seems to arise in the while loop and for loop, both of which potentially loop through every edge. Is my understanding correct?