| 项目 | 值 |
|---|---|
| 主题 | 图的存储结构 |
| 核心概念 | 用二维数组 / 链表表示图中顶点之间的邻接关系 |
| 时间复杂度 | $O(1)$、$O(|V|)$、$O(|V|+|E|)$、$O(|V|^2)$、$O(\deg(v))$ |
| 难度 | ⭐⭐⭐ |
| 重要性 | ⭐⭐⭐⭐⭐ |
用一个二维数组表示图中顶点之间的邻接关系。
#define MaxVertexNum 100
typedef struct {
char vex[MaxVertexNum]; // 顶点表
int edge[MaxVertexNum][MaxVertexNum]; // 邻接矩阵
int vexnum, arcnum; // 顶点数、边数
} MGraph;
$$A[i][j] = \begin{cases} 1, & (v_i, v_j) \in E \text{ 或 } <v_i, v_j> \in E \\ 0, & \text{其他} \end{cases}$$
$$A[i][j] = \begin{cases} w_{ij}, & (v_i, v_j) \in E \text{ 或 } <v_i, v_j> \in E \\ \infty, & \text{其他} \end{cases}$$
A --- B
| / |
| / |
C --- D
邻接矩阵:
A B C D
A [ 0 1 1 0 ]
B [ 1 0 1 1 ]
C [ 1 1 0 1 ]
D [ 0 1 1 0 ]
| 操作 | 时间复杂度 |
|---|---|
| 判断边是否存在 | $O(1)$ |
| 找顶点的邻接点 | $O(|V|)$ |
| 插入 / 删除边 | $O(1)$ |
| 插入 / 删除顶点 | $O(|V|^2)$ |
对每个顶点建立一个单链表,存储其所有邻接点。
// 边结点
typedef struct ArcNode {
int adjvex; // 邻接点下标
struct ArcNode *next; // 下一条边
// InfoType info; // 边权值
} ArcNode;
// 顶点结点
typedef struct {
char data; // 顶点信息
ArcNode *first; // 第一条边
} VNode;
// 邻接表
typedef struct {
VNode vertices[MaxVertexNum];
int vexnum, arcnum;
} ALGraph;
A --- B
| / |
| / |
C --- D
邻接表:
A → [B] → [C]
B → [A] → [C] → [D]
C → [A] → [B] → [D]
D → [B] → [C]
| 操作 | 时间复杂度 |
|---|---|
| 判断边是否存在 | $O(\deg(v))$ |
| 找顶点的邻接点 | $O(\deg(v))$ |
| 插入 / 删除边 | $O(\deg(v))$ |
对有向图,每个顶点的链表存储指向该顶点的边。
A ← B
A ← C
B ← C
B ← D
C ← D
逆邻接表:
A → [B] → [C] ← 指向A的边
B → [C] → [D] ← 指向B的边
C → [D] ← 指向C的边
D ← 指向D的边
typedef struct ArcBox {
int tailvex, headvex; // 弧尾、弧头
struct ArcBox *hlink, *tlink; // 同弧头、同弧尾链
// InfoType info;
} ArcBox;
typedef struct VexNode {
char data;
ArcBox *firstin, *firstout; // 入弧、出弧
} VexNode;
特点:
typedef struct ArcNode {
int ivex, jvex; // 依附的两个顶点
struct ArcNode *ilink, *jlink; // 依附于ivex、jvex的下一条边
// InfoType info;
} ArcNode;
typedef struct {
char data;
ArcNode *firstedge;
} VexNode;
特点:
| 存储方式 | 空间 | 判边存在 | 找邻接点 | 适用场景 |
|---|---|---|---|---|
| 邻接矩阵 | $O(|V|^2)$ | $O(1)$ | $O(|V|)$ | 稠密图 |
| 邻接表 | $O(|V|+|E|)$ | $O(\deg)$ | $O(\deg)$ | 稀疏图 |
| 十字链表 | $O(|V|+|E|)$ | $O(\deg)$ | $O(\deg)$ | 有向图 |
| 邻接多重表 | $O(|V|+|E|)$ | $O(\deg)$ | $O(\deg)$ | 无向图 |
有向图:
A → B → C
↑ ↓
← ← ← D
邻接矩阵:
A B C D
A [ 0 1 0 0 ]
B [ 0 0 1 0 ]
C [ 0 0 0 1 ]
D [ 1 0 0 0 ]
无向图:
0 --- 1
| / |
| / |
2 --- 3
邻接表:
0 → [1] → [2]
1 → [0] → [2] → [3]
2 → [0] → [1] → [3]
3 → [1] → [2]
有向图邻接表:
A → [B] → [C]
B → [C]
C → [A]
D → [A] → [B]
| 顶点 | 出度 | 入度 |
|---|---|---|
| A | 2 | 2(来自 C, D) |
| B | 1 | 2(来自 A, D) |
| C | 1 | 2(来自 A, B) |
| D | 2 | 0 |
| 图类型 | 推荐存储 | 空间 |
|---|---|---|
| 稠密图 | 邻接矩阵 | $O(|V|^2)$ |
| 稀疏图 | 邻接表 | $O(|V|+|E|)$ |
| 有向图需入度 | 十字链表 | $O(|V|+|E|)$ |
| 无向图需删边 | 邻接多重表 | $O(|V|+|E|)$ |
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。