Minimum Spanning Tree Prim's Algorithm in DSA Python - Time & Space Complexity
We want to understand how the time needed to find the minimum spanning tree using Prim's algorithm grows as the graph size increases.
Specifically, how the number of nodes and edges affects the work done.
Analyze the time complexity of the following Prim's algorithm implementation.
import heapq
def prim(graph, start):
mst = []
visited = set([start])
edges = [(cost, start, to) for to, cost in graph[start].items()]
heapq.heapify(edges)
while edges:
cost, frm, to = heapq.heappop(edges)
if to not in visited:
visited.add(to)
mst.append((frm, to, cost))
for to_next, cost_next in graph[to].items():
if to_next not in visited:
heapq.heappush(edges, (cost_next, to, to_next))
return mst
This code builds a minimum spanning tree by always choosing the smallest edge connecting visited nodes to unvisited nodes.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Extracting the smallest edge from the priority queue and adding new edges to it.
- How many times: Each edge is pushed and popped at most once, so operations repeat roughly proportional to the number of edges.
As the number of nodes (n) and edges (e) grow, the number of operations grows mainly with edges.
| Input Size (n, e) | Approx. Operations |
|---|---|
| 10 nodes, 15 edges | About 15 heap push/pop operations |
| 100 nodes, 200 edges | About 200 heap push/pop operations |
| 1000 nodes, 5000 edges | About 5000 heap push/pop operations |
Pattern observation: The work grows roughly with the number of edges, since each edge is processed once.
Time Complexity: O(e log n)
This means the time grows with the number of edges times the cost of managing the priority queue of nodes, which depends on the number of nodes.
[X] Wrong: "Prim's algorithm always runs in O(n²) time because it checks all nodes repeatedly."
[OK] Correct: Using a priority queue, Prim's algorithm processes edges efficiently, so the time depends on edges and log of nodes, not just nodes squared.
Understanding Prim's time complexity helps you explain how graph algorithms scale and why data structures like heaps matter, a key skill in interviews.
"What if we used a simple array instead of a priority queue to select edges? How would the time complexity change?"
Practice
Solution
Step 1: Understand Prim's algorithm purpose
Prim's algorithm builds a tree connecting all vertices with minimum total edge weight.Step 2: Compare with other graph algorithms
Shortest path, cycle detection, and topological sort serve different purposes than Prim's.Final Answer:
To find the minimum spanning tree connecting all vertices with the least total edge weight -> Option CQuick Check:
Prim's algorithm = Minimum Spanning Tree [OK]
- Confusing Prim's with Dijkstra's shortest path
- Thinking it detects cycles
- Mixing it with topological sorting
Solution
Step 1: Identify the need for selecting minimum edge
Prim's algorithm repeatedly selects the edge with the smallest weight.Step 2: Choose data structure for efficient minimum extraction
Priority Queue (heapq) allows efficient extraction of the smallest element.Final Answer:
Priority Queue (heapq) -> Option BQuick Check:
Minimum edge selection = Priority Queue [OK]
- Using list and scanning all edges each time
- Using queue which is FIFO, not minimum-based
- Using dictionary which doesn't order by weight
graph = {
0: [(1, 2), (3, 6)],
1: [(0, 2), (2, 3), (3, 8), (4, 5)],
2: [(1, 3), (4, 7)],
3: [(0, 6), (1, 8), (4, 9)],
4: [(1, 5), (2, 7), (3, 9)]
}
import heapq
def prim(graph, start=0):
mst = []
visited = set([start])
edges = [(weight, start, to) for to, weight in graph[start]]
heapq.heapify(edges)
while edges:
weight, frm, to = heapq.heappop(edges)
if to not in visited:
visited.add(to)
mst.append((frm, to, weight))
for to_next, w in graph[to]:
if to_next not in visited:
heapq.heappush(edges, (w, to, to_next))
return mst
print(prim(graph))Solution
Step 1: Start from vertex 0 and add edges
Edges from 0: (0-1,2), (0-3,6). Choose smallest: (0-1,2).Step 2: Add edges from vertex 1 and pick next smallest
From 1: (1-2,3), (1-3,8), (1-4,5). Next smallest edge overall is (1-2,3).Step 3: Continue adding edges and selecting minimum
Next edges: (1-4,5), (0-3,6). Choose (1-4,5) then (0-3,6).Final Answer:
[(0, 1, 2), (1, 2, 3), (1, 4, 5), (0, 3, 6)] -> Option AQuick Check:
Edges chosen in ascending weight order form MST [OK]
- Choosing edges with higher weight first
- Adding edges that create cycles
- Not updating visited vertices correctly
def prim_bug(graph, start=0):
mst = []
visited = set()
edges = [(0, start, start)]
while edges:
weight, frm, to = edges.pop()
if to not in visited:
visited.add(to)
if frm != to:
mst.append((frm, to, weight))
for to_next, w in graph[to]:
if to_next not in visited:
edges.append((w, to, to_next))
return mstSolution
Step 1: Check how edges are selected
Edges are popped from a list using pop(), which removes the last element, not the smallest weight.Step 2: Understand Prim's requirement for minimum edge selection
Prim's requires selecting the edge with the smallest weight each time, which needs a priority queue (heap).Final Answer:
Using list pop() instead of priority queue causes wrong edge selection order -> Option DQuick Check:
Edge selection order must be by minimum weight [OK]
- Using list pop() instead of heapq.heappop()
- Not initializing visited with start vertex
- Appending edges incorrectly
0-1: 4, 0-2: 3, 1-2: 1, 1-3: 2, 2-3: 4, 3-4: 2, 4-5: 6Using Prim's algorithm starting at vertex 0, what is the total weight of the minimum spanning tree?
Solution
Step 1: Start from vertex 0 and pick smallest edges
Edges from 0: (0-2,3), (0-1,4). Choose (0-2,3).Step 2: Add edges from visited vertices and pick smallest
Visited: {0,2}. Edges: (2-1,1), (0-1,4), (2-3,4). Choose (2-1,1).Step 3: Continue adding edges
Visited: {0,1,2}. Edges: (1-3,2), (0-1,4), (2-3,4). Choose (1-3,2).Step 4: Add edges from 3
Visited: {0,1,2,3}. Edges: (3-4,2), (2-3,4), (0-1,4). Choose (3-4,2).Step 5: Add edges from 4
Visited: {0,1,2,3,4}. Edges: (4-5,6), (2-3,4), (0-1,4). Choose (4-5,6).Step 6: Calculate total weight
Edges chosen: 3 + 1 + 2 + 2 + 6 = 14.Final Answer:
14 -> Option AQuick Check:
Sum of MST edges = 14 [OK]
- Including edges that form cycles
- Skipping the smallest connecting edge
- Miscounting total weight
Ready to prove it?
Pass the test and this pattern moves unknown
