如何跟踪广度优先搜索的路径,如以下示例所示:
如果搜索key 11,则返回连接1到11 的 最短 列表。
11
[1, 4, 7, 11]
您应该先查看http://en.wikipedia.org/wiki/Breadth- first_search。
下面是一个快速实现,其中我使用了一个列表列表来表示路径队列。
# graph is in adjacent list representation graph = { '1': ['2', '3', '4'], '2': ['5', '6'], '5': ['9', '10'], '4': ['7', '8'], '7': ['11', '12'] } def bfs(graph, start, end): # maintain a queue of paths queue = [] # push the first path into the queue queue.append([start]) while queue: # get the first path from the queue path = queue.pop(0) # get the last node from the path node = path[-1] # path found if node == end: return path # enumerate all adjacent nodes, construct a new path and push it into the queue for adjacent in graph.get(node, []): new_path = list(path) new_path.append(adjacent) queue.append(new_path) print bfs(graph, '1', '11')
另一种方法是维护从每个节点到其父节点的映射,并在检查相邻节点时记录其父节点。搜索完成后,只需根据父映射进行回溯即可。
graph = { '1': ['2', '3', '4'], '2': ['5', '6'], '5': ['9', '10'], '4': ['7', '8'], '7': ['11', '12'] } def backtrace(parent, start, end): path = [end] while path[-1] != start: path.append(parent[path[-1]]) path.reverse() return path def bfs(graph, start, end): parent = {} queue = [] queue.append(start) while queue: node = queue.pop(0) if node == end: return backtrace(parent, start, end) for adjacent in graph.get(node, []): if node not in queue : parent[adjacent] = node # <<<<< record its parent queue.append(adjacent) print bfs(graph, '1', '11')
上面的代码基于没有循环的假设。