📅  最后修改于: 2023-12-03 15:26:04.046000             🧑  作者: Mango
本题涉及到数据结构和算法的知识,要求学生能够理解树和图的基本概念,并具有深度优先搜索(DFS)和广度优先搜索(BFS)算法的实际应用能力。
给定一个无向连通图 $G=(V,E)$,其邻接矩阵表示为 $A$,其中 $A[i][j]=1$ 表示 $i$ 和 $j$ 之间有一条边,否则等于 $0$。假设 $G$ 的起点为节点 $0$,请编写一个程序,从 $G$ 的起点出发,遍历整张图,输出遍历过的所有节点的编号,要求使用 DFS 和 BFS 两种遍历算法。
深度优先搜索是一种基于栈实现的搜索算法。从起点开始,将其压入栈中,然后不断弹出栈顶元素并访问其相邻未被访问过的节点,将这些节点压入栈中。重复该过程直到栈为空,此时所有可达的节点均已访问。
DFS 可以看作是一个递归的过程,具体实现可参考下面的代码片段:
visited = set()
def dfs(graph, v):
visited.add(v)
print(v, end=' ')
for w in graph[v]:
if w not in visited:
dfs(graph, w)
其中,graph
表示图的邻接表表示,v
是当前访问的节点。visited
集合用于记录已访问的节点,防止重复遍历。
广度优先搜索是一种基于队列实现的搜索算法。从起点开始,将其入队,然后不断出队列首元素并访问其相邻未被访问过的节点,将这些节点入队。重复该过程直到队列为空,此时所有可达的节点均已访问。
BFS 可以看作是一个迭代的过程,具体实现可参考下面的代码片段:
from collections import deque
visited = set()
def bfs(graph, v):
queue = deque([v])
visited.add(v)
while queue:
v = queue.popleft()
print(v, end=' ')
for w in graph[v]:
if w not in visited:
visited.add(w)
queue.append(w)
其中,graph
表示图的邻接表表示,v
是起点。visited
集合用于记录已访问的节点,防止重复遍历。deque
是 Python 标准库中的双端队列实现,可以高效地支持队列操作。
以下是完整的 Python 代码,包含了 DFS 和 BFS 两种遍历算法的实现:
from collections import deque
def dfs(graph, v, visited):
visited.add(v)
print(v, end=' ')
for w in graph[v]:
if w not in visited:
dfs(graph, w, visited)
def bfs(graph, v, visited):
queue = deque([v])
visited.add(v)
while queue:
v = queue.popleft()
print(v, end=' ')
for w in graph[v]:
if w not in visited:
visited.add(w)
queue.append(w)
if __name__ == '__main__':
# 测试数据
A = [[0, 1, 1, 0, 0, 0],
[1, 0, 0, 1, 1, 0],
[1, 0, 0, 0, 1, 1],
[0, 1, 0, 0, 0, 1],
[0, 1, 1, 0, 0, 1],
[0, 0, 1, 1, 1, 0]]
graph = {}
for i in range(len(A)):
graph[i] = [j for j in range(len(A[i])) if A[i][j] == 1]
# DFS
visited = set()
dfs(graph, 0, visited)
print()
# BFS
visited = set()
bfs(graph, 0, visited)
print()
其中,graph
变量是图的邻接表表示,由邻接矩阵转换而来。测试数据中的邻接矩阵表示下图:
0
/ \
1 - 2
/ / \
3 4 - 5