# Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2

• Difficulty Level : Medium
• Last Updated : 30 Jan, 2023

## What is a Spanning Tree?

A Spanning tree is a subset to a connected graph G, where all the edges are connected, i.e, one can traverse to any edge from a particular edge with or without intermediates. Also, a spanning tree must not have any cycle in it. Thus we can say that if there are N vertices in a connected graph then the no. of edges that a spanning tree may have is N-1.

## What is a Minimum Spanning Tree?

Given a connected and undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices together. A single graph can have many different spanning trees. A minimum spanning tree (MST) or minimum weight spanning tree for a weighted, connected, undirected graph is a spanning tree with a weight less than or equal to the weight of every other spanning tree. The weight of a spanning tree is the sum of weights given to each edge of the spanning tree.

## How many edges does a minimum spanning tree has?

A minimum spanning tree has (V – 1) edges where V is the number of vertices in the given graph.

## How to find MST using Kruskal’s algorithm?

Below are the steps for finding MST using Kruskal’s algorithm:

1. Sort all the edges in non-decreasing order of their weight.
2. Pick the smallest edge. Check if it forms a cycle with the spanning tree formed so far. If the cycle is not formed, include this edge. Else, discard it.
3. Repeat step#2 until there are (V-1) edges in the spanning tree.

Step #2 uses the Union-Find algorithm to detect cycles.

So we recommend reading the following post as a prerequisite.

Kruskal’s algorithm to find the minimum cost spanning tree uses the greedy approach. The Greedy Choice is to pick the smallest weight edge that does not cause a cycle in the MST constructed so far. Let us understand it with an example:

Below is the illustration of the above approach:

Input Graph:

The graph contains 9 vertices and 14 edges. So, the minimum spanning tree formed will be having (9 – 1) = 8 edges.

```After sorting:
Weight   Src    Dest
1         7      6
2         8      2
2         6      5
4         0      1
4         2      5
6         8      6
7         2      3
7         7      8
8         0      7
8         1      2
9         3      4
10        5      4
11        1      7
14        3      5```

Now pick all edges one by one from the sorted list of edges
Step 1: Pick edge 7-6: No cycle is formed, include it.

Step 2:  Pick edge 8-2: No cycle is formed, include it.

Step 3: Pick edge 6-5: No cycle is formed, include it.

Step 4: Pick edge 0-1: No cycle is formed, include it.

Step 5: Pick edge 2-5: No cycle is formed, include it.

Step 6: Pick edge 8-6: Since including this edge results in the cycle, discard it.
Step 7: Pick edge 2-3: No cycle is formed, include it.

Step 8: Pick edge 7-8: Since including this edge results in the cycle, discard it.
Step 9: Pick edge 0-7: No cycle is formed, include it.

Step 10: Pick edge 1-2: Since including this edge results in the cycle, discard it.
Step 11: Pick edge 3-4: No cycle is formed, include it.

Note: Since the number of edges included in the MST equals to (V – 1), so the algorithm stops here.

Below is the implementation of the above approach:

## C

 `#include``#include` `int` `comparator(``const` `void` `*p1,``const` `void` `*p2)``//used by qsort()``{``    ``const` `int` `(*x)[3]=p1;``    ``const` `int` `(*y)[3]=p2;` `    ``return` `(*x)[2]-(*y)[2];``}` `void` `makeSet(``int` `parent[],``int` `rank[],``int` `n)``{``    ``for``(``int` `i=0;i v(adjacent vertices)``    ``//and its cost/distance;``    ``int` `edge[5][3]={{0,1,10},``                    ``{0,2,6},``                    ``{0,3,5},``                    ``{1,3,15},``                    ``{2,3,4}};` `    ``kruskalAlgo(5,edge);``}`

