六讲贯通C++图的应用之二 DFS和BFS("C++图应用六讲之二:深度优先搜索DFS与广度优先搜索BFS详解")
原创
一、引言
在C++中,图是一种非常常见的数据结构,广泛应用于各种算法和问题求解中。图的遍历是图算法中的基础,深度优先搜索(DFS)和广度优先搜索(BFS)是两种最基本的图遍历算法。本文将详细介绍这两种算法的原理、实现及应用。
二、图的描述
在C++中,图通常可以用邻接矩阵或邻接表来描述。邻接矩阵适用于稠密图,而邻接表适用于稀疏图。以下是一个邻接表的单纯示例:
#include
#include
using namespace std;
class Graph {
int V; // 顶点数
vector
*adj; // 邻接表 public:
Graph(int V) {
this->V = V;
adj = new vector
[V]; }
void addEdge(int v, int w) {
adj[v].push_back(w);
adj[w].push_back(v); // 无向图
}
};
三、深度优先搜索(DFS)
深度优先搜索(DFS)是一种递归的图遍历算法。它从图的某个顶点开端,沿着一条路径深入到该路径的末端,然后回溯到之前的分叉点,继续沿着另一条路径深入。以下是DFS的基本步骤:
- 访问起始顶点,并标记为已访问。
- 递归地对所有未访问的邻接点进行深度优先搜索。
以下是DFS的C++实现:
void DFSUtil(int v, bool visited[]) {
visited[v] = true;
cout << v << " ";
for (int i = 0; i < adj[v].size(); i++) {
int neighbor = adj[v][i];
if (!visited[neighbor]) {
DFSUtil(neighbor, visited);
}
}
}
void DFS(int v) {
bool visited[V];
for (int i = 0; i < V; i++) {
visited[i] = false;
}
DFSUtil(v, visited);
}
四、广度优先搜索(BFS)
广度优先搜索(BFS)是一种基于队列的图遍历算法。它从图的某个顶点开端,首先访问该顶点的所有未访问的邻接点,然后再对这些邻接点进行同样的操作。以下是BFS的基本步骤:
- 将起始顶点放入队列。
- 当队列不为空时,从队列中取出一个顶点,并标记为已访问。
- 访问该顶点的所有未访问的邻接点,并将它们放入队列。
以下是BFS的C++实现:
void BFS(int s) {
bool visited[V];
for (int i = 0; i < V; i++) {
visited[i] = false;
}
list
queue; visited[s] = true;
queue.push_back(s);
while (!queue.empty()) {
s = queue.front();
cout << s << " ";
queue.pop_front();
for (int i = 0; i < adj[s].size(); i++) {
int neighbor = adj[s][i];
if (!visited[neighbor]) {
visited[neighbor] = true;
queue.push_back(neighbor);
}
}
}
}
五、DFS和BFS的应用
DFS和BFS在许多问题中都有广泛的应用,以下是一些常见的应用场景:
- 路径查找:寻找两个顶点之间的路径。
- 拓扑排序:对有向无环图进行排序。
- 连通性问题:判断图中两个顶点是否连通。
- 最小生成树:寻找连接所有顶点的最小权值边。
- 最短路径:寻找两个顶点之间的最短路径。
六、总结
深度优先搜索(DFS)和广度优先搜索(BFS)是图遍历的两种基本算法,它们在解决各种图相关问题时发挥着重要作用。通过本文的介绍,我们了解了它们的原理和C++实现。在实际应用中,我们需要基于问题的具体需求选择合适的遍历算法。
以上是一个基本的HTML文档,包含了深度优先搜索(DFS)和广度优先搜索(BFS)的原理、实现和应用场景。文档中使用了`