返回
深度探索图的遍历:广度优先与深度优先可视化实现
闲谈
2023-10-13 21:21:23
图是一种强大的数据结构,在许多计算机科学应用程序中都有广泛应用。遍历图涉及系统地访问图中的所有节点和边。本文将介绍两种经典的图遍历算法:广度优先搜索(BFS)和深度优先搜索(DFS),并提供使用 EasyX 库在 C++ 中实现这些算法的可视化演示。
广度优先搜索(BFS)
BFS 以逐层方式遍历图,从根节点开始,依次访问其所有相邻节点,然后再继续访问下一层。使用队列数据结构,BFS 确保优先遍历图的宽度,而不是深度。
void bfs(Graph& graph, int root) {
// 初始化队列并入队根节点
queue<int> q;
q.push(root);
// 标记已访问节点
vector<bool> visited(graph.size(), false);
visited[root] = true;
// 队列不为空,继续遍历
while (!q.empty()) {
// 出队队首节点
int u = q.front();
q.pop();
// 访问节点 u
// ...
// 遍历 u 的所有相邻节点
for (auto v : graph[u]) {
if (!visited[v]) {
// 如果 v 未被访问,则入队 v
q.push(v);
// 标记 v 为已访问
visited[v] = true;
}
}
}
}
深度优先搜索(DFS)
DFS 沿着图的深度进行遍历,从根节点开始,深入探索一条路径,直到遇到死路,然后再回溯到上一个未探索的分支。使用栈数据结构,DFS 优先遍历图的深度,而不是宽度。
void dfs(Graph& graph, int root) {
// 初始化栈并压入根节点
stack<int> s;
s.push(root);
// 标记已访问节点
vector<bool> visited(graph.size(), false);
visited[root] = true;
// 栈不为空,继续遍历
while (!s.empty()) {
// 弹出栈顶节点
int u = s.top();
s.pop();
// 访问节点 u
// ...
// 遍历 u 的所有相邻节点
for (auto v : graph[u]) {
if (!visited[v]) {
// 如果 v 未被访问,则压栈 v
s.push(v);
// 标记 v 为已访问
visited[v] = true;
}
}
}
}
可视化实现
使用 EasyX 库,我们可以创建交互式可视化界面,直观地显示图的遍历过程。用户可以通过单击按钮选择 BFS 或 DFS 算法,然后观察图中的节点和边的遍历顺序。
int main() {
// 创建 EasyX 窗口
initgraph(640, 480);
// 初始化图
Graph graph;
// ...
// 主循环
while (true) {
// 绘制图
draw_graph(graph);
// 等待用户输入
char key = getch();
// 根据用户输入执行 BFS 或 DFS
if (key == 'b') {
bfs(graph, 0);
} else if (key == 'd') {
dfs(graph, 0);
}
// 更新可视化
update_visualization();
}
// 销毁 EasyX 窗口
closegraph();
return 0;
}
总结
通过结合广度优先搜索和深度优先搜索的可视化实现,本文提供了对图遍历算法的深入理解。该代码不仅易于理解和修改,还提供了一个交互式可视化界面,让用户可以亲眼见证算法的运行过程。这种动手学习体验使读者能够加深对图遍历的理解和实际编程技能。