(一)实验目的
本次实验的目的是深入理解深度优先搜索(DFS)算法的原理和执行过程。通过使用 Python 的 networkx 库构建复杂图结构,并对其进行 DFS 遍历,同时利用 matplotlib 库将遍历过程可视化展示,从而更直观地掌握 DFS 算法在图中的应用。
(二)实验内容
- 构建复杂图结构
节点定义:设计一个包含多个节点的集合,本实验采用大写字母(如 A - Z)来代表不同节点,每个节点具有唯一性,可用于后续在图结构中标识特定位置或元素。例如,计划构建一个包含 10 个节点的图,节点分别为 A, B, C, D, E, F, G, H, I, J。
边关系设定:基于实际需求或特定拓扑结构要求,确定节点之间的连接关系,即边。边的定义需明确连接的两个节点,如 (A, B) 表示节点 A 与节点 B 之间存在连接。同时,需考虑图的类型,本次实验构建无向图,意味着 (A, B) 和 (B, A) 代表同一条边。例如,构建一个具有复杂连接关系的图,包含边 (A, B), (A, C), (B, D), (C, D), (D, E), (E, F), (F, G), (G, H), (H, I), (I, J), (J, A) 等,这些边共同构成了一个具备一定连通性和复杂度的图结构。
- 深度优先搜索算法实现
访问记录集合:创建一个空集合,用于记录在 DFS 遍历过程中已经访问过的节点。该集合能够确保每个节点在遍历中仅被访问一次,避免重复操作,提升算法效率。
待访问节点栈:构建一个栈结构,并将指定的起始节点放入栈中。栈是 DFS 算法实现的关键数据结构,它决定了节点的访问顺序,符合深度优先的原则,即优先沿着一条路径尽可能深地探索。
核心遍历逻辑
节点弹出与判断:进入循环,只要栈不为空,就从栈中弹出一个节点。随后检查该节点是否已存在于访问记录集合中。若节点未被访问过,则继续后续操作;若已访问,则直接进入下一轮循环,从栈中弹出下一个节点。
节点处理与邻接节点入栈:对于未访问过的节点,将其添加到访问记录集合中,以标记该节点已被访问。接着,获取该节点的所有邻接节点,按照特定顺序(如字母顺序倒序,以确保实验结果的可重复性和一致性)将未访问过的邻接节点依次压入栈中。这样,算法会沿着当前节点的邻接节点继续深入探索,直到无法继续深入(即当前节点的所有邻接节点都已被访问),然后回溯到上一层节点,继续探索其他未访问路径。
- DFS 过程可视化
初始图绘制:利用可视化工具,将构建好的图结构以直观的图形形式展示出来。在初始状态下,所有节点以统一的样式(如相同颜色、形状)呈现,边也以常规方式连接各个节点,让使用者能够清晰看到图的整体拓扑结构。以下是遍历过程动态展示:
节点状态更新:在 DFS 遍历过程中,每当访问到一个新节点,就改变该节点在可视化图形中的显示样式,如将节点颜色变为红色,以突出显示当前正在访问的节点。
图形更新与暂停:每次更新节点状态后,刷新可视化图形,让使用者能够实时看到节点的访问顺序。同时,在每次更新后设置一个短暂的暂停时间(如 2 秒),以便使用者有足够时间观察图形变化,理解 DFS 算法的执行过程。随着遍历的持续进行,整个图中节点的颜色会逐步发生变化,清晰地展示出 DFS 算法如何从起始节点开始,沿着不同路径深度优先地访问各个节点,直至遍历完所有可达节点。
(三)实验思路
流程图:
(四)伪代码
function create_graph():
G = 创建一个空图
nodes = ["A", "B", "C", ..., "J"]
将 nodes 添加到 G 中
edges = [("A", "B"), ("A", "C"), ..., ("J", "A")]
将 edges 添加到 G 中
return G
function dfs_visualize(G, start_node):
visited = 空集合
stack = [start_node]
pos = 图 G 的布局
开启交互模式
绘制图 G 的初始状态
暂停 2 秒
while stack 不为空:
node = 从 stack 中弹出一个节点
if node 不在 visited 中:
将 node 添加到 visited 中
打印 "Visiting node: " + node
清除之前的高亮显示
重新绘制图 G
高亮显示当前节点 node
暂停 2 秒
neighbors = 节点 node 的所有邻接节点
对 neighbors 进行降序排序
for neighbor in neighbors:
if neighbor 不在 visited 中:
将 neighbor 添加到 stack 中
关闭交互模式
显示最终图
main:
G = create_graph()
start_node = "A"
dfs_visualize(G, start_node)
(五)实验结果
当程序运行到nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray', ax=ax) 这一步并显示图形时,这是图的初始状态。此时会看到一个由节点 A 到 J 组成的图,所有节点都是浅蓝色,边是灰色,并且每个节点都有相应的标签显示其字母名称。节点的布局是由 nx.spring_layout(G) 生成的。这个状态展示了要进行 DFS 操作的图的基本结构。
每次访问一个新节点时,该节点会被高亮显示为红色,并且在控制台会打印出当前访问的节点。
该程序运行的最终窗口会停留在遍历结束后的状态。