邻接多重表存储图的方式可以看作是邻接表和十字链表的结合,都是为各顶点建立一个链表;各顶点建立的链表又组合在一起。
链表头节点:
其它节点:
同十字链表的一样,不过很多地方会多一个mark标志域,用来防止再进行操作时,同一无向弧被多次访问。mark为0时,表示为访问过,mark为1时,表示被访问过。不过,我没理解其中的高深之处,mark标志只有一次性,用过一次后变为1,再次使用便不在生效。此处例子,我便不设置mark标志域。
邻接多重表存储无向图
/*
邻接多重表主要存储无向图
*/
#define MAX_VERTEX_NUM 10 // 最大顶点数
typedef char verType; // 顶点类型
typedef string InfoType; // 弧上信息类型
// 弧
struct ArcNode {
int tailIndex, headIndex; // 弧尾、弧头所在数组下标
ArcNode *tlink, *hlink; // 分别指向与弧尾、弧头下一个相关的弧
InfoType* info; // 弧上信息
};
// 顶点
struct verNode {
verType vertex; // 数据域
ArcNode* firstArc; // 第一个与该顶点相关的弧
};
// 邻接多重表
struct AMLGraph {
verNode Vertex[MAX_VERTEX_NUM]; // 顶点数组
int ver_num; // 顶点数
int arc_num; // 弧数
};
// 获取顶点在数组位置
int LocateVertex(AMLGraph &graph, verType vex) {
for (int i = 0; i < graph.ver_num; ++i)
if (graph.Vertex[i].vertex == vex) return i;
return -1;
}
// 创建邻接多重表
void CreatAMLGraph(AMLGraph &graph) {
cout << "输入顶点数、边数>>" << endl;
cin >> graph.ver_num >> graph.arc_num;
cout << "输入顶点信息>>" << endl;
for (int i = 0; i < graph.ver_num; ++i) {
cin >> graph.Vertex[i].vertex;
graph.Vertex[i].firstArc = NULL;
}
verType v1, v2;
int index1, index2;
for (int i = 0; i < graph.arc_num; ++i) {
cout << "输入邻接的顶点" << endl;
cin >> v1 >> v2;
index1 = LocateVertex(graph, v1);
index2 = LocateVertex(graph, v2);
if (index1 < 0 || index2 < 0) {
cout << "邻接顶点错误" << endl;
--i;
continue;
}
ArcNode* arc = new ArcNode();
arc->tailIndex = index1;
arc->headIndex = index2;
arc->tlink = graph.Vertex[index1].firstArc;
arc->hlink = graph.Vertex[index2].firstArc;
graph.Vertex[index1].firstArc = arc;
graph.Vertex[index2].firstArc = arc;
cout << "弧上是否存储信息" << endl;
cout << " 1、是 0、否" << endl;
int Is_info;
cin >> Is_info;
if (Is_info) {
cout << "输入弧上信息" << endl;
InfoType INFO;
cin >> INFO;
arc->info = new InfoType(INFO);
}
}
}
遍历:
// 遍历
void Traverse(AMLGraph &graph) {
for (int i = 0; i < graph.ver_num; ++i) {
ArcNode* T = graph.Vertex[i].firstArc;
while (T) {
int index = i == T->headIndex ? T->tailIndex : T->headIndex;
cout << "顶点 " << graph.Vertex[i].vertex << "<-- -->" << graph.Vertex[index].vertex;
if (T->info) {
cout << " 弧上信息:" << *(T->info);
}
cout << endl;
if (i == T->headIndex) T = T->hlink;
else T = T->tlink;
}
}
}