# 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(V2) - 適合稠密圖(邊數量接近頂點平方)
實現方式: - 使用數組或哈希表存儲頂點 - 每個頂點維護一個鏈表/數組存儲鄰接頂點
示例(有向加權圖):
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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。