Kruskal’s algorithm is another greedy algorithm used to find the Minimum Spanning Tree (MST) of a connected, undirected graph with weighted edges. Unlike Prim's algorithm, which grows the MST from a starting vertex, Kruskal's algorithm works by sorting all the edges of the graph and then adding them to the MST one by one, provided they don't form a cycle.
Sort all edges: Sort the edges of the graph in non-decreasing order of their weights.
Initialize:
Process each edge:
Repeat the process until the MST contains exactly V-1 edges (where V is the number of vertices in the graph).
Let’s consider the following graph with 4 vertices and 5 edges:
10 15
(0)---(1)-------(2)
| / \ |
5 / \ 4 |
| / \ |
(3)--------- (4)
3
Sort the edges in increasing order of their weights:
Initialize disjoint-set (each vertex is its own parent):
Pick the smallest edge (2, 4, 3):
Pick the next smallest edge (0, 3, 5):
Pick the next smallest edge (1, 4, 4):
Pick the next smallest edge (0, 1, 10):
Pick the next smallest edge (1, 3, 15):
At this point, we have the MST with the following edges:
The Minimum Spanning Tree contains the edges:
(2, 4, 3)
(0, 3, 5)
(1, 4, 4)
The total weight of the MST is 3 + 5 + 4 = 12.
Below is the C++ implementation of Kruskal's algorithm using the Union-Find (Disjoint-Set) data structure:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// Edge structure to store the edges
struct Edge {
int u, v, weight;
};
// Disjoint Set Union-Find structure
class UnionFind {
public:
UnionFind(int n) {
parent.resize(n);
rank.resize(n, 0);
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];
}
void unite(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
// Union by rank
if (rank[rootX] > rank[rootY]) {
parent[rootY] = rootX;
} else if (rank[rootX] < rank[rootY]) {
parent[rootX] = rootY;
} else {
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
private:
vector<int> parent, rank;
};
// Function to implement Kruskal's Algorithm
void kruskal(int V, vector<Edge>& edges) {
// Sort edges based on their weights
sort(edges.begin(), edges.end(), [](Edge a, Edge b) {
return a.weight < b.weight;
});
UnionFind uf(V);
int mstWeight = 0;
vector<Edge> mstEdges;
// Iterate through all edges, picking the smallest edge that doesn't form a cycle
for (const Edge& edge : edges) {
int u = edge.u;
int v = edge.v;
int weight = edge.weight;
if (uf.find(u) != uf.find(v)) {
uf.unite(u, v);
mstEdges.push_back(edge);
mstWeight += weight;
}
}
// Print the edges in the MST
cout << "Edges in the MST:" << endl;
for (const Edge& edge : mstEdges) {
cout << "(" << edge.u << ", " << edge.v << ") : " << edge.weight << endl;
}
cout << "Total weight of MST: " << mstWeight << endl;
}
int main() {
int V = 5; // Number of vertices
vector<Edge> edges = {
{0, 1, 10},
{0, 3, 5},
{1, 3, 15},
{1, 4, 4},
{2, 4, 3}
};
// Call Kruskal's algorithm
kruskal(V, edges);
return 0;
}
Edge Structure: The Edge structure holds the two vertices (u, v) and the weight of the edge connecting them.
Union-Find (Disjoint-Set): The UnionFind class provides methods to perform:
find: To find the root of a vertex (with path compression).unite: To merge two sets (using union by rank).Kruskal’s Algorithm:
Time Complexity:
Open this section to load past papers