Now that we can build the graph, we need to explore it. Breadth-first search (BFS) visits a start node, then all of its direct dependencies, then their dependencies, level by level. Package managers use this style of walk to answer "what does this package reach?" one ring at a time.
Implement bfs(start) returning the list of nodes in BFS order:
Use a queue (collections.deque is imported for you). Mark a node as seen when you enqueue it so it is not queued again.
g.add_edge("a", "b")
g.add_edge("a", "c")
g.add_edge("b", "d")
g.add_edge("c", "d")
g.add_edge("c", "e")
g.bfs("a") -> ["a", "b", "c", "d", "e"]
from collections import deque
class Graph:
def __init__(self):
self.adj = {}
def add_edge(self, u, v):
if u not in self.adj:
self.adj[u] = []
if v not in self.adj:
self.adj[v] = []
self.adj[u].append(v)
def nodes(self):
return list(self.adj.keys())
def neighbors(self, u):
return self.adj.get(u, [])
def bfs(self, start):
"""Return nodes reachable from start in breadth-first order.
Visit neighbors in insertion order and never repeat a node.
"""
# TODO: use a deque as a queue. Track seen nodes, append each node to
# the result when it is dequeued, and enqueue unseen neighbors.
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Now that we can build the graph, we need to explore it. Breadth-first search (BFS) visits a start node, then all of its direct dependencies, then their dependencies, level by level. Package managers use this style of walk to answer "what does this package reach?" one ring at a time.
Implement bfs(start) returning the list of nodes in BFS order:
Use a queue (collections.deque is imported for you). Mark a node as seen when you enqueue it so it is not queued again.
g.add_edge("a", "b")
g.add_edge("a", "c")
g.add_edge("b", "d")
g.add_edge("c", "d")
g.add_edge("c", "e")
g.bfs("a") -> ["a", "b", "c", "d", "e"]
Press Run Tests or ββ© to check your solution.