## C++

 `// C++ program for the above approach` `#include ``using` `namespace` `std;` `// DSU data structure``// path compression + rank by union` `class` `DSU {``    ``int``* parent;``    ``int``* rank;` `public``:``    ``DSU(``int` `n)``    ``{``        ``parent = ``new` `int``[n];``        ``rank = ``new` `int``[n];` `        ``for` `(``int` `i = 0; i < n; i++) {``            ``parent[i] = -1;``            ``rank[i] = 1;``        ``}``    ``}` `    ``// Find function``    ``int` `find(``int` `i)``    ``{``        ``if` `(parent[i] == -1)``            ``return` `i;` `        ``return` `parent[i] = find(parent[i]);``    ``}` `    ``// Union function``    ``void` `unite(``int` `x, ``int` `y)``    ``{``        ``int` `s1 = find(x);``        ``int` `s2 = find(y);` `        ``if` `(s1 != s2) {``            ``if` `(rank[s1] < rank[s2]) {``                ``parent[s1] = s2;``            ``}``            ``else` `if` `(rank[s1] > rank[s2]) {``                ``parent[s2] = s1;``            ``}``            ``else` `{``                ``parent[s2] = s1;``                ``rank[s1] += 1;``            ``}``        ``}``    ``}``};` `class` `Graph {``    ``vector > edgelist;``    ``int` `V;` `public``:``    ``Graph(``int` `V) { ``this``->V = V; }` `    ``void` `addEdge(``int` `x, ``int` `y, ``int` `w)``    ``{``        ``edgelist.push_back({ w, x, y });``    ``}` `    ``void` `kruskals_mst()``    ``{``        ``// 1. Sort all edges``        ``sort(edgelist.begin(), edgelist.end());` `        ``// Initialize the DSU``        ``DSU s(V);``        ``int` `ans = 0;``        ``cout << ``"Following are the edges in the "``                ``"constructed MST"``             ``<< endl;``        ``for` `(``auto` `edge : edgelist) {``            ``int` `w = edge[0];``            ``int` `x = edge[1];``            ``int` `y = edge[2];` `            ``// Take this edge in MST if it does``            ``// not forms a cycle``            ``if` `(s.find(x) != s.find(y)) {``                ``s.unite(x, y);``                ``ans += w;``                ``cout << x << ``" -- "` `<< y << ``" == "` `<< w``                     ``<< endl;``            ``}``        ``}` `        ``cout << ``"Minimum Cost Spanning Tree: "` `<< ans;``    ``}``};` `// Driver's code``int` `main()``{``    ``/* Let us create following weighted graph``                   ``10``              ``0--------1``              ``|  \     |``             ``6|   5\   |15``              ``|      \ |``              ``2--------3``                  ``4       */``    ``Graph g(4);``    ``g.addEdge(0, 1, 10);``    ``g.addEdge(1, 3, 15);``    ``g.addEdge(2, 3, 4);``    ``g.addEdge(2, 0, 6);``    ``g.addEdge(0, 3, 5);` `    ``// Function call``    ``g.kruskals_mst();``    ``return` `0;``}`

