Minimum spanning tree-Kruskal's algorithm, with C Program Example

Kruskal’s algorithm to find the minimum cost spanning tree uses the greedy approach. This algorithm treats the graph as a forest and every node it has as an individual tree. A tree connects to another only and only if, it has the least cost among all available options and does not violate MST(Minimum spanning tree) properties.

Kruskal’s algorithm

  • create a forest F (a set of trees), where each vertex in the graph is a separate tree
  • create a set S containing all the edges in the graph
  • while S is nonempty and F is not yet spanning
    • remove an edge with minimum weight from S
    • if the removed edge connects two different trees then add it to the forest F, combining two trees into a single tree

_config.yml

At the termination of the algorithm, the forest forms a minimum spanning forest of the graph. If the graph is connected, the forest has a single component and forms a minimum spanning tree Kruskal’s algorithm can be shown to run in O(E log E) time, or equivalently, O(E log V) time, where E is the number of edges in the graph and V is the number of vertices.

Program in C :

#include<stdlib.h>
#include<stdio.h>
 
#define NIL -1
#define MAX 100
 
struct edge
{
      int x;
      int y;
      int weight;
      struct edge *link;
}*front = NULL;
 
void create_tree(struct edge tree[]);
void insert_queue(int i, int j, int wt);
struct edge *delete_queue();
int isEmpty();
void make_a_graph();
 
int vertices;
 
int main()
{
      int count;
      struct edge tree[MAX];
      int tree_weight = 0;
      make_a_graph();
      create_tree(tree);
      printf("Edges in MST:\n");
      for(count = 1; count <= vertices - 1; count++)
      {
            printf("%d->", tree[count].x);
            printf("%d\n", tree[count].y);
            tree_weight = tree_weight + tree[count].weight;
      }
      printf("Total Weight of this Minimum Spanning Tree:\t%d\n", tree_weight);
      return 0;
}
 
void create_tree(struct edge tree[])
{
      struct edge *tmp;
      int y1, y2, root_y1, root_y2;
      int parent[MAX];
      int i, count = 0;
      for(i = 0; i < vertices; i++)
      {
            parent[i] = NIL;
      }
      while(!isEmpty( ) && count < vertices - 1) 
      {
            tmp = delete_queue();
            y1 = tmp->x;
            y2 = tmp->y; 
            while(y1 != NIL)
            {
                  root_y1 = y1;
                  y1 = parent[y1];
            }
            while(y2 != NIL)
            {
                  root_y2 = y2;
                  y2 = parent[y2];
            }
            if(root_y1 != root_y2)
            {
                  count++;
                  tree[count].x = tmp->x;
                  tree[count].y = tmp->y;
                  tree[count].weight = tmp->weight;
                  parent[root_y2] = root_y1;
            }
      }
      if(count < vertices - 1)
      {
            printf("Graph is Disconnected. Therefore, Spanning Tree is not possible\n");
            exit(1);
      }
}
 
void insert_queue(int i, int j, int wt)
{
      struct edge *tmp, *q;
      tmp = (struct edge *)malloc(sizeof(struct edge));
      tmp->x = i;
      tmp->y = j;
      tmp->weight = wt;
      if(front == NULL || tmp->weight < front->weight)
      {
            tmp->link = front;
            front = tmp;
      }
      else
      {
            q = front;
            while(q->link != NULL && q->link->weight <= tmp->weight)
            {
                  q = q->link;
            }
            tmp->link = q->link;
            q->link = tmp;
            if(q->link == NULL) 
            {
                  tmp->link = NULL;
            }
      }
}
 
struct edge *delete_queue()
{
      struct edge *tmp;
      tmp = front;
      front = front->link;
      return tmp;
}
 
int isEmpty()
{
      if(front == NULL)
      {
            return 1;
      }
      else
      {
            return 0;
      }
}
 
void make_a_graph()
{
      int count, weight, maximum_edges, origin_vertex, destination_vertex;
      printf("Enter Total Number of Vertices:\t");
      scanf("%d", &vertices);
      maximum_edges = vertices * (vertices - 1)/2;
      for(count = 0; count < maximum_edges; count++)
      {
            printf("Enter Edge [%d] Co-ordinates [-1 -1] to Quit\n", count + 1);
            printf("Enter Origin Point:\t"); 
            scanf("%d", &origin_vertex);
            printf("Enter Destination Point:\t");
            scanf("%d", &destination_vertex);
            if((origin_vertex == -1) && (destination_vertex == -1))
            {
                  break;
            }
            printf("Enter Weight for this Edge:\n");
            scanf("%d", &weight);
            if(origin_vertex >= vertices || destination_vertex >= vertices || origin_vertex < 0 || destination_vertex < 0)
            {
                  printf("Entered Edge Co - ordinates is Invalid\n");
                  count--;
            }
            else
            {
                  insert_queue(origin_vertex, destination_vertex, weight);
            }
      }
}

Output:

_config.yml

Please comment below in case of any problem found during running the code or any other doubts.

Saheb Ghosh

Saheb Ghosh
Computer Science Major, Bioinformatics Bachelor, Deep Learning enthusiast, hard core Gamer , occasional Philosopher, avid music listener and movie lover. Visit my other blog for Gaming and Technical review related posts @ Blogger; also feel free to post a question @ Quora (links below)

How to Change Service Fabric replicator log size and drive

How to modify Service Fabric replicator log size and also how to change Service Fabric Local cluster installtion directory or log directory. Continue reading