图(Graph)是由节点(也称为顶点)和连接这些节点的边组成的数据结构。图可以用来表示网络、道路系统、社交网络等各种结构。图可以是有向的(边有方向)或无向的(边没有方向),可以是加权的(边有权重)或非加权的。
下面是如何在Java中实现一个简单的无向图和执行基本操作的例子:
定义图的数据结构
首先定义图的基本结构。一个简单的方法是使用邻接表来表示图:
import java.util.*;
public class Graph {
private Map<Integer, List<Integer>> adjList; // 邻接表
public Graph() {
adjList = new HashMap<>();
}
// 添加顶点
public void addVertex(int v) {
adjList.putIfAbsent(v, new LinkedList<>());
}
// 添加边
public void addEdge(int v1, int v2) {
adjList.get(v1).add(v2);
adjList.get(v2).add(v1); // 因为是无向图,所以也要添加v2到v1的边
}
// 获取图的顶点
public Set<Integer> getVertices() {
return adjList.keySet();
}
// 获取与顶点相连的所有顶点(邻居)
public List<Integer> getAdjVertices(int v) {
return adjList.get(v);
}
// 打印图
public void printGraph() {
for (int v : adjList.keySet()) {
System.out.print("Vertex " + v + " is connected to: ");
for (int w : adjList.get(v)) {
System.out.print(w + " ");
}
System.out.println();
}
}
}
图的遍历
图的两种基本遍历方法是深度优先遍历(DFS)和广度优先遍历(BFS)。
深度优先遍历(DFS)
public void dfs(int start) {
Set<Integer> visited = new HashSet<>();
Stack<Integer> stack = new Stack<>();
stack.push(start);
while (!stack.isEmpty()) {
int vertex = stack.pop();
if (!visited.contains(vertex)) {
visited.add(vertex);
System.out.print(vertex + " ");
for (int v : getAdjVertices(vertex)) {
if (!visited.contains(v)) {
stack.push(v);
}
}
}
}
}
广度优先遍历(BFS)
public void bfs(int start) {
Set<Integer> visited = new HashSet<>();
Queue<Integer> queue = new LinkedList<>();
visited.add(start);
queue.add(start);
while (!queue.isEmpty()) {
int vertex = queue.poll();
System.out.print(vertex + " ");
for (int v : getAdjVertices(vertex)) {
if (!visited.contains(v)) {
visited.add(v);
queue.add(v);
}
}
}
}
使用图
创建一个图实例,并添加顶点和边,然后执行遍历:
public class Main {
public static void main(String[] args) {
Graph graph = new Graph();
// 向图中添加顶点
for (int i = 0; i < 6; i++) {
graph.addVertex(i);
}
// 向图中添加边
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 3);
graph.addEdge(1, 4);
graph.addEdge(2, 4);
graph.addEdge(3, 4);
graph.addEdge(3, 5);
graph.addEdge(4, 5);
// 打印图
graph.printGraph(); // 输出图的邻接表
// 执行深度优先遍历
System.out.print("DFS Traversal starting from vertex 0: ");
graph.dfs(0);
System.out.println();
// 执行广度优先遍历
System.out.print("BFS Traversal starting from vertex 0: ");
graph.bfs(0);
System.out.println();
}
}
总结
图是一种复杂且强大的数据结构,可用于模拟现实世界中的许多不同类型的关系。理解如何实现和操作图是计算机科学中的一个重要概念,它是许多算法的基础,如网络流、最短路径、拓扑排序和联通分量等。掌握图的基本操作,可以帮助你在处理更高级的问题时建立坚实的基础。在实际应用中,根据具体需求,你可能需要选择不同的图表示方式(如邻接表、邻接矩阵)和不同的图算法。