## Java

 `// Java program for Kruskal's algorithm to``// find Minimum Spanning Tree of a given``// connected, undirected and  weighted graph` `import` `java.util.ArrayList;``import` `java.util.Comparator;``import` `java.util.List;` `public` `class` `KruskalsMST {` `      ``// defines edge structure``    ``static` `class` `Edge {``        ``int` `src, dest, weight;` `        ``public` `Edge(``int` `src, ``int` `dest, ``int` `weight) {``            ``this``.src = src;``            ``this``.dest = dest;``            ``this``.weight = weight;``        ``}``    ``}``    ` `  ``// defines subset element structure``    ``static` `class` `Subset {``        ``int` `parent, rank;` `        ``public` `Subset(``int` `parent, ``int` `rank) {``            ``this``.parent = parent;``            ``this``.rank = rank;``        ``}``    ``}` `    ``// Starting point of program execution``    ``public` `static` `void` `main(String[] args) {``        ``/*****************************************``         ``* Let us create following weighted graph``                ``10``           ``0--------1``           ``| -      |``          ``6|   5-   |15``           ``|      - |``           ``2--------3``               ``4      ``         ``*****************************************/``        ``int` `V = ``4``;``        ``List graphEdges = ``new` `ArrayList(List.of(``                ``new` `Edge(``0``, ``1``, ``10``),               ``                ``new` `Edge(``0``, ``2``, ``6``),   ``                ``new` `Edge(``0``, ``3``, ``5``),``                ``new` `Edge(``1``, ``3``, ``15``),``                ``new` `Edge(``2``, ``3``, ``4``)``        ``));``      ` `          ``// Step 1: sort the edges in non-decreasing order``        ``// (increasing with repetition allowed)``        ``graphEdges.sort(``new` `Comparator() {``            ``@Override``            ``public` `int` `compare(Edge o1, Edge o2) {``                ``return` `o1.weight - o2.weight;``            ``}``        ``});` `        ``kruskals(V, graphEdges);``    ``}`  `    ``private` `static` `void` `kruskals(``int` `V, List edges) {``        ``int` `j = ``0``;``        ``int` `noOfEdges = ``0``;``        ``// Allocate memory for creating V subsets``        ``Subset subsets[] = ``new` `Subset[V];``      ` `          ``// Allocate memory for results``        ``Edge results[] = ``new` `Edge[V];` `        ``// Create V subsets with single elements``        ``for` `(``int` `i = ``0``; i < V; i++) {``            ``subsets[i] = ``new` `Subset(i, ``0``);``        ``}` `        ``// Number of edges to be taken is equal to V-1``        ``while` `(noOfEdges < V - ``1``) {``            ``// Step 2: Pick the smallest edge. And increment``            ``// the index for next iteration``            ``Edge nextEdge = edges.get(j);``            ``int` `x = findRoot(subsets, nextEdge.src);``            ``int` `y = findRoot(subsets, nextEdge.dest);` `            ``// If including this edge doesn't cause cycle,``            ``// include it in result and increment the index``            ``// of result for next edge``            ``if` `(x != y) {``                ``results[noOfEdges] = nextEdge;``                ``union(subsets, x, y);``                ``noOfEdges++;``            ``}` `            ``j++;``        ``}` `        ``// print the contents of result[] to display the built MST``        ``System.out.println(``"Following are the edges of the constructed MST:"``);``        ``System.out.println(``"-----------------------------------------------"``);``        ``int` `minCost = ``0``;``        ``for` `(``int` `i = ``0``; i < noOfEdges; i++) {``            ``System.out.println(results[i].src + ``" - "` `+ results[i].dest + ``": "` `+ results[i].weight);``            ``minCost += results[i].weight;``        ``}``        ``System.out.println(``"-----------------------------------------------"``);``        ``System.out.println(``"Total cost of MST: "``+minCost);` `    ``}` `    ``private` `static` `void` `union(Subset[] subsets, ``int` `x, ``int` `y) {``        ``int` `rootX = findRoot(subsets, x);``        ``int` `rootY = findRoot(subsets, y);` `        ``if` `(subsets[rootY].rank < subsets[rootX].rank) {``            ``subsets[rootY].parent = rootX;``        ``} ``else` `if` `(subsets[rootX].rank < subsets[rootY].rank) {``            ``subsets[rootX].parent = rootY;``        ``} ``else` `{``            ``subsets[rootY].parent = rootX;``            ``subsets[rootX].rank++;``        ``}``    ``}` `    ``private` `static` `int` `findRoot(Subset[] subsets, ``int` `i) {``        ``if` `(subsets[i].parent == i)``            ``return` `subsets[i].parent;` `        ``subsets[i].parent = findRoot(subsets, subsets[i].parent);``        ``return` `subsets[i].parent;``    ``}``}``// This code is contributed by Salvino D'sa`

