邻接多重表是一种常见的图表示方法,用于表示无向图。在邻接多重表中,每个节点既是图的顶点,又是图的边。本文将介绍邻接多重表的原理、数据结构定义以及基本操作,并附带使用C++实现的示例代码。
一、邻接多重表原理
邻接多重表是一种更加紧凑的图表示方法,它结合了邻接表和十字链表的优点。每个节点同时代表一个顶点和一条边,通过利用重复利用节点的方式,可以更加高效地存储图的信息。在邻接多重表中,每个节点包含了以下信息:
顶点结构图:
data:顶点数据。
firstEdge:这个顶点的第一条边。
边结构图:
ivex:该边的起始顶点在顶点数组中的位置(即顶点的下标)。
jvex:该边的终止顶点在顶点数组中的位置。
ilink:指向起始顶点与ivex相同的下一条边。
jlink:指向终止顶点与jvex相同的下一条边。
二、邻接多重表数据结构定义
我们使用以下的结构体来定义邻接多重表:
#define MaxSize 50
// 邻接多重表的边节点
typedef struct EdgeNode {
int ivex;
int jvex;
struct EdgeNode* ilink;
struct EdgeNode* jlink;
} EdgeNode;
// 邻接多重表的顶点节点
typedef struct VertexNode {
char data; // 顶点数据,可以是任意类型
EdgeNode* firstEdge; // 该顶点的第一条边
} VertexNode;
//邻接多重表的定义
struct AdjMultiList {
VertexNode vertexList[MaxSize];
int vex_num, Edge_num;
};
三、初始化
//初始化邻接多重表
void InitAdjMultiList(AdjMultiList& Mlist, int VexNum) {
Mlist.vex_num = VexNum;
Mlist.Edge_num = 0;
for (int i = 0; i < VexNum; i++) {
Mlist.vertexList[i].data = 'a' + i;
Mlist.vertexList[i].firstEdge = NULL;
}
}
四、判断邻接多重表中是否存在某条边
// 判断邻接多重表中是否存在某条边
bool hasEdge(EdgeNode* firstEdge, int ivex, int jvex) {
EdgeNode* edge = firstEdge;
while (edge != NULL) {
if ((edge->ivex == ivex && edge->jvex == jvex) || (edge->ivex == jvex && edge->jvex == ivex)) {
return true; // 找到与给定边相同的边节点
}
edge = (edge->ivex == ivex) ? edge->ilink : edge->jlink;
}
return false; // 未找到与给定边相同的边节点
}
五、添加边
//添加边
bool addEdge(AdjMultiList& Mlist, int from, int to) {
//判断from,to是否合法,我们只讨论简单图,所以from!=to
if (from < 0 || from >= Mlist.vex_num || to < 0 || to >= Mlist.vex_num||from==to) {
return false; //添加失败
}
//判断是否存在from与to之间的边
if (hasEdge(Mlist.vertexList[0].firstEdge, from, to)) {
return true; //需添加的边已经存在 不需要再添加
}
EdgeNode* newEdge = (EdgeNode*)malloc(sizeof(EdgeNode));
newEdge->ivex = from; //添加边的时候我们想象以from出发点
newEdge->jvex = to;
newEdge->ilink = Mlist.vertexList[from].firstEdge;
newEdge->jlink = Mlist.vertexList[to].firstEdge;
//将newEdge插入from这条链的链头
Mlist.vertexList[from].firstEdge = newEdge;
Mlist.vertexList[to].firstEdge = newEdge;
Mlist.Edge_num++;
}
六、main
int main() {
AdjMultiList Mlist; //创建一个邻接表
InitAdjMultiList(Mlist, 5); //初始化邻接表
return 0;
}