Java 图结构实现指南:使用邻接矩阵存储节点与边关系
发布时间 - 2026-02-02 00:00:00 点击率:次本文介绍如何在 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.g
etClass()) 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
# node
# edge
# ai
# win
# Boolean
# 布尔型
# int
# double
# 数据结构
# map
# 对象
# 重写
# 自定义
# 可将
# 连通性
# 两点
# 若需
# 一是
# 布尔
# 绑定
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
使用spring连接及操作mongodb3.0实例
浅谈redis在项目中的应用
Android使用GridView实现日历的简单功能
Laravel安装步骤详细教程_Laravel环境搭建指南
香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧
Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
魔毅自助建站系统:模板定制与SEO优化一键生成指南
lovemo网页版地址 lovemo官网手机登录
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
北京的网站制作公司有哪些,哪个视频网站最好?
如何在建站主机中优化服务器配置?
Android自定义控件实现温度旋转按钮效果
如何快速搭建虚拟主机网站?新手必看指南
HTML 中如何正确使用模板变量为元素的 name 属性赋值
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
JavaScript如何实现错误处理_try...catch如何捕获异常?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
轻松掌握MySQL函数中的last_insert_id()
网站制作报价单模板图片,小松挖机官方网站报价?
如何自定义建站之星模板颜色并下载新样式?
如何在云主机上快速搭建网站?
晋江文学城电脑版官网 晋江文学城网页版直接进入
悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
网站制作企业,网站的banner和导航栏是指什么?
浅述节点的创建及常见功能的实现
动图在线制作网站有哪些,滑动动图图集怎么做?
如何利用DOS批处理实现定时关机操作详解
音乐网站服务器如何优化API响应速度?
深入理解Android中的xmlns:tools属性
Thinkphp 中 distinct 的用法解析
Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理
微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】
HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】
Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧
Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】
Laravel storage目录权限问题_Laravel文件写入权限设置
油猴 教程,油猴搜脚本为什么会网页无法显示?
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
如何用西部建站助手快速创建专业网站?
Laravel如何创建自定义中间件?(Middleware代码示例)
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
如何在腾讯云服务器上快速搭建个人网站?
利用 Google AI 进行 YouTube 视频 SEO 描述优化


