实现DFS:Java使用的数据结构
深度优先搜索(DFS,Depth-First Search)是一种用于遍历或搜索树或图的算法。它通过访问一个节点,然后递归地访问它的子节点,直到到达最深处,然后回溯到上一个节点,继续访问下一个子节点。在本文中,我们将探讨在Java中实现DFS算法时使用的数据结构。
栈(Stack)
在DFS算法中,我们需要使用栈数据结构来保存需要访问的节点。栈是一种具有后进先出(LIFO)特性的数据结构,我们可以使用Java的内置类java.util.Stack
来实现栈。
import java.util.Stack;
public class DFS {
public static void dfs(Graph graph, int startNode) {
Stack<Integer> stack = new Stack<>();
boolean[] visited = new boolean[graph.getNumNodes()];
stack.push(startNode);
visited[startNode] = true;
while (!stack.isEmpty()) {
int currentNode = stack.pop();
System.out.println("Visiting node: " + currentNode);
for (int neighbor : graph.getNeighbors(currentNode)) {
if (!visited[neighbor]) {
stack.push(neighbor);
visited[neighbor] = true;
}
}
}
}
}
上面的代码展示了一个简单的DFS算法实现。我们使用一个栈来保存需要访问的节点,同时使用一个布尔数组来记录节点是否已被访问。我们从起始节点开始,将其入栈并标记为已访问。然后我们进入一个循环,直到栈为空。在循环中,我们弹出栈顶的节点,访问它,并将其未访问的邻居节点入栈。
图(Graph)
在DFS算法中,我们需要一个图数据结构来表示节点之间的关系。图可以以多种方式表示,常见的有邻接矩阵和邻接表。我们将使用邻接表的方式来实现图。
import java.util.ArrayList;
import java.util.List;
public class Graph {
private int numNodes;
private List<List<Integer>> adjacencyList;
public Graph(int numNodes) {
this.numNodes = numNodes;
this.adjacencyList = new ArrayList<>();
for (int i = 0; i < numNodes; i++) {
this.adjacencyList.add(new ArrayList<>());
}
}
public void addEdge(int node1, int node2) {
this.adjacencyList.get(node1).add(node2);
this.adjacencyList.get(node2).add(node1);
}
public List<Integer> getNeighbors(int node) {
return this.adjacencyList.get(node);
}
public int getNumNodes() {
return this.numNodes;
}
}
上面的代码展示了一个简单的邻接表实现的图数据结构。我们使用一个List来保存每个节点的邻居节点列表。在构造函数中,我们初始化邻接表,并在添加边时更新对应节点的邻居列表。
示例
假设我们有以下的图:
0---1
| /
| /
2---3
我们可以使用上述的DFS算法和图数据结构来遍历这个图。
public class Main {
public static void main(String[] args) {
Graph graph = new Graph(4);
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 2);
graph.addEdge(2, 3);
DFS.dfs(graph, 0);
}
}
运行上述代码,我们可以得到以下输出:
Visiting node: 0
Visiting node: 2
Visiting node: 3
Visiting node: 1
这表示我们按照深度优先搜索的顺序遍历了图中的节点。
类图
下面是DFS算法中使用的类的类图:
classDiagram
class DFS {
+dfs(Graph graph, int startNode)
}
class Graph {
-numNodes: int
-adjacencyList: List<List<Integer>>
+Graph(numNodes: int)
+addEdge(node1: int, node2: int)
+getNeighbors(node: int): List<Integer>
+getNumNodes(): int
}
class Stack<E> {
+push(item: E)
+pop(): E
+isEmpty():