深度优先搜索(Depth-First Search, DFS)是一种用于遍历或搜索树或图的算法。在Java中,可以使用递归或迭代的方法来实现DFS。下面我将分别介绍这两种实现方式。
递归实现
递归实现通常更为直观和简洁。在递归方法中,我们会使用一个栈(在递归调用栈中)来保存节点信息。
import java.util.*;
class Graph {
private int numVertices;
private LinkedList<Integer>[] adjLists;
// 构造函数
Graph(int vertices) {
numVertices = vertices;
adjLists = new LinkedList[vertices];
for (int i = 0; i < vertices; i++) {
adjLists[i] = new LinkedList<>();
}
}
// 添加边
void addEdge(int src, int dest) {
adjLists[src].add(dest);
}
// 递归的深度优先搜索(DFS)辅助函数
private void DFSUtil(int vertex, boolean[] visited) {
// 标记当前节点为已访问
visited[vertex] = true;
System.out.print(vertex + " ");
// 递归访问所有邻接节点
Iterator<Integer> iterator = adjLists[vertex].listIterator();
while (iterator.hasNext()) {
int adjVertex = iterator.next();
if (!visited[adjVertex]) {
DFSUtil(adjVertex, visited);
}
}
}
// 深度优先搜索算法
void DFS(int startVertex) {
// 标记所有节点为未访问
boolean[] visited = new boolean[numVertices];
// 从指定节点开始DFS
DFSUtil(startVertex, visited);
}
public static void main(String[] args) {
Graph graph = new Graph(5);
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 2);
graph.addEdge(2, 0);
graph.addEdge(2, 3);
graph.addEdge(3, 3);
System.out.println("深度优先搜索(DFS)遍历起始节点为 2:");
graph.DFS(2);
}
}
迭代实现
迭代实现DFS需要使用显式栈来保存节点信息。以下是一个使用栈实现DFS的例子:
import java.util.*;
class Graph {
private int numVertices;
private LinkedList<Integer>[] adjLists;
// 构造函数
Graph(int vertices) {
numVertices = vertices;
adjLists = new LinkedList[vertices];
for (int i = 0; i < vertices; i++) {
adjLists[i] = new LinkedList<>();
}
}
// 添加边
void addEdge(int src, int dest) {
adjLists[src].add(dest);
}
// 深度优先搜索算法(迭代方式)
void DFS(int startVertex) {
// 标记所有节点为未访问
boolean[] visited = new boolean[numVertices];
// 创建一个栈并压入起始节点
Stack<Integer> stack = new Stack<>();
stack.push(startVertex);
// 遍历栈,直到栈为空
while (!stack.isEmpty()) {
int vertex = stack.pop();
// 如果该节点未被访问
if (!visited[vertex]) {
// 标记为已访问并打印
visited[vertex] = true;
System.out.print(vertex + " ");
// 将所有邻接节点压入栈中
Iterator<Integer> iterator = adjLists[vertex].listIterator();
while (iterator.hasNext()) {
int adjVertex = iterator.next();
if (!visited[adjVertex]) {
stack.push(adjVertex);
}
}
}
}
}
public static void main(String[] args) {
Graph graph = new Graph(5);
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 2);
graph.addEdge(2, 0);
graph.addEdge(2, 3);
graph.addEdge(3, 3);
System.out.println("深度优先搜索(DFS)遍历起始节点为 2:");
graph.DFS(2);
}
}
总结
- 递归实现:代码更简洁,但对于非常深的图(例如递归深度非常大)可能会导致栈溢出。
- 迭代实现:使用显式栈来控制递归深度,更适合处理深图,但代码相对复杂一些。
你可以根据具体的需求选择合适的实现方式。