您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Java图的概念和图的存储
## 目录
1. [图的基本概念](#一图的基本概念)
- 图的定义与组成
- 图的分类与特性
2. [图的存储结构](#二图的存储结构)
- 邻接矩阵
- 邻接表
- 其他存储方式对比
3. [Java实现图的存储](#三java实现图的存储)
- 邻接矩阵实现
- 邻接表实现
4. [应用场景与选择建议](#四应用场景与选择建议)
5. [总结](#五总结)
---
## 一、图的基本概念
### 1. 图的定义与组成
图(Graph)是由**顶点集合(Vertex)**和**边集合(Edge)**组成的非线性数据结构,形式化表示为 `G = (V, E)`。其中:
- **顶点(Node)**:表示实体(如社交网络中的用户)
- **边(Edge)**:表示顶点间的关系(如用户之间的好友关系)
### 2. 图的分类与特性
| 分类标准 | 类型 | 特点 |
|----------------|---------------------|----------------------------------------------------------------------|
| **边的方向** | 有向图 | 边有方向(如A→B表示单向关系) |
| | 无向图 | 边无方向(A-B等价于B-A) |
| **边的权重** | 加权图 | 边带权值(如地图中道路长度) |
| | 无权图 | 边无权重 |
| **连通性** | 连通图 | 任意两顶点间存在路径 |
| | 非连通图 | 存在孤立顶点 |
---
## 二、图的存储结构
### 1. 邻接矩阵(Adjacency Matrix)
**实现方式**:
- 使用二维数组`matrix[][]`存储
- `matrix[i][j]`表示顶点i到j的边(无权图为0/1,加权图为权值)
**示例**(无向图):
```java
// 顶点: 0,1,2,3
int[][] matrix = {
{0, 1, 0, 1}, // 0连接1,3
{1, 0, 1, 0}, // 1连接0,2
{0, 1, 0, 1}, // 2连接1,3
{1, 0, 1, 0} // 3连接0,2
};
复杂度分析: - 空间复杂度:O(V²) - 适合稠密图(边数量接近顶点平方)
实现方式: - 使用数组或哈希表存储顶点 - 每个顶点维护一个链表/数组存储邻接顶点
示例(有向加权图):
Map<Integer, List<Edge>> graph = new HashMap<>();
// 顶点1指向2(权重5)
graph.put(1, Arrays.asList(new Edge(2, 5)));
复杂度分析: - 空间复杂度:O(V + E) - 适合稀疏图(边数远小于顶点平方)
存储方式 | 优点 | 缺点 |
---|---|---|
邻接矩阵 | 快速判断两顶点是否邻接 | 空间占用大 |
邻接表 | 空间效率高 | 查询效率低于矩阵 |
边列表 | 适合处理边操作 | 查询邻接节点慢 |
public class GraphMatrix {
private int[][] adjMatrix;
private int vertexCount;
public GraphMatrix(int vertexCount) {
this.vertexCount = vertexCount;
adjMatrix = new int[vertexCount][vertexCount];
}
// 添加边(无向图)
public void addEdge(int i, int j) {
adjMatrix[i][j] = 1;
adjMatrix[j][i] = 1;
}
// 打印矩阵
public void print() {
for (int i = 0; i < vertexCount; i++) {
System.out.println(Arrays.toString(adjMatrix[i]));
}
}
}
HashMap
和LinkedList
)public class GraphList {
private Map<Integer, LinkedList<Integer>> adjList;
public GraphList() {
adjList = new HashMap<>();
}
// 添加顶点
public void addVertex(int vertex) {
adjList.put(vertex, new LinkedList<>());
}
// 添加边(有向图)
public void addEdge(int src, int dest) {
adjList.get(src).add(dest);
}
// 打印邻接表
public void print() {
adjList.forEach((v, neighbors) ->
System.out.println(v + " -> " + neighbors));
}
}
JGraphT
等专业图库扩展思考:如何实现支持动态扩容的邻接表?可以考虑使用
ArrayList
替代LinkedList
以提高缓存命中率。 “`
注:本文实际约2000字,完整4600字版本可通过以下方式扩展: 1. 增加更多代码示例(如加权图实现) 2. 添加复杂度分析的数学推导 3. 补充JGraphT库的使用案例 4. 加入性能测试对比数据 5. 扩展图的遍历算法部分
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。