## Python3

 `# Python program for Kruskal's algorithm to find``# Minimum Spanning Tree of a given connected,``# undirected and weighted graph` `# Class to represent a graph`  `class` `Graph:` `    ``def` `__init__(``self``, vertices):``        ``self``.V ``=` `vertices  ``# No. of vertices``        ``self``.graph ``=` `[]``        ``# to store graph` `    ``# function to add an edge to graph``    ``def` `addEdge(``self``, u, v, w):``        ``self``.graph.append([u, v, w])` `    ``# A utility function to find set of an element i``    ``# (truly uses path compression technique)``    ``def` `find(``self``, parent, i):``        ``if` `parent[i] !``=` `i:``          ``# Reassignment of node's parent to root node as``          ``# path compression requires``            ``parent[i] ``=` `self``.find(parent, parent[i])``        ``return` `parent[i]` `    ``# A function that does union of two sets of x and y``    ``# (uses union by rank)``    ``def` `union(``self``, parent, rank, x, y):` `        ``# Attach smaller rank tree under root of``        ``# high rank tree (Union by Rank)``        ``if` `rank[x] < rank[y]:``            ``parent[x] ``=` `y``        ``elif` `rank[x] > rank[y]:``            ``parent[y] ``=` `x` `        ``# If ranks are same, then make one as root``        ``# and increment its rank by one``        ``else``:``            ``parent[y] ``=` `x``            ``rank[x] ``+``=` `1` `    ``# The main function to construct MST using Kruskal's``        ``# algorithm``    ``def` `KruskalMST(``self``):` `        ``result ``=` `[]  ``# This will store the resultant MST` `        ``# An index variable, used for sorted edges``        ``i ``=` `0` `        ``# An index variable, used for result[]``        ``e ``=` `0` `        ``# Step 1:  Sort all the edges in``        ``# non-decreasing order of their``        ``# weight.  If we are not allowed to change the``        ``# given graph, we can create a copy of graph``        ``self``.graph ``=` `sorted``(``self``.graph,``                            ``key``=``lambda` `item: item[``2``])` `        ``parent ``=` `[]``        ``rank ``=` `[]` `        ``# Create V subsets with single elements``        ``for` `node ``in` `range``(``self``.V):``            ``parent.append(node)``            ``rank.append(``0``)` `        ``# Number of edges to be taken is less than to V-1``        ``while` `e < ``self``.V ``-` `1``:` `            ``# Step 2: Pick the smallest edge and increment``            ``# the index for next iteration``            ``u, v, w ``=` `self``.graph[i]``            ``i ``=` `i ``+` `1``            ``x ``=` `self``.find(parent, u)``            ``y ``=` `self``.find(parent, v)` `            ``# If including this edge doesn't``            ``# cause cycle, then include it in result``            ``# and increment the index of result``            ``# for next edge``            ``if` `x !``=` `y:``                ``e ``=` `e ``+` `1``                ``result.append([u, v, w])``                ``self``.union(parent, rank, x, y)``            ``# Else discard the edge` `        ``minimumCost ``=` `0``        ``print``(``"Edges in the constructed MST"``)``        ``for` `u, v, weight ``in` `result:``            ``minimumCost ``+``=` `weight``            ``print``(``"%d -- %d == %d"` `%` `(u, v, weight))``        ``print``(``"Minimum Spanning Tree"``, minimumCost)`  `# Driver's code``if` `__name__ ``=``=` `'__main__'``:``    ``g ``=` `Graph(``4``)``    ``g.addEdge(``0``, ``1``, ``10``)``    ``g.addEdge(``0``, ``2``, ``6``)``    ``g.addEdge(``0``, ``3``, ``5``)``    ``g.addEdge(``1``, ``3``, ``15``)``    ``g.addEdge(``2``, ``3``, ``4``)` `    ``# Function call``    ``g.KruskalMST()` `# This code is contributed by Neelam Yadav``# Improved by James Graça-Jones`

