图 - 邻接矩阵 (Adjacency Matrix)

用 V×V 二维矩阵表示边。矩阵[i][j] 存储边权重(或 0/1 表示有无边)。空间 O(V²),适合稠密图。


结构定义

typedef struct {
    int **mat;           /* V×V 矩阵,mat[u][v] = 权重,0 表示无边 */
    int V;
    int directed;
} GraphM;

函数签名

函数复杂度说明
GraphM* graphm_create(int V, int directed)O(V²)创建并初始化全 0 矩阵
void graphm_add_edge(GraphM *g, int u, int v, int w)O(1)设置 mat[u][v] = w
void graphm_remove_edge(GraphM *g, int u, int v)O(1)设置 mat[u][v] = 0
int graphm_has_edge(GraphM *g, int u, int v)O(1)检查 mat[u][v] != 0
void graphm_bfs(GraphM *g, int start, void (*visit)(int))O(V²)广度优先(遍历整行找邻居)
void graphm_dfs(GraphM *g, int start, void (*visit)(int))O(V²)深度优先
void graphm_free(GraphM *g)O(V)释放

创建

GraphM* graphm_create(int V, int directed) {
    GraphM *g = malloc(sizeof(GraphM));
    g->V = V;
    g->directed = directed;
    g->mat = malloc(V * sizeof(int *));
    for (int i = 0; i < V; i++)
        g->mat[i] = calloc(V, sizeof(int));
    return g;
}

加边

void graphm_add_edge(GraphM *g, int u, int v, int w) {
    g->mat[u][v] = w;
    if (!g->directed)
        g->mat[v][u] = w;   /* 无向图对称设置 */
}

遍历邻居

/* 遍历顶点 u 的所有邻居 */
for (int v = 0; v < g->V; v++) {
    if (g->mat[u][v] != 0) {
        /* v 是 u 的邻居,权重为 mat[u][v] */
    }
}

邻接矩阵遍历邻居始终是 O(V),即使实际邻居很少——这是稀疏图上的主要劣势。


优势场景

场景适合原因
稠密图 (E ≈ V²)空间利用率高
Floyd-Warshall 全源最短路径需要 O(1) 查边长
快速查询”u 到 v 是否有边”O(1) vs 邻接表的 O(deg)
矩阵乘法 (图的代数性质)邻接矩阵的 n 次幂表示 n 步可达关系

跨语言参考