Kruskal's algorithm is a greedy algorithm for finding a Minimum Spanning Tree (MST) of a connected, undirected, weighted graph.
It sorts all edges by weight and adds the cheapest safe edge one by one.
Union-Find, also called Disjoint Set Union (DSU), is used to avoid cycles efficiently.
Kruskal's algorithm finds a minimum spanning tree of a weighted, undirected graph. A minimum spanning tree connects all vertices with the minimum possible total edge weight and contains no cycle.
The algorithm is greedy because it repeatedly picks the smallest available edge. However, it does not blindly add every small edge. It adds an edge only when that edge connects two different components and does not form a cycle.
Kruskal is useful whenever we want to connect multiple points with the minimum total cost.
| Term | Meaning |
|---|---|
| Spanning Tree | A tree that connects all vertices of a connected graph without cycles |
| Minimum Spanning Tree | A spanning tree with the minimum possible total edge weight |
| Component | A connected group of vertices formed so far |
| Safe Edge | An edge that can be added without creating a cycle |
| Union-Find | A data structure used to check and merge connected components |
The algorithm starts with no selected edges. Every vertex is treated as a separate component. Then edges are processed from smallest weight to largest weight.
Kruskal's algorithm is based on the cut property of MSTs. If we divide the graph into two parts, the lightest edge crossing that cut is safe to include in some minimum spanning tree.
When Kruskal picks the smallest edge that joins two different components, that edge is the cheapest way to connect those two separated parts at that moment. Since it does not create a cycle, it preserves the tree structure.
Consider the following weighted undirected graph with 4 vertices: A, B, C, and D.
| Edge | Weight |
|---|---|
| A - B | 10 |
| A - C | 6 |
| A - D | 5 |
| B - D | 15 |
| C - D | 4 |
First sort the edges by weight: C-D(4), A-D(5), A-C(6), A-B(10), B-D(15).
| Step | Edge Checked | Decision | Reason | MST Edges So Far |
|---|---|---|---|---|
| 1 | C - D (4) | Add | C and D are in different components | C-D |
| 2 | A - D (5) | Add | A is separate, D is in component C-D | C-D, A-D |
| 3 | A - C (6) | Skip | A and C are already connected through D, so this forms a cycle | C-D, A-D |
| 4 | A - B (10) | Add | B is separate, so this connects a new vertex | C-D, A-D, A-B |
The graph has 4 vertices, so the MST must contain V-1 = 3 edges. After selecting 3 edges, the algorithm stops.
The most important implementation detail in Kruskal's algorithm is cycle detection. If we check cycles by traversing the graph every time, the algorithm becomes slow. Union-Find solves this problem efficiently.
The following program stores each edge as {u, v, weight}, sorts edges by weight, and uses Union-Find to build the MST.
import java.util.*;
public class KruskalMST {
static class Edge {
int u, v, weight;
Edge(int u, int v, int weight) {
this.u = u;
this.v = v;
this.weight = weight;
}
}
static class DSU {
int[] parent;
int[] rank;
DSU(int n) {
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]); // path compression
}
return parent[x];
}
boolean union(int a, int b) {
int rootA = find(a);
int rootB = find(b);
if (rootA == rootB) {
return false; // cycle would be formed
}
if (rank[rootA] < rank[rootB]) {
parent[rootA] = rootB;
} else if (rank[rootA] > rank[rootB]) {
parent[rootB] = rootA;
} else {
parent[rootB] = rootA;
rank[rootA]++;
}
return true;
}
}
static int kruskal(int vertices, List<Edge> edges) {
edges.sort(Comparator.comparingInt(edge -> edge.weight));
DSU dsu = new DSU(vertices);
int totalWeight = 0;
int selectedEdges = 0;
System.out.println("Edges in MST:");
for (Edge edge : edges) {
if (dsu.union(edge.u, edge.v)) {
System.out.println(edge.u + " - " + edge.v + " : " + edge.weight);
totalWeight += edge.weight;
selectedEdges++;
if (selectedEdges == vertices - 1) {
break;
}
}
}
return totalWeight;
}
public static void main(String[] args) {
int vertices = 4;
List<Edge> edges = new ArrayList<>();
edges.add(new Edge(0, 1, 10)); // A-B
edges.add(new Edge(0, 2, 6)); // A-C
edges.add(new Edge(0, 3, 5)); // A-D
edges.add(new Edge(1, 3, 15)); // B-D
edges.add(new Edge(2, 3, 4)); // C-D
int mstWeight = kruskal(vertices, edges);
System.out.println("Total MST Weight = " + mstWeight);
}
}
Edges in MST:
2 - 3 : 4
0 - 3 : 5
0 - 1 : 10
Total MST Weight = 19
Let V be the number of vertices and E be the number of edges.
| Operation | Complexity | Explanation |
|---|---|---|
| Sorting edges | O(E log E) | All edges are sorted by weight |
| Union-Find operations | Almost O(E) | With path compression and union by rank |
| Overall time | O(E log E) | Sorting dominates the running time |
| Space complexity | O(V + E) | Edges plus parent and rank arrays |
| Point | Kruskal | Prim |
|---|---|---|
| Approach | Edge-based | Vertex/tree-based |
| Main operation | Sort all edges and pick safe edges | Grow one tree by cheapest outgoing edge |
| Data structure | Union-Find | Priority queue |
| Best for | Sparse graphs | Dense graphs |
Add every edge after sorting by weight.
Add an edge only if its endpoints are in different components.
Stop after selecting V edges.
Stop after selecting V - 1 edges.
Use Kruskal to find shortest paths from a source vertex.
Use Kruskal to build a minimum spanning tree.
Yes. It makes a greedy choice by selecting the smallest safe edge at each step.
Union-Find quickly tells whether two vertices are already connected. If they are connected, adding the edge would create a cycle.
Yes. Negative weights are allowed in MST problems. The edges are still sorted by weight, and the same cycle-checking rule applies.
For a connected graph with V vertices, the MST has exactly V-1 edges.
A single MST cannot be formed. Kruskal will produce a minimum spanning forest, one tree for each connected component.
Explore 500+ free tutorials across 20+ languages and frameworks.