Kruskal's algorithm
Sort edges, add the lightest that does not form a cycle using union-find. Edge-centric, O(E lg V).
Kruskal: greedy connected components
Kruskal's algorithm is *edge-centric*: it processes edges globally, from lightest to heaviest, and keeps each one that joins two so-far-separate pieces of the graph. Concretely:
- Put every vertex in its own singleton set (
MAKE-SET), and set $A=\varnothing$. - Sort all edges by non-decreasing weight.
- Scan the sorted edges. For edge $(u,v)$: if
FIND-SET(u) != FIND-SET(v)(the endpoints are in different components), add $(u,v)$ to $A$ andUNION(u,v).
The disjoint-set forest (union by rank + path compression) makes the FIND/UNION test almost free — $O(E\,\alpha(V))$ total, where $\alpha$ is the inverse-Ackermann function ($\le 4$ for any conceivable input). So the sort dominates: $O(E\lg E)=O(E\lg V)$ overall (since $\lg E < \lg V^2 = 2\lg V$).
Why it is correct
When Kruskal considers $(u,v)$ with $u$ in component $C_1$, the cut $(C_1, V-C_1)$ respects $A$ (every $A$-edge lies *inside* a component). Because edges are processed in sorted order, $(u,v)$ is the lightest unprocessed edge crossing that cut — a *light edge*. By Corollary 21.2 it is safe. The FIND-SET(u) == FIND-SET(v) rejection is exactly the cycle check: same component means adding the edge would close a cycle.
Worked example
On the CLRS Fig 21.4 graph (9 vertices, 14 edges) the lightest safe edges are taken in order — weights 1, 2, 2, 4, 4, 7, 8, 9 — for a total MST weight of 37. The implementation below reuses the union-find structure from the data-structures module.