4.2 图的遍历:深度优先搜索、广度优先搜索
在我们了解了图的基本概念和表示方法后,接下来我们来讨论如何遍历图,也就是如何访问图中的所有顶点。在图论中,有两种主要的遍历策略:深度优先搜索(DFS)和广度优先搜索(BFS)。在这个部分,我们将详细介绍这两种方法。
深度优先搜索
深度优先搜索(DFS)是一种用于遍历或搜索树或图的算法。这种算法会尽可能深地搜索图的分支。当节点 v 的所有边都已被探寻过,搜索将回溯到发现节点 v 的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
import java.util.*;
public class DepthFirstSearch {
private boolean[] marked; // 标记数组,用于标记节点是否已被访问
private List<Integer>[] adjList; // 图的邻接表
public DepthFirstSearch(int numVertices) {
marked = new boolean[numVertices];
adjList = new ArrayList[numVertices];
for (int v = 0; v < numVertices; v++)
adjList[v] = new ArrayList<>();
}
public void addEdge(int v, int w) {
adjList[v].add(w);
adjList[w].add(v);
}
public void dfs(int v) {
marked[v] = true; // 标记节点 v 已被访问
System.out.println("Visiting vertex " + v);
for (int w : adjList[v]) {
if (!marked[w]) dfs(w); // 对于 v 的每个邻接节点 w,如果 w 未被访问,则递归调用 dfs(w)
}
}
}
广度优先搜索
广度优先搜索(BFS)是另一种用于遍历或搜索树或图的算法。相比之下,BFS 是沿着树的高度(对于树)或者图的"宽度"(即,元素的邻居们)遍历,而不像 DFS 那样尽可能地深入搜索。
import java.util.*;
public class BreadthFirstSearch {
private boolean[] marked; // 标记数组,用于标记节点是否已被访问
private List<Integer>[] adjList; // 图的邻接表
public BreadthFirstSearch(int numVertices) {
marked = new boolean[numVertices];
adjList = new ArrayList[numVertices];
for (int v = 0; v < numVertices; v++)
adjList[v] = new ArrayList<>();
}
public void addEdge(int v, int w) {
adjList[v].add(w);
adjList[w].add(v);
}
public void bfs(int s) {
Queue<Integer> queue = new LinkedList<>();
marked[s] = true; // 标记节点 s 已被访问
System.out.println("Visiting vertex " + s);
queue.add(s); // 将 s 添加到队列中
while (!queue.isEmpty()) {
int v = queue.poll(); // 从队列中取出一个节点
for (int w : adjList[v]) {
if (!marked[w]) { // 对于 v 的每个邻接节点 w,如果 w 未被访问
marked[w] = true; // 标记 w 已被访问
System.out.println("Visiting vertex " + w);
queue.add(w); // 将 w 添加到队列中
}
}
}
}
}
深度优先搜索和广度优先搜索都是图遍历的基本方法,理解他们的工作原理和应用场景,对于更深入地理解和使用图论非常重要。在后续的章节中,我们还将介绍一些基于深度优先搜索和广度优先搜索的图论算法。