在计算机科学中,图是一种非常重要的非线性数据结构。当我们需要表示图时,有两种常用的方法:邻接矩阵和邻接表。对于稀疏图(边数远小于顶点数平方的图),C语言邻接表表示法更加节省空间且高效。
邻接表是图的一种链式存储结构。它为图中的每个顶点维护一个链表,链表中存储了所有与该顶点直接相连的其他顶点。这种结构非常适合表示稀疏图。
在C语言图结构中,我们通常定义两个结构体:
AdjListNode:表示邻接链表中的一个节点AdjList:表示一个顶点及其对应的邻接链表Graph:整个图的结构,包含顶点数量和邻接表数组下面是一个完整的邻接表实现教程,包含了创建图、添加边和打印图的功能:
#include <stdio.h>#include <stdlib.h>// 邻接链表中的节点typedef struct AdjListNode { int dest; // 目标顶点 struct AdjListNode* next; // 指向下一个邻接节点} AdjListNode;// 邻接表typedef struct AdjList { AdjListNode* head; // 指向邻接链表的头节点} AdjList;// 图结构typedef struct Graph { int V; // 顶点数量 AdjList* array; // 邻接表数组} Graph;// 创建新的邻接节点AdjListNode* newAdjListNode(int dest) { AdjListNode* newNode = (AdjListNode*) malloc(sizeof(AdjListNode)); newNode->dest = dest; newNode->next = NULL; return newNode;}// 创建图Graph* createGraph(int V) { Graph* graph = (Graph*) malloc(sizeof(Graph)); graph->V = V; // 为邻接表数组分配内存 graph->array = (AdjList*) malloc(V * sizeof(AdjList)); // 初始化每个邻接表的头指针为NULL for (int i = 0; i < V; ++i) { graph->array[i].head = NULL; } return graph;}// 添加边到无向图void addEdge(Graph* graph, int src, int dest) { // 添加从src到dest的边 AdjListNode* newNode = newAdjListNode(dest); newNode->next = graph->array[src].head; graph->array[src].head = newNode; // 因为是无向图,所以也要添加从dest到src的边 newNode = newAdjListNode(src); newNode->next = graph->array[dest].head; graph->array[dest].head = newNode;}// 打印图的邻接表表示void printGraph(Graph* graph) { for (int v = 0; v < graph->V; ++v) { AdjListNode* pCrawl = graph->array[v].head; printf("\n邻接表 %d\n head", v); while (pCrawl) { printf(" -> %d", pCrawl->dest); pCrawl = pCrawl->next; } printf("\n"); }}// 主函数示例int main() { // 创建一个有5个顶点的图 int V = 5; Graph* graph = createGraph(V); // 添加边 addEdge(graph, 0, 1); addEdge(graph, 0, 4); addEdge(graph, 1, 2); addEdge(graph, 1, 3); addEdge(graph, 1, 4); addEdge(graph, 2, 3); addEdge(graph, 3, 4); // 打印邻接表表示 printGraph(graph); return 0;} 让我们逐部分理解这段代码:
- AdjListNode:存储目标顶点和指向下一个节点的指针
- AdjList:包含指向邻接链表头节点的指针
- Graph:包含顶点数量和邻接表数组
newAdjListNode函数动态分配内存并初始化一个新的邻接节点。
createGraph函数分配图结构的内存,并初始化每个顶点的邻接表为空。
在无向图中,每条边需要在两个顶点的邻接表中都添加对方。这里使用头插法将新节点插入到链表头部。
printGraph函数遍历每个顶点的邻接表并打印出来,便于调试和验证。
| 特性 | 邻接表 | 邻接矩阵 |
|---|---|---|
| 空间复杂度 | O(V + E) | O(V²) |
| 查询两点是否相邻 | O(degree(v)) | O(1) |
| 适用场景 | 稀疏图 | 稠密图 |
通过这个C语言邻接表教程,你应该已经掌握了如何用C语言实现图的邻接表表示。邻接表是处理稀疏图的高效方法,在实际应用中非常常见,比如社交网络、网页链接分析等场景。
记住关键点:
现在你已经具备了实现C语言图结构的基础知识,可以尝试扩展这个实现,比如支持有向图、权重边,或者实现图的遍历算法(DFS、BFS)等。
本文由主机测评网于2025-12-17发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025128880.html