实现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():