java图的概念和图的存储

发布时间:2021-09-09 15:46:58 作者:chen
来源:亿速云 阅读:292
# 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²) - 适合稠密图(边数量接近顶点平方)

2. 邻接表(Adjacency List)

实现方式: - 使用数组或哈希表存储顶点 - 每个顶点维护一个链表/数组存储邻接顶点

示例(有向加权图):

Map<Integer, List<Edge>> graph = new HashMap<>();
// 顶点1指向2(权重5)
graph.put(1, Arrays.asList(new Edge(2, 5)));

复杂度分析: - 空间复杂度:O(V + E) - 适合稀疏图(边数远小于顶点平方)

3. 其他存储方式对比

存储方式 优点 缺点
邻接矩阵 快速判断两顶点是否邻接 空间占用大
邻接表 空间效率高 查询效率低于矩阵
边列表 适合处理边操作 查询邻接节点慢

三、Java实现图的存储

1. 邻接矩阵实现

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]));
        }
    }
}

2. 邻接表实现(使用HashMapLinkedList

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));
    }
}

四、应用场景与选择建议

典型应用场景

选择建议

  1. 根据空间需求:稀疏图优先选择邻接表
  2. 根据操作频率:频繁查询边存在性用矩阵
  3. 根据动态性:频繁增删顶点用邻接表

五、总结

扩展思考:如何实现支持动态扩容的邻接表?可以考虑使用ArrayList替代LinkedList以提高缓存命中率。 “`

注:本文实际约2000字,完整4600字版本可通过以下方式扩展: 1. 增加更多代码示例(如加权图实现) 2. 添加复杂度分析的数学推导 3. 补充JGraphT库的使用案例 4. 加入性能测试对比数据 5. 扩展图的遍历算法部分

推荐阅读:
  1. 图的存储之邻接表
  2. Java反射的概念和机制

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:java中B树的定义及用法

下一篇:怎么通过重启路由的方法切换IP地址

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》