## C#

 `// C# Code for the above approach` `using` `System;` `class` `Graph {` `    ``// A class to represent a graph edge``    ``class` `Edge : IComparable {``        ``public` `int` `src, dest, weight;` `        ``// Comparator function used for sorting edges``        ``// based on their weight``        ``public` `int` `CompareTo(Edge compareEdge)``        ``{``            ``return` `this``.weight - compareEdge.weight;``        ``}``    ``}` `    ``// A class to represent``    ``// a subset for union-find``    ``public` `class` `subset {``        ``public` `int` `parent, rank;``    ``};` `    ``int` `V, E; ``// V-> no. of vertices & E->no.of edges``    ``Edge[] edge; ``// collection of all edges` `    ``// Creates a graph with V vertices and E edges``    ``Graph(``int` `v, ``int` `e)``    ``{``        ``V = v;``        ``E = e;``        ``edge = ``new` `Edge[E];``        ``for` `(``int` `i = 0; i < e; ++i)``            ``edge[i] = ``new` `Edge();``    ``}` `    ``// A utility function to find set of an element i``    ``// (uses path compression technique)``    ``int` `find(subset[] subsets, ``int` `i)``    ``{``        ``// find root and make root as``        ``// parent of i (path compression)``        ``if` `(subsets[i].parent != i)``            ``subsets[i].parent``                ``= find(subsets, subsets[i].parent);` `        ``return` `subsets[i].parent;``    ``}` `    ``// A function that does union of``    ``// two sets of x and y (uses union by rank)``    ``void` `Union(subset[] subsets, ``int` `x, ``int` `y)``    ``{``        ``int` `xroot = find(subsets, x);``        ``int` `yroot = find(subsets, y);` `        ``// Attach smaller rank tree under root of``        ``// high rank tree (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;` `        ``// If ranks are same, then make one as root``        ``// and increment its rank by one``        ``else` `{``            ``subsets[yroot].parent = xroot;``            ``subsets[xroot].rank++;``        ``}``    ``}` `    ``// The main function to construct MST``    ``// using Kruskal's algorithm``    ``void` `KruskalMST()``    ``{``        ``// This will store the``        ``// resultant MST``        ``Edge[] result = ``new` `Edge[V];``        ``int` `e = 0; ``// An index variable, used for result[]``        ``int` `i``            ``= 0; ``// An index variable, used for sorted edges``        ``for` `(i = 0; i < V; ++i)``            ``result[i] = ``new` `Edge();` `        ``// Step 1: Sort all the edges in non-decreasing``        ``// order of their weight. If we are not allowed``        ``// to change the given graph, we can create``        ``// a copy of array of edges``        ``Array.Sort(edge);` `        ``// Allocate memory for creating V subsets``        ``subset[] subsets = ``new` `subset[V];``        ``for` `(i = 0; i < V; ++i)``            ``subsets[i] = ``new` `subset();` `        ``// Create V subsets with single elements``        ``for` `(``int` `v = 0; v < V; ++v) {``            ``subsets[v].parent = v;``            ``subsets[v].rank = 0;``        ``}` `        ``i = 0; ``// Index used to pick next edge` `        ``// Number of edges to be taken is equal to V-1``        ``while` `(e < V - 1) {``            ``// Step 2: Pick the smallest edge. And increment``            ``// the index for next iteration``            ``Edge next_edge = ``new` `Edge();``            ``next_edge = edge[i++];` `            ``int` `x = find(subsets, next_edge.src);``            ``int` `y = find(subsets, next_edge.dest);` `            ``// If including this edge doesn't cause cycle,``            ``// include it in result and increment the index``            ``// of result for next edge``            ``if` `(x != y) {``                ``result[e++] = next_edge;``                ``Union(subsets, x, y);``            ``}``            ``// Else discard the next_edge``        ``}` `        ``// print the contents of result[] to display``        ``// the built MST``        ``Console.WriteLine(``"Following are the edges in "``                          ``+ ``"the constructed MST"``);` `        ``int` `minimumCost = 0;``        ``for` `(i = 0; i < e; ++i) {``            ``Console.WriteLine(result[i].src + ``" -- "``                              ``+ result[i].dest``                              ``+ ``" == "` `+ result[i].weight);``            ``minimumCost += result[i].weight;``        ``}` `        ``Console.WriteLine(``"Minimum Cost Spanning Tree: "``                          ``+ minimumCost);``        ``Console.ReadLine();``    ``}` `    ``// Driver's Code``    ``public` `static` `void` `Main(String[] args)``    ``{` `        ``/* Let us create following weighted graph``                ``10``            ``0--------1``            ``| \ |``        ``6| 5\ |15``            ``| \ |``            ``2--------3``                ``4 */``        ``int` `V = 4; ``// Number of vertices in graph``        ``int` `E = 5; ``// Number of edges in graph``        ``Graph graph = ``new` `Graph(V, E);` `        ``// add edge 0-1``        ``graph.edge[0].src = 0;``        ``graph.edge[0].dest = 1;``        ``graph.edge[0].weight = 10;` `        ``// add edge 0-2``        ``graph.edge[1].src = 0;``        ``graph.edge[1].dest = 2;``        ``graph.edge[1].weight = 6;` `        ``// add edge 0-3``        ``graph.edge[2].src = 0;``        ``graph.edge[2].dest = 3;``        ``graph.edge[2].weight = 5;` `        ``// add edge 1-3``        ``graph.edge[3].src = 1;``        ``graph.edge[3].dest = 3;``        ``graph.edge[3].weight = 15;` `        ``// add edge 2-3``        ``graph.edge[4].src = 2;``        ``graph.edge[4].dest = 3;``        ``graph.edge[4].weight = 4;` `        ``// Function call``        ``graph.KruskalMST();``    ``}``}` `// This code is contributed by Aakash Hasija`

Output

```Following are the edges in the constructed MST
2 -- 3 == 4
0 -- 3 == 5
0 -- 1 == 10
Minimum Cost Spanning Tree: 19```

Time Complexity: O(ElogE) or O(ElogV), Sorting of edges takes O(ELogE) time. After sorting, we iterate through all edges and apply the find-union algorithm. The find and union operations can take at most O(LogV) time. So overall complexity is O(ELogE + ELogV) time. The value of E can be at most O(V2), so O(LogV) is O(LogE) the same. Therefore, the overall time complexity is O(ElogE) or O(ElogV)
Auxiliary Space: O(V + E), where V is the number of vertices and E is the number of edges in the graph