基本的 BFS 和 DFS,以及基于 BFS 的无权图最短路径算法

BFS 基于队列实现,DFS 基于栈实现,是最基本的图算法,但是它们的扩展有很多实际用处。下面给出这两种图搜索的实现:

def bfs(graph, v):
	queue = [v]
	visited = set()
	visited.add(v)
	res = []
	while queue != []:
		temp = queue.pop(0)
		res.append(temp)
		for neighbor in graph[temp]:
			if neighbor not in visited:
				queue.append(neighbor)
				visited.add(neighbor)
	return res

def dfs(graph, v):
	stack = [v]
	visited = set()
	visited.add(v)
	res = []
	while stack != []:
		temp = stack.pop()
		res.append(temp)
		for neighbor in graph[temp]:
			if neighbor not in visited:
				stack.append(neighbor)
				visited.add(neighbor)
	return res

if __name__ == '__main__':
	g = {'A': ['B', 'C'],
		'B': ['A', 'C', 'D'],
		'C': ['A', 'D', 'E'],
		'D': ['B', 'C', 'E', 'F'],
		'E': ['C', 'D'],
		'F': ['D']}
	print(bfs(g, 'F'))
	print(dfs(g, 'F'))

这里使用了 Python 的 set 容器记录已经访问过的顶点。下面简单扩展一下 BFS,实现一个寻找无权图中任意两点最短路径的算法:

def shortestPath(graph, v, target):
	queue = [v]
	visited = set()
	visited.add(v)
	res = {}
	while queue != []:
		parent = queue.pop(0)
		for neighbor in graph[parent]:
			if neighbor not in visited:
				queue.append(neighbor)
				visited.add(neighbor)
				res[neighbor] = parent
	key = target
	path = [target]
	while key is not v:
		path.append(res[key])
		key = res[key]
	return path[::-1]

if __name__ == '__main__':
	g = {'A': ['B', 'C'],
		'B': ['A', 'C', 'D'],
		'C': ['A', 'D', 'E'],
		'D': ['B', 'C', 'E', 'F'],
		'E': ['C', 'D'],
		'F': ['D']}
	print(shortestPath(g, 'F', 'C'))

对于一个无权图来说,实际上从一点 BFS 到其他点的搜索路径就是这两点间的最短路径,只要使用一个映射(这里是一个字典)记录过程中每个顶点的 parent,最后逆向打印出来就可以了。

你可能感兴趣的:(Algorithm)