Table of Contents
What is Kruskal Algorithm?
Kruskal’s algorithm is used to find the minimum spanning tree(MST) of a connected and undirected graph.
Example
Graph

Minimum Spanning Tree(MST)

Algorithm
Kruskal’s algorithm is a greedy algorithm to find the minimum spanning tree.
- Sort the edges in ascending order according to their weights.
- At every step, choose the smallest edge(with minimum weight). If this edge forms a cycle with the MST formed so far, discard the edge, else, add it to the MST.
- Repeat step 2, until all the vertices are not present in MST.
Explanation
Consider the graph shown in above example,
The edges in the above graph are,
Edges = {{0 to 1, wt = 5}, {0 to 2, wt = 8}, {1 to 2, wt = 10}, {1 to 3, wt = 15}, {2 to 3, wt = 20}}
After sorting, edges are,
Edges = {{0 to 1 wt = 5}, {0 to 2, wt = 8}, {1 to 2, wt = 10}, {1 to 3, wt = 15}, {2 to 3, wt = 20}}
- {0 to 1, wt = 5}, include in MST

- {0 to 2, wt = 8}, include in MST

- {1 to 2, wt = 10}, forms a cycle, do not include in MST
- {1 to 3, wt = 15}, include in MST

All the vertices are included in MST, so we stop here.
JAVA Program For Kruskal Algorithm
public class KruskalAlgorithm {
// Function to find the set of element i
private static int find(Subset subsets[], int i) {
// Path Compression
if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}
// Function to perform union of two sets of x and y
private static void Union(Subset subsets[], int x, int y) {
int xRoot = find(subsets, x);
int yRoot = find(subsets, y);
// (Union by Rank)
if (subsets[xRoot].rank < subsets[yRoot].rank) {
subsets[xRoot].parent = yRoot;
} else if (subsets[xRoot].rank > subsets[yRoot].rank) {
subsets[yRoot].parent = xRoot;
} else {
// If rank are same, then make one as root and increment
// its rank by one
subsets[yRoot].parent = xRoot;
subsets[xRoot].rank++;
}
}
private static void findPrintMST(ArrayList<Edge> graph[], Edge edges[]) {
// Sort the edges in ascending order of their weights
Arrays.sort(edges, Edge.comp);
// Stores the mst
Edge mst[] = new Edge[graph.length - 1];
for (int i = 0; i < graph.length - 1; i++) {
mst[i] = new Edge(-1, -1, -1);
}
int e = 0; // Number of edges included in mst
// Create v subsets, v is the number of vertices
Subset subsets[] = new Subset[graph.length];
for (int i = 0; i < graph.length; i++) {
subsets[i] = new Subset();
}
// Initialise parent of all as itself and rank as 0
for (int i = 0; i < graph.length; i++) {
subsets[i].parent = i;
subsets[i].rank = 0;
}
// One by one traverse all the edges
for (int i = 0; i < edges.length; i++) {
// Find the set of vertices present on this edge
int x = find(subsets, edges[i].from);
int y = find(subsets, edges[i].to);
// If the set is not same(that is, no cycle is formed)
// Add this edge to mst
if (x != y) {
mst[e].from = edges[i].from;
mst[e].to = edges[i].to;
mst[e].weight = edges[i].weight;
Union(subsets, x, y);
e++;
} else {
// Discard the edge
}
// If all the vertices are included in MST, stop here
if (e == graph.length - 1) {
break;
}
}
// Print the MST
for (int i = 0; i < graph.length - 1; i++) {
System.out.println("From " + mst[i].from + " to " + mst[i].to + " weight " + mst[i].weight);
}
}
public static void main(String[] args) {
// Graph
ArrayList<Edge> graph[] = new ArrayList[4];
// Stores all the edges of the graph
Edge edges[] = new Edge[5];
for (int i = 0; i < 4; i++)
graph[i] = new ArrayList<>();
// Make the graph in given example
graph[0].add(new Edge(0, 1, 5));
graph[0].add(new Edge(0, 2, 8));
graph[1].add(new Edge(1, 0, 5));
graph[1].add(new Edge(1, 2, 10));
graph[1].add(new Edge(1, 3, 15));
graph[2].add(new Edge(2, 0, 8));
graph[2].add(new Edge(2, 1, 10));
graph[2].add(new Edge(2, 3, 20));
graph[3].add(new Edge(3, 1, 15));
graph[3].add(new Edge(3, 2, 20));
// Store all the edges of the graph
edges[0] = new Edge(0, 1, 5);
edges[1] = new Edge(0, 2, 8);
edges[2] = new Edge(1, 2, 10);
edges[3] = new Edge(1, 3, 15);
edges[4] = new Edge(2, 3, 20);
// Find MST using Kruskal's Algorithm and print it
findPrintMST(graph, edges);
}
static class Edge {
int from;
int to;
int weight;
public Edge(int from, int to, int weight) {
this.from = from;
this.to = to;
this.weight = weight;
}
public static final Comparator<Edge> comp = new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
// Sort according to edge weights
return Integer.compare(o1.weight, o2.weight);
}
};
}
// Subset class is used to detect cycle while adding an edge
static class Subset {
int parent;
int rank;
}
}C++ Program For Kruskal Algorithm
#include <iostream>
#include<algorithm>
#include <vector>
using namespace std;
// class representing an Edge of a graph
class Edge {
public:
int from;
int to;
int weight;
Edge(int f, int t, int w) {
from = f;
to = t;
weight = w;
}
};
// Subset class is used to detect cycle while adding an edge
class Subset {
public:
int parent;
int rank;
};
// Function to find the set of element i
int find(Subset subsets[], int i) {
// Path compression
if (subsets[i].parent != i)
subsets[i].parent = find(subsets, subsets[i].parent);
return subsets[i].parent;
}
// Function to perform union of two sets of x and y
void Union(Subset subsets[], int x, int y) {
int xroot = find(subsets, x);
int yroot = find(subsets, y);
// Union by Rank
if (subsets[xroot].rank < subsets[yroot].rank) {
subsets[xroot].parent = yroot;
} else if (subsets[xroot].rank > subsets[yroot].rank) {
subsets[yroot].parent = xroot;
} else {
// If ranks are same, then make one as root and
// increment its rank by one
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}
void findPrintMST(vector<Edge> graph[], vector<Edge> &edges, int v) {
// Sort the edges in ascending order of their weights
sort(edges.begin(), edges.end(),
[](const Edge& lhs, const Edge& rhs) {
return lhs.weight < rhs.weight;
});
// Stores the mst
vector<Edge> mst;
int e = 0; // Number of edges included in mst
// Create v subsets, v is the number of vertices
Subset *subsets = new Subset[(v * sizeof(Subset))];
// Initialise parent of all as itself and rank as 0
for (int i = 0; i < v; i++) {
subsets[i].parent = i;
subsets[i].rank = 0;
}
// One by one traverse all the edges
for (int i = 0; i < edges.size(); i++) {
// Find the set of vertices present on this edge
int x = find(subsets, edges[i].from);
int y = find(subsets, edges[i].to);
// If the set is not same(that is, no cycle is formed)
// Add this edge to mst
if (x != y) {
Edge curr(edges[i].from, edges[i].to, edges[i].weight);
mst.push_back(curr);
Union(subsets, x, y);
e++;
} else {
// Discard the edge
}
// If all the vertices are included in MST, stop here
if (e == v - 1) {
break;
}
}
// Print the mst
for (int i = 0; i < mst.size(); i++) {
cout<<"From "<<mst[i].from<<" to "<<mst[i].to<<" weight "<<mst[i].weight<<endl;
}
}
int main() {
vector<Edge> graph[4];
vector<Edge> edges;
// Make the graph in given example
Edge e1(0, 1, 5);
Edge e2(0, 2, 8);
Edge e3(1, 0, 5);
Edge e4(1, 2, 10);
Edge e5(1, 3, 15);
Edge e6(2, 0, 8);
Edge e7(2, 1, 10);
Edge e8(2, 3, 20);
Edge e9(3, 1, 15);
Edge e10(3, 2, 20);
graph[0].push_back(e1);
graph[0].push_back(e2);
graph[1].push_back(e3);
graph[1].push_back(e4);
graph[1].push_back(e5);
graph[2].push_back(e6);
graph[2].push_back(e7);
graph[2].push_back(e8);
graph[3].push_back(e9);
graph[3].push_back(e10);
// Edges in the graph
edges.push_back(e1);
edges.push_back(e2);
edges.push_back(e4);
edges.push_back(e5);
edges.push_back(e8);
// Find MST using Kruskal's Algorithm and print it
findPrintMST(graph, edges, 4);
return 0;
}Output
From 0 to 1 weight 5 From 0 to 2 weight 8 From 1 to 3 weight 15
Time Complexity
O(E * log(E) + E * log (V)) where E denotes the Number of edges in the graph and V denotes the Number of vertices in the graph.

