import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
class Graph {
private int V; // 图中节点的数量
private List<List<Integer>> adj; // 邻接列表
public Graph(int v) {
V = v;
adj = new ArrayList<>(v);
for (int i = 0; i < v; ++i) {
adj.add(new ArrayList<>());
}
}
public void addEdge(int v, int w) {
adj.get(v).add(w);
}
public void dfs(int start) {
boolean[] visited = new boolean[V]; // 用于记录节点是否已访问
Stack<Integer> stack = new Stack<>();
// 将起始节点入栈
stack.push(start);
while (!stack.isEmpty()) {
int current = stack.pop();
// 如果当前节点未访问,则访问它并标记为已访问
if (!visited[current]) {
System.out.print(current + " ");
visited[current] = true;
}
// 将当前节点的未访问邻居入栈
for (int neighbor : adj.get(current)) {
if (!visited[neighbor]) {
stack.push(neighbor);
}
}
}
}
}
public class Main {
public static void main(String[] args) {
Graph g = new Graph(7); // 创建一个包含7个节点的图
// 添加图的边
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(1, 4);
g.addEdge(2, 5);
g.addEdge(2, 6);
// 从节点0出发的深度优先遍历结果将会是 :
// 0 2 6 5 1 4 3
// 后序优先(因为push栈,后进先出)
System.out.println("深度优先遍历结果:");
g.dfs(0); // 从节点0开始进行深度优先搜索
}
}
private List
是一个邻接列表(adjacency list)的数据结构,用于表示图中节点之间的关系。在邻接列表中,每个节点都与一个列表相关联,该列表存储与该节点直接相连的其他节点。> adj;
0 --- 1 --- 3
| | |
2 4 5
private List<List<Integer>> adj = new ArrayList<>();
// 添加节点0的邻居
adj.add(Arrays.asList(1, 2));
// 添加节点1的邻居
adj.add(Arrays.asList(0, 3, 4));
// 添加节点2的邻居
adj.add(Arrays.asList(0));
// 添加节点3的邻居
adj.add(Arrays.asList(1, 5));
// 添加节点4的邻居
adj.add(Arrays.asList(1));
// 添加节点5的邻居
adj.add(Arrays.asList(3));
for (int i = 0; i < v; ++i) {
adj.add(new ArrayList<>());
}
这段代码的 for 循环用于初始化邻接列表(adj)的数据结构。在构造函数 public Graph(int v)
中,参数 v 表示图中节点的数量,而 adj 是一个成员变量,用于存储图的邻接列表。
这个 for 循环的作用如下:
adj = new ArrayList<>(v)
:这一行代码创建了一个名为 adj 的 ArrayList,其大小初始化为 v,也就是图中节点的数量。这个 ArrayList 是用来存储邻接列表的,每个列表对应图中的一个节点。
for (int i = 0; i < v; ++i)
:这是一个循环,它从 0 开始迭代,一直到 v - 1。在每次迭代中,它执行以下操作:
adj.add(new ArrayList<>())
:这一行代码在 adj 列表中添加一个新的空 ArrayList。这个 ArrayList 用于存储与图中节点 i 相邻的其他节点。因此,整个循环的目的是为每个图中的节点创建一个对应的空邻接列表,以便稍后将节点的邻居添加到相应的列表中。这是构建邻接列表数据结构的初始化步骤,为后续的图操作做好了准备。
adj.get(current)
返回的是一个列表类型,具体来说是List
类型的列表。在邻接列表 adj
中,每个节点的邻居信息都以整数的形式存储在这个列表中。
所以,adj.get(current)
表示获取邻接列表 adj
中索引为 current
的位置上存储的整数列表,这个列表包含了与节点 current
直接相连的邻居节点的索引。因此,返回的类型是 List
,其中 Integer
表示整数类型。这个列表包含了与当前节点相邻的其他节点的索引信息。
public void addEdge(int v, int w)
方法的
public void addEdge(int v, int w) {
adj.get(v).add(w);
}
作用是将一条有向边从节点 v
指向节点 w
添加到图的邻接列表中。在这个深度优先搜索(DFS)的图类中,邻接列表 adj
用于存储节点之间的关系。
具体来说,这个方法完成以下操作:
adj.get(v)
获取节点 v
对应的邻居列表。w
添加到 v
的邻居列表中,表示节点 v
与节点 w
有一条有向边。这个方法是用来构建图的结构的,通过多次调用 addEdge
方法,可以将图的边逐一添加到邻接列表中,从而建立图的连接关系。
例如,在前面提供的示例中,以下代码段添加了图中的边:
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(1, 4);
g.addEdge(2, 5);
g.addEdge(2, 6);
这些方法调用将节点之间的有向边添加到了图的邻接列表中,从而定义了图的结构。