
本文介绍如何在 java 中高效存储图的节点与边关系,重点讲解基于邻接矩阵的实现方式,包括节点索引映射、连通性判断、边添加逻辑,并强调 equals/hashcode 重写与边界防护等关键实践。
在构建图(Graph)数据结构时,核心挑战之一是如何准确、高效地表示节点(Vertex)之间的连接关系(即边,Edge)。虽然 Map
✅ 推荐方案:布尔型邻接矩阵 + 节点数组索引
假设图中节点总数在初始化时已知(例如 n = 10),可采用以下结构:
public class Graph {
private final Node[] nodes; // 按索引顺序存储所有节点
private final boolean[][] adjacent; // adjacent[i][j] 表示 i→j 是否存在有向边
public Graph(int n) {
this.nodes = new Node[n];
this.adjacent = new boolean[n][n]; // 默认全为 false
}
// 注册节点(按顺序分配索引)
public void addNode(int index, Node node) {
if (index < 0 || index >= nodes.length) {
throw new IllegalArgumentException("Index out of bounds: " + index);
}
this.nodes[index] = node;
}
// 建立有向边:从节点 a 到节点 b
public void connect(int from, int to) {
validateIndex(from, to);
adjacent[from][to] = true;
}
// 查询两点是否连通(有向)
public boolean areConnected(int from, int to) {
validateIndex(from, to);
return adjacent[from][to];
}
// 辅助方法:通过节点对象查找其索引(需 Node 正确重写 equals & hashCode!)
public int indexOf(Node node) {
if (node == null) return -1;
for (int i = 0; i < nodes.length; i++) {
if (nodes[i] != null && nodes[i].equals(node)) {
return i;
}
}
return -1;
}
// 支持以 Node 对象为参数的连通性查询
public boolean areConnected(Node a, Node b) {
int idxA = indexOf(a);
int idxB = indexOf(b);
if (idxA == -1 || idxB == -1) return false;
return areConnected(idxA, idxB);
}
private void validateIndex(int... indices) {
for (int i : indices) {
if (i < 0 || i >= nodes.length) {
throw new IllegalArgumentException("Invalid node index: " + i);
}
}
}
}⚠️ 关键注意事项
-
必须重写 equals() 和 hashCode()
Node 类若未重写 equals(),默认使用引用比较(==),导致 indexOf() 永远无法匹配语义相同的节点。推荐基于 ID 或 data 字段实现:@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Node node = (Node) o; return ID == node.ID && Objects.equals(data, node.data); } @Override public int hashCode() { return Objects.hash(ID, data); } 邻接矩阵的扩展性
若节点数动态增长,可用 List- > 替代二维数组,但需自行维护行列一致性;若需存储权重(如距离、成本),可将 boolean[][] 升级为 int[][]、double[][] 或自定义对象数组。
有向 vs 无向图
上述实现默认为有向图。若需无向图,connect(a, b) 应同时设置 adjacent[a][b] = adjacent[b][a] = true。图形界面衔接提示
在 GUI 层(如 JavaFX),可将 nodes[] 绑定到 Circle 或 Label 列表,adjacent[][] 驱动 Line 的显示/隐藏,实现节点拖拽、连线高亮等交互效果。
综上,邻接矩阵以空间换时间,逻辑清晰、查询 O(1)、适合中小规模图及可视化场景。配合严谨的索引管理与对象语义比较,即可稳健支撑你的图编辑器开发目标。
立即学习“Java免费学习笔记(深入)”;








