邻接表(Adjacency List)是图的一种链式存储结构。在邻接表中,对图中的每个顶点建立一个单链表,第i个单链表中的结点表示依附于顶点vi的边(对有向图是以顶点vi为尾的弧)。每个结点有三个域组成,其中邻接点域(adjvex)指示与顶点vi邻接的点在图中的位置,链域(nextarc)指示下一条边或弧的结点;数据域(info)存储和边或弧相关的信息,如权值等。每个链表上附设一个表头结点。在表头结点中,除了链域(firstarc)指向链表中的第一结点之外,还设有存储顶点vi的名或其他相关信息的数据域(data)。
如图:
图:
#include<iostream>
using namespace std;
#include<malloc.h>
#include<string.h>
#define MAX_NAME 5 //顶点字符串的最大长度
#define MAX_VERTEX_NUM 20 //顶点最大长度
#define OK 1
#define FALSE -1
typedef char VertexType[MAX_NAME];
typedef int InfoType;
typedef struct ArcNode
{
int adjvex; //该弧所指向的顶点的位置
struct ArcNode *nextarc; //指向下一条弧的指针
InfoType *info; //该弧相关信息
}ArcNode;
typedef struct VNode
{
VertexType data; //顶点信息, 如 v1, v2,v3
ArcNode *firstarc; //指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList vertices;
int vexnum, arcnum; //图的当前顶点数和弧数
int king; //图的种类标志
}ALGraph;
int LocateVex(ALGraph &G, VertexType &u) //返回顶点u在vertices数组中的位置
{
for(int i = 0; i < G.vexnum; ++i)
if(strcmp(G.vertices[i].data,u) == 0)
return i;
return FALSE;
}
int CreateDG(ALGraph &G)
{
int IncInfo, i, j, k;
VertexType v1,v2;
cout << "请输入有向图的顶点数:" << endl;
cin >> G.vexnum;
cout << "请输入有向图的弧数:" << endl;
cin >> G.arcnum;
cout << "请输入有向图的弧是否含有其它信息:(有:1 无:0)" << endl;
cin >> IncInfo;
cout << "请输入有向图的所有顶点:" << endl;
for (i = 0; i < G.vexnum; ++i) //初始化G.vertices数组
{
cout << "请输入第" << i+1 << "个顶点" << endl;
scanf("%s",&G.vertices[i].data);
//gets(G.vertices[i].data);
G.vertices[i].firstarc = NULL;
}
cout << "请输入弧,如:(v1->v2)" << endl;
for (k = 0; k < G.arcnum; ++k)
{
cout << "请输入第" << k+1 << "条弧" << endl;
cin >> v1;
cout << v1 << "->";
cin >> v2;
i = LocateVex(G,v1); //如果v1存在,则返回v1在数组G.vertices[]中的位置,否则返回-1
j = LocateVex(G,v2);
while(i<0 || i > G.vexnum-1 || j<0 || j > G.vexnum-1)
{
cout << "找不到该弧所依附的顶点,请重新输入:" << endl;
cout << "请输入第" << k+1 << "条弧" << endl;
cin >> v1;
cout << "->";
cin >> v2;
i = LocateVex(G,v1); //如果v1存在,则返回v1在数组G.vertices[]中的位置,否则返回-1
j = LocateVex(G,v2);
}
ArcNode *p;
p = (ArcNode *)malloc(sizeof(ArcNode)); //开辟内存空间
if(!p)
{
cout << "溢出" << endl;
return 0;
}
p->adjvex = j; //这里运用了单链表的逆序构建
p->info = NULL;
p->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = p;
if(IncInfo)
{
cout << "请输入单链表的其它信息:" << endl;
cin >> *(p->info);
} // if end
} // for end
return OK;
} // CreateDG() end
void DisplayDG(ALGraph &G)
{
cout << "邻接表:" << endl;
for(int i = 0; i < G.vexnum; ++i)
{
cout << G.vertices[i].data << ' ';
for(ArcNode *p = G.vertices[i].firstarc; p!=NULL; p=p->nextarc)
{
cout << p->adjvex << ' ';
}
cout << endl;
}
}
void DestroyDG(ALGraph &G)
{
ArcNode *q;
for(int i = 0; i > G.vexnum; ++i)
for (ArcNode *p = G.vertices[i].firstarc; p!=NULL; )
{
q = p;
p = p->nextarc;
free(q);
}
}
int main()
{
ALGraph G;
CreateDG(G);
DisplayDG(G);
DestroyDG(G);
return 0;
}
运行结果: