Hello! In our last lesson, we built a solid foundation by exploring the Union-Find data structure, including its powerful optimizations like union by rank and path compression. We concluded by noting its incredible efficiency makes it a perfect tool for detecting cycles in graphs.
Today, we'll put that tool to work. Our goal is to apply Kruskal's algorithm using union-find to find a Minimum Spanning Tree (MST). A Minimum Spanning Tree is a subset of the edges of a connected, edge-weighted graph that connects all the vertices together, without any cycles and with the minimum possible total edge weight.
This lesson will show you how a simple, greedy strategy, powered by the efficient Union-Find data structure, can solve this fundamental graph problem.
1. The Greedy Strategy of Kruskal's Algorithm
Kruskal's algorithm is a classic example of a greedy algorithm. This means that at each step, it makes the choice that seems best at that moment, without considering the future consequences of that choice. For Kruskal's, the greedy choice is simple: always pick the available edge with the smallest weight.
The overall process is as follows:
- Create a list of all edges in the graph and sort them in non-decreasing order of their weights.
- Initialize a new graph, the MST, with all the vertices of the original graph but no edges.
- Iterate through the sorted edges. For each edge
(u, v):- Check if adding this edge to the MST would form a cycle.
- If it does not form a cycle, add the edge to the MST.
- If it does form a cycle, discard the edge and move to the next one.
- The algorithm terminates when the MST has edges, where is the number of vertices.
To see this high-level process in action, let's watch a short introductory video.
Kruskal's Algorithm Visually Explained | Disjoint Sets | Union By Rank | Path Compression
The video 'Kruskal's Algorithm Visually Explained' by ByteQuest provides a quick, clear demonstration of the algorithm's core idea.
Watch the first minute (00:00 - 01:14). Focus on how the algorithm sorts all edges first and then iteratively adds the smallest-weight edges, skipping any that would create a loop.
This greedy approach of picking the "cheapest" edge at every step feels intuitive, but the crucial part is knowing how to efficiently detect whether adding an edge creates a cycle. This is where your knowledge from the previous lesson comes into play.
2. Detecting Cycles with Union-Find
As we just saw, the main challenge in Kruskal's algorithm is cycle detection. Trying to traverse the graph to check for a cycle after adding each edge would be very inefficient. Instead, we can use the Union-Find data structure to track the connected components of the growing MST.
Here’s how it works:
- Initialization: We begin by placing each vertex in its own set using the
make_set()operation. This represents a forest of trees, each containing a single vertex. - Iteration: As we process each edge
(u, v)from our sorted list:- We use
find(u)andfind(v)to determine the representatives (roots) of the sets containinguandv. - If
find(u)is the same asfind(v), it meansuandvare already in the same connected component. Adding the edge(u, v)would create a cycle. Therefore, we discard this edge. - If
find(u)is different fromfind(v), the vertices are in different components. Adding the edge(u, v)will not create a cycle. So, we add this edge to our MST and merge the two components by callingunion(u, v).
- We use
Thanks to the path compression and union by rank optimizations we studied, the find and union operations are nearly constant time. This makes the cycle-detection part of the algorithm extremely fast.
Let's watch a detailed walkthrough that visualizes how these components (or "groups") are managed using Union-Find.
Union Find Kruskal's Algorithm
The video 'Union Find Kruskal's Algorithm' by WilliamFiset provides an excellent, step-by-step visualization of the algorithm. Pay close attention to how the colored groups merge.
Watch from 01:00 to 05:36. The first part (until 01:49) outlines the steps. The main walkthrough (from 01:49) shows how edges are considered and how the 'groups' of vertices are merged using the union operation, or how edges are discarded if they connect vertices within the same group.
3. A Complete Example and Pseudocode
To solidify your understanding, let's review the algorithm's structure with pseudocode and a static visual example.
The Wikipedia article on Kruskal's algorithm provides a concise summary.
Kruskal's algorithm - Wikipedia
The Wikipedia page for Kruskal's algorithm offers clear pseudocode that explicitly references the Union-Find operations we've learned.
Read the 'Algorithm' and 'Pseudocode' sections. Notice how the pseudocode directly translates the steps we discussed, using MAKE-SET, FIND-SET, and UNION to manage the forest of trees.
The pseudocode looks like this:
function Kruskal(Graph G) is
F := ∅ // F will be the set of edges in the MST
for each vertex v in G.Vertices do
MAKE-SET(v)
Sort G.Edges into a list, ordered by increasing weight
for each edge {u, v} in the sorted list do
if FIND-SET(u) ≠FIND-SET(v) then
F := F ∪ { {u, v} }
UNION(FIND-SET(u), FIND-SET(v)) // Or simply UNION(u, v)
return F
The image below provides another excellent step-by-step trace of the algorithm. On the right, you see the list of edges sorted by weight. The diagrams show which edge is being considered (red), which edges are already in the MST (black), and which are discarded because they form a cycle.

4. Complexity Analysis
Your preference for understanding the "why" includes analyzing performance. Let's break down the time complexity of Kruskal's algorithm. The main operations are:
- Sorting Edges: Sorting edges takes time using a standard comparison-based sort like merge sort or quicksort.
- Initializing Union-Find: Creating disjoint sets takes time.
- Iterating and Processing Edges: We iterate through all edges. For each edge, we perform two
findoperations and at most oneunionoperation. With the optimizations from our last lesson, these operations have an amortized time complexity of , where is the extremely slow-growing inverse Ackermann function. The total time for this step is therefore .
The overall time complexity is the sum of these parts: .
Since grows faster than , the bottleneck is the initial edge sort.
Thus, the final time complexity of Kruskal's algorithm is . This is often written as because in a connected graph, is at least , and for dense graphs, is proportional to .
5. Implementation Example
As a software engineer, you may find it helpful to see how these concepts translate into code. The following resource provides a clean Java implementation of Kruskal's algorithm, complete with the UnionFind class we've discussed.
Finding Minimum Spanning Trees with Kruskal's Algorithm in Java
The article 'Finding Minimum Spanning Trees with Kruskal's Algorithm in Java' by Alexander Obregon provides a full, well-commented implementation.
Please read the sections 'Data Structures Used' and 'Java Implementation Example'. Pay attention to how the Edge class implements Comparable to allow sorting, how the UnionFind class is structured, and how the main findMST method orchestrates the algorithm.
This implementation brings together the Edge representation, the optimized UnionFind data structure, and the main greedy logic into a cohesive solution, showing a practical application of the theory.
Conclusion
In this lesson, we have successfully applied our knowledge of the Union-Find data structure to implement Kruskal's algorithm for finding a Minimum Spanning Tree.
Key Takeaways:
- Kruskal's algorithm is a greedy algorithm that builds an MST by iteratively adding the lowest-weight edge that does not form a cycle.
- The core of its efficiency lies in using a Union-Find (or DSU) data structure to track connected components and detect cycles in nearly constant time.
- The algorithm first sorts all edges by weight, which is the most computationally expensive step.
- The overall time complexity is dominated by sorting, resulting in .
Preview of the Next Lesson:
Kruskal's algorithm is an "edge-centric" approach. What if we took a "vertex-centric" approach instead? In the next lesson, we will explore Prim's algorithm, another classic greedy algorithm for finding MSTs. It works by growing a single tree from an arbitrary starting vertex. We will compare its strategy and performance with Kruskal's, using a different data structure—the priority queue—as its core engine.