packagecom.thealgorithms.datastructures.graphs;importjava.util.Comparator;importjava.util.HashSet;importjava.util.PriorityQueue;publicclassKruskal{// Complexity: O(E log V) time, where E is the number of edges in the graph and V is the number of// verticesprivatestaticclassEdge{privateint from;privateintto;privateint weight;publicEdge(int from,intto,int weight){this.from = from;this.to=to;this.weight = weight;}}privatestaticvoidaddEdge(HashSet<Edge>[] graph,int from,intto,int weight){
graph[from].add(newEdge(from,to, weight));}publicstaticvoidmain(String[] args){HashSet<Edge>[] graph =newHashSet[7];for(int i =0; i < graph.length; i++){
graph[i]=newHashSet<>();}addEdge(graph,0,1,2);addEdge(graph,0,2,3);addEdge(graph,0,3,3);addEdge(graph,1,2,4);addEdge(graph,2,3,5);addEdge(graph,1,4,3);addEdge(graph,2,4,1);addEdge(graph,3,5,7);addEdge(graph,4,5,8);addEdge(graph,5,6,9);System.out.println("Initial Graph: ");for(int i =0; i < graph.length; i++){for(Edge edge : graph[i]){System.out.println(i +" <-- weight "+ edge.weight +" --> "+ edge.to);}}Kruskal k =newKruskal();HashSet<Edge>[] solGraph = k.kruskal(graph);System.out.println("\nMinimal Graph: ");for(int i =0; i < solGraph.length; i++){for(Edge edge : solGraph[i]){System.out.println(i +" <-- weight "+ edge.weight +" --> "+ edge.to);}}}publicHashSet<Edge>[]kruskal(HashSet<Edge>[] graph){int nodes = graph.length;int[] captain =newint[nodes];// captain of i, stores the set with all the connected nodes to iHashSet<Integer>[] connectedGroups =newHashSet[nodes];HashSet<Edge>[] minGraph =newHashSet[nodes];PriorityQueue<Edge> edges =newPriorityQueue<>((Comparator.comparingInt(edge -> edge.weight)));for(int i =0; i < nodes; i++){
minGraph[i]=newHashSet<>();
connectedGroups[i]=newHashSet<>();
connectedGroups[i].add(i);
captain[i]= i;
edges.addAll(graph[i]);}int connectedElements =0;// as soon as two sets merge all the elements, the algorithm must stopwhile(connectedElements != nodes &&!edges.isEmpty()){Edge edge = edges.poll();// This if avoids cyclesif(!connectedGroups[captain[edge.from]].contains(edge.to)&&!connectedGroups[captain[edge.to]].contains(edge.from)){// merge sets of the captains of each point connected by the edge
connectedGroups[captain[edge.from]].addAll(connectedGroups[captain[edge.to]]);// update captains of the elements merged
connectedGroups[captain[edge.from]].forEach(i -> captain[i]= captain[edge.from]);// add Edge to minimal graphaddEdge(minGraph, edge.from, edge.to, edge.weight);// count how many elements have been merged
connectedElements = connectedGroups[captain[edge.from]].size();}}return minGraph;}}