图 - 邻接表 (Adjacency List)

每个顶点维护一个链表(或动态数组),存储其所有邻居。空间 O(V + E),适合稀疏图。


结构定义

typedef struct AdjNode {
    int vertex;           /* 目标顶点 */
    int weight;           /* 边权重(可选,无权图可省略) */
    struct AdjNode *next;
} AdjNode;
 
typedef struct {
    AdjNode **adj;        /* 邻接表数组 */
    int V;                /* 顶点数 */
    int directed;         /* 是否是有向图 */
} Graph;

函数签名

函数复杂度说明
Graph* graph_create(int V, int directed)O(V)创建图
void graph_add_edge(Graph *g, int u, int v, int w)O(1)添加边(头插法)
void graph_remove_edge(Graph *g, int u, int v)O(deg(u))移除边
int graph_has_edge(Graph *g, int u, int v)O(deg(u))边是否存在
void graph_bfs(Graph *g, int start, void (*visit)(int))O(V + E)广度优先
void graph_dfs(Graph *g, int start, void (*visit)(int))O(V + E)深度优先
void graph_free(Graph *g)O(V + E)释放

BFS 实现

void graph_bfs(Graph *g, int start, void (*visit)(int)) {
    int *visited = calloc(g->V, sizeof(int));
    int *queue = malloc(g->V * sizeof(int));
    int front = 0, rear = 0;
 
    visited[start] = 1;
    queue[rear++] = start;
 
    while (front < rear) {
        int u = queue[front++];
        visit(u);
        for (AdjNode *p = g->adj[u]; p; p = p->next) {
            if (!visited[p->vertex]) {
                visited[p->vertex] = 1;
                queue[rear++] = p->vertex;
            }
        }
    }
    free(visited);
    free(queue);
}

DFS 实现(递归)

static void dfs_util(Graph *g, int u, int *visited, void (*visit)(int)) {
    visited[u] = 1;
    visit(u);
    for (AdjNode *p = g->adj[u]; p; p = p->next)
        if (!visited[p->vertex])
            dfs_util(g, p->vertex, visited, visit);
}

邻接表 vs 邻接矩阵

特性邻接表邻接矩阵
空间O(V + E)O(V²)
查边 (u,v)O(deg(u))O(1)
遍历邻居O(deg(u))O(V)
适合场景稀疏图稠密图 / 边查询密集

跨语言参考