在C语言邻接多重表的学习过程中,很多初学者常常对图(Graph)的存储方式感到困惑。本文将用通俗易懂的语言,带你从零开始理解什么是邻接多重表、它适用于什么场景,并手把手教你用 C 语言实现它。无论你是编程小白还是刚接触数据结构教程的新手,都能轻松掌握!
邻接多重表(Adjacency Multilist)是一种用于存储无向图的数据结构。它结合了邻接表和十字链表的优点,特别适合需要频繁操作边(如删除、标记)的场景。
与邻接表不同,邻接多重表中每条边只用一个节点表示,而不是像邻接表那样为每条边在两个顶点的链表中各存一份。这样可以节省空间,也便于对边进行统一管理。
在邻接多重表中,我们需要定义两种结构体:
typedef struct EdgeNode { int ivex, jvex; // 两个顶点在顶点数组中的下标 char mark; // 边的标记,例如是否被访问过 struct EdgeNode *ilink; // 指向顶点 ivex 的下一条边 struct EdgeNode *jlink; // 指向顶点 jvex 的下一条边} EdgeNode;typedef struct VertexNode { char data; // 顶点信息,例如 'A', 'B' 等 EdgeNode *firstedge; // 指向第一条依附于该顶点的边} VertexNode;typedef struct { VertexNode vertices[MAX_VERTEX_NUM]; int vexnum, edgenum; // 顶点数和边数} AMGraph; // Adjacency Multilist Graph
为什么不用简单的邻接表而要用邻接多重表?关键在于边的操作效率:
下面是一个完整的 C 语言程序,演示如何构建一个包含 4 个顶点(A, B, C, D)和 3 条边(A-B, A-C, B-D)的无向图。
#include <stdio.h>#include <stdlib.h>#define MAX_VERTEX_NUM 10typedef struct EdgeNode { int ivex, jvex; char mark; struct EdgeNode *ilink, *jlink;} EdgeNode;typedef struct VertexNode { char data; EdgeNode *firstedge;} VertexNode;typedef struct { VertexNode vertices[MAX_VERTEX_NUM]; int vexnum, edgenum;} AMGraph;void createAMGraph(AMGraph *g) { g->vexnum = 4; g->edgenum = 3; // 初始化顶点 g->vertices[0].data = 'A'; g->vertices[0].firstedge = NULL; g->vertices[1].data = 'B'; g->vertices[1].firstedge = NULL; g->vertices[2].data = 'C'; g->vertices[2].firstedge = NULL; g->vertices[3].data = 'D'; g->vertices[3].firstedge = NULL; // 添加边 A-B (0-1) EdgeNode *e1 = (EdgeNode*)malloc(sizeof(EdgeNode)); e1->ivex = 0; e1->jvex = 1; e1->mark = 'U'; e1->ilink = g->vertices[0].firstedge; e1->jlink = g->vertices[1].firstedge; g->vertices[0].firstedge = e1; g->vertices[1].firstedge = e1; // 添加边 A-C (0-2) EdgeNode *e2 = (EdgeNode*)malloc(sizeof(EdgeNode)); e2->ivex = 0; e2->jvex = 2; e2->mark = 'U'; e2->ilink = g->vertices[0].firstedge; e2->jlink = g->vertices[2].firstedge; g->vertices[0].firstedge = e2; g->vertices[2].firstedge = e2; // 添加边 B-D (1-3) EdgeNode *e3 = (EdgeNode*)malloc(sizeof(EdgeNode)); e3->ivex = 1; e3->jvex = 3; e3->mark = 'U'; e3->ilink = g->vertices[1].firstedge; e3->jlink = g->vertices[3].firstedge; g->vertices[1].firstedge = e3; g->vertices[3].firstedge = e3;}void printAMGraph(AMGraph *g) { for (int i = 0; i < g->vexnum; i++) { printf("Vertex %c: ", g->vertices[i].data); EdgeNode *p = g->vertices[i].firstedge; while (p) { int other = (p->ivex == i) ? p->jvex : p->ivex; printf("%c ", g->vertices[other].data); // 根据当前顶点选择下一个指针 p = (p->ivex == i) ? p->ilink : p->jlink; } printf(\n"); }}int main() { AMGraph g; createAMGraph(&g); printAMGraph(&g); return 0;}
运行结果:
Vertex A: C B Vertex B: D A Vertex C: A Vertex D: B
邻接多重表虽然实现略复杂,但在处理无向图且需要频繁操作边(如图遍历中标记已访问边、网络流算法等)时非常高效。它是学习高级图的存储结构的重要一环。
通过本篇C语言邻接多重表教程,你应该已经掌握了其基本原理、结构定义和简单实现。建议你动手敲一遍代码,加深理解!
如果你觉得这篇文章对你有帮助,欢迎分享给更多正在学习数据结构教程的朋友!
本文由主机测评网于2025-12-06发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025123783.html