Prim’s Algorithm
Discover Prim’s algorithm for building a minimum spanning tree.
Prim’s algorithm is a well-known algorithm for finding minimum spanning trees. The algorithm in the form known today bears striking similarities with Dijkstra’s algorithm.
A tree-growing strategy
Prim’s algorithm starts with a vertex, and gradually extends this single vertex tree to a full-blown minimum spanning tree by adding one edge at a time.
As the subgraph, built by the algorithm, remains a tree after each edge addition, Prim’s algorithm is often thought of as a tree growing algorithm.
The crux of it
The idea is to build a subgraph of by adding an edge to it in every round such that remains a tree after each round.
Conceptually, in every round, the vertices of are regrouped as:
- Those in
- Those in , the complement of
We refer to an edge as a boundary-edge if it has one end-vertex in and the other in . For the example shown below, we show the boundary-edges as dotted, and the edges in are highlighted in red. Note how the edges in form a tree.
Here is how the algorithm works:
- An arbitrary vertex of is chosen as the root and placed in .
- At each subsequent step, we pick a boundary-edge of the smallest weight and add it to . Adding an edge to entails also adding its other end-vertex to .
This algorithm ensures that remains a tree after every round. Here is why:
- It remains connected after each round.
- It remains acyclic after each round.
Conclusion: Since, in each round, a new vertex becomes part of the tree , by the end of the execution, contains all vertices of the original graph and is, therefore, a spanning tree.
In fact, is guaranteed to be a minimum spanning tree, but we defer showing this for now.
A dry run
Let’s look at a visualization of how the algorithm picks the edges that form a minimum spanning tree.
Implementation details
Let’s drill down and see how to implement Prim’s algorithm.
Priority queue
Since in each round, we want to pick a minimum-weight boundary-edge, we could use a priority queue for the boundary-edges. However, each boundary-edge has exactly one end-vertex in . So, instead, we make the simpler decision to use the priority queue to keep the vertices in , such that each vertex has an attribute to store the weight of a minimum-weight boundary-edge incident on .
Note: The attribute also serves as the priority key of . If a vertex is extracted from the priority queue, it implies that the vertex has an incident boundary-edge of the smallest weight over all the boundary-edges incident on vertices in .
Vertices that are not in the priority queue are exactly the vertices in .
Implementing the tree
Instead of maintaining an explicit data structure for the tree ...