Kruskal's Algorithm
Kruskal's algorithm is a minimum-spanning-tree algorithm which finds an edge of the least possible weight that connects any two trees in the forest. It is a greedy algorithm in graph theory as it finds a minimum spanning tree for a connected weighted graph adding increasing cost arcs at each step. This means it finds a subset of the edges that forms a tree that includes every vertex, where the total weight of all the edges in the tree is minimized. If the graph is not connected, then it finds a minimum spanning forest (a minimum spanning tree for each connected component).
/*****Please include following header files*****/
// stdio.h
// stdlib.h
/***********************************************/
struct Edge
{
int Source;
int Destination;
int Weight;
};
struct Graph
{
int VerticesCount;
int EdgesCount;
struct Edge* Edge;
};
struct Subset
{
int Parent;
int Rank;
};
static struct Graph* CreateGraph(int verticesCount, int edgesCoun)
{
struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));
graph->VerticesCount = verticesCount;
graph->EdgesCount = edgesCoun;
graph->Edge = (struct Edge*)malloc(graph->EdgesCount * sizeof(struct Edge));
return graph;
}
static int Find(struct Subset subsets[], int i)
{
if (subsets[i].Parent != i)
subsets[i].Parent = Find(subsets, subsets[i].Parent);
return subsets[i].Parent;
}
static void Union(struct Subset subsets[], int x, int y)
{
int xroot = Find(subsets, x);
int yroot = Find(subsets, y);
if (subsets[xroot].Rank < subsets[yroot].Rank)
subsets[xroot].Parent = yroot;
else if (subsets[xroot].Rank > subsets[yroot].Rank)
subsets[yroot].Parent = xroot;
else
{
subsets[yroot].Parent = xroot;
++subsets[xroot].Rank;
}
}
static int CompareEdges(const void* a, const void* b)
{
struct Edge* a1 = (struct Edge*)a;
struct Edge* b1 = (struct Edge*)b;
return a1->Weight > b1->Weight;
}
static void Print(struct Edge* result, int e)
{
for (int i = 0; i < e; ++i)
printf("%d -- %d == %d\n", result[i].Source, result[i].Destination, result[i].Weight);
}
static void Kruskal(struct Graph* graph)
{
int verticesCount = graph->VerticesCount;
struct Edge* result = (struct Edge*)malloc(sizeof(result) * verticesCount);
int i = 0;
int e = 0;
qsort(graph->Edge, graph->EdgesCount, sizeof(graph->Edge[0]), CompareEdges);
struct Subset* subsets = (struct Subset*) malloc(verticesCount * sizeof(struct Subset));
for (int v = 0; v < verticesCount; ++v)
{
subsets[v].Parent = v;
subsets[v].Rank = 0;
}
while (e < verticesCount - 1)
{
struct Edge nextEdge = graph->Edge[i++];
int x = Find(subsets, nextEdge.Source);
int y = Find(subsets, nextEdge.Destination);
if (x != y)
{
result[e++] = nextEdge;
Union(subsets, x, y);
}
}
Print(result, e);
}
Example
int verticesCount = 4;
int edgesCount = 5;
struct Graph* graph = CreateGraph(verticesCount, edgesCount);
// Edge 0-1
graph->Edge[0].Source = 0;
graph->Edge[0].Destination = 1;
graph->Edge[0].Weight = 10;
// Edge 0-2
graph->Edge[1].Source = 0;
graph->Edge[1].Destination = 2;
graph->Edge[1].Weight = 6;
// Edge 0-3
graph->Edge[2].Source = 0;
graph->Edge[2].Destination = 3;
graph->Edge[2].Weight = 5;
// Edge 1-3
graph->Edge[3].Source = 1;
graph->Edge[3].Destination = 3;
graph->Edge[3].Weight = 15;
// Edge 2-3
graph->Edge[4].Source = 2;
graph->Edge[4].Destination = 3;
graph->Edge[4].Weight = 4;
Kruskal(graph);
Output
2 -- 3 == 4
0 -- 3 == 5
0 -- 1 == 10