
本文介绍一种基于邻接矩阵的图结构实现方式,通过二维布尔数组配合节点索引映射,高效、清晰地存储节点对(边)关系,并支持快速查询和连接操作,适用于需可视化展示的图应用。
在构建可交互的图形化图应用(如节点拖拽、连线可视化)时,底层数据结构的合理性直接决定性能与扩展性。虽然Map
✅ 推荐方案:索引化邻接矩阵
核心思想是将每个Node绑定唯一整数索引(而非依赖对象引用比较),用boolean[n][n]二维数组表示有向边存在性:
public class Graph {
private final Node[] nodes;
private final boolean[][] adjacent;
public Graph(int capacity) {
this.nodes = new Node[capacity];
this.adjacent = new boolean[capacity][capacity];
}
// 注册节点(分配索引)
public int addNode(Node node) {
for (int i = 0; i < nodes.length; i++) {
if (nodes[i] == null) {
nodes[i] = node;
return i; // 返回分配的索引
}
}
throw new IllegalStateException("Graph is full");
}
// 建立有向边:from → to
public void connect(int fromIndex, int toIndex) {
validateIndex(fromIndex);
validateIndex(toIndex);
adjacent[fromIndex][toIndex] = true;
}
// 查询两点是否连通(有向)
public boolean areConnected(int fromIndex, int toIndex) {
validateIndex(fromIndex);
validateIndex(toIndex);
return adjacent[fromIndex][toIndex];
}
// 安全的节点对象查询(需重写 equals & hashCode!)
public int indexOf(Node target) {
if (target == null) return -1;
for (int i = 0; i < nodes.length; i++) {
if (nodes[i] != null && nodes[i].equals(target)) {
return i;
}
}
return -1;
}
private void validateIndex(int index) {
if (index < 0 || index >= nodes.length) {
throw new IndexOutOfBoundsException("Invalid node index: " + index);
}
}
}⚠️ 关键注意事项: 必须为 Node 类重写 equals() 和 hashCode(),否则 indexOf() 将仅比较引用(==),导致逻辑错误。示例: @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); }
? 扩展性说明
- 无向图支持:调用 connect(a, b) 同时设置 adjacent[a][b] = adjacent[b][a] = true。
-
动态扩容:若节点数不确定,可用 List
- > 替代二维数组(牺牲部分性能换取灵活性)。
- 加权边:将 boolean[][] 升级为 double[][] 或自定义权重类(如 EdgeWeight),轻松支持距离、成本等语义。
- GUI集成提示:在 Swing/JavaFX 中,每个 Node 可额外持有 Point2D position 字段;渲染时遍历 adjacent 矩阵,对 adjacent[i][j] == true 的节点对绘制连线即可。
该设计兼顾简洁性、可读性与工程鲁棒性,是图形界面图应用的理想底层基石。









