Articles

Prim's vs Kruskal's Algorithm: Minimum Spanning Trees

Prim's and Kruskal's both build a minimum spanning tree but grow it differently — one from a single node, the other by sorted edges. Here's how each works.

The Lycoris Team The Lycoris Team · · 5 min read
Handwritten graph and equations on a chalkboard

A minimum spanning tree (MST) is the cheapest set of edges that connects every node in a weighted graph with no cycles. Prim’s and Kruskal’s algorithms both find one, both run in roughly the same time complexity, and both are greedy — but they build the tree in opposite ways. Prim’s grows a single tree outward from one starting node; Kruskal’s assembles the tree from the graph’s cheapest edges regardless of where they sit.

What a spanning tree actually is

Given a connected, undirected graph with n nodes, a spanning tree is a subset of n - 1 edges that touches every node without forming a cycle. There are usually many possible spanning trees for a given graph — the minimum spanning tree is the one whose edge weights sum to the smallest total. MSTs show up anywhere you need to connect a set of points as cheaply as possible: laying network cable between offices, routing power distribution, or clustering data points by similarity.

Both algorithms rely on the same underlying fact, sometimes called the cut property: for any partition of the graph’s nodes into two groups, the cheapest edge crossing that partition must belong to some MST. That’s what makes a greedy approach provably optimal here, unlike many other optimization problems where greedy choices can lead you astray.

Prim’s algorithm: grow one tree

Prim’s starts at an arbitrary node and repeatedly adds the cheapest edge that connects a node already in the tree to a node outside it.

  1. Pick a starting node; mark it as “in the tree.”
  2. Look at every edge crossing the boundary between the tree and the rest of the graph.
  3. Add the cheapest such edge, pulling a new node into the tree.
  4. Repeat until every node is included.

The natural implementation uses a priority queue (typically a binary heap) keyed on the cheapest known edge to each node outside the tree. With a binary heap, Prim’s runs in O(E log V) time. It behaves a lot like Dijkstra’s algorithm in structure — both grow outward from a source using a priority queue — but Dijkstra’s tracks total path distance from the source, while Prim’s only tracks the cost of the single next edge.

Kruskal’s algorithm: sort and union

Kruskal’s ignores the notion of a single growing tree and instead works globally across all edges.

  1. Sort every edge in the graph by weight, ascending.
  2. Walk the sorted list. For each edge, add it to the MST unless it would create a cycle.
  3. Stop once you’ve added n - 1 edges.

The cycle check is the interesting part. Kruskal’s uses a union-find (disjoint set) structure to test, in near-constant time, whether the two endpoints of an edge are already connected through previously added edges. If they are, adding the edge would form a cycle, so it’s skipped. Sorting the edges dominates the running time, giving Kruskal’s the same O(E log E) complexity as Prim’s O(E log V) — the two are equivalent since E is bounded by V².

Comparing the two

Prim’sKruskal’s
ApproachGrows one connected tree outwardMerges disjoint components via sorted edges
Core structurePriority queueSorted edge list + union-find
Best forDense graphs (many edges relative to nodes)Sparse graphs (few edges relative to nodes)
Natural output orderTree expands from a fixed startEdges added in weight order, tree can form anywhere
Typical complexityO(E log V)O(E log E)

In practice, the difference in asymptotic complexity rarely matters — pick whichever is easier to implement with the tools at hand. Kruskal’s tends to be the more common textbook choice because a union-find structure is simple to write and reason about; Prim’s is a natural fit if you’re already comfortable with priority-queue-based graph traversal from Dijkstra’s or A*.

Why greedy works here but not everywhere

It’s worth pausing on why this greedy strategy is guaranteed to produce an optimal answer, since greedy algorithms often only produce a good answer rather than the best one. MST construction is one of the classic cases where a locally greedy choice is provably globally optimal, thanks to the cut property described above. Contrast this with problems like the traveling salesman problem, where greedily picking the nearest unvisited city at each step can lead to a badly suboptimal tour. If you’re studying greedy algorithms vs. dynamic programming, MST construction is a useful anchor example: it’s a case where the simpler, greedy approach is not just faster but actually correct.

Where MSTs show up in practice

  • Network design — minimizing the total cable, pipe, or trunk length needed to connect a set of physical locations.
  • Clustering — building an MST over a distance matrix and cutting its most expensive edges is a classic technique for single-linkage clustering.
  • Approximation algorithms — MSTs are a building block in approximation schemes for harder problems like the traveling salesman problem, since an optimal tour is always at least as expensive as the MST.
  • Circuit design — minimizing wire length when connecting components on a board.

Real-world variants often add constraints — a maximum degree per node, or multiple disconnected components that need to stay separate — that turn the clean MST problem into something considerably harder. But the base algorithms remain the starting point for reasoning about those variants.

The takeaway

Prim’s and Kruskal’s both exploit the same cut property to guarantee an optimal minimum spanning tree, but they get there differently: Prim’s grows one tree node by node using a priority queue, while Kruskal’s assembles the tree by walking globally sorted edges and using union-find to reject cycles. Choose Prim’s when the graph is dense and you’re already thinking in terms of priority queues; choose Kruskal’s when the graph is sparse or a union-find structure is the more natural fit for your data.

The Lycoris Team The Lycoris Team · · 4 min read

The Rope Data Structure: Editing Huge Strings Efficiently

A rope is a binary tree of string chunks that makes inserting, deleting, and slicing huge strings fast, which is why text editors use it over plain arrays.

#Computer Science #Data Structures #Algorithms
The Lycoris Team The Lycoris Team · · 4 min read

Memoization vs. Tabulation in Dynamic Programming

Memoization caches results top-down via recursion; tabulation builds a table bottom-up with loops. Same technique, opposite direction, different tradeoffs.

#Computer Science #Algorithms #Data Structures
The Lycoris Team The Lycoris Team · · 4 min read

Manacher's Algorithm Explained

Manacher's algorithm finds the longest palindromic substring in linear time by reusing symmetry from palindromes already found, avoiding redundant checks.

#Computer Science #Algorithms #Data Structures