图的邻接表表示法类似于树的孩子链表表示法。对于图G中的每个顶点vi,该方法把所有邻接于vi的顶点vj链成一个带头结点的单链表,这个单链表就称为顶点vi的邻接表(Adjacency List)。
1. 邻接表的结点结构
(1)表结点结构
┌────┬───┐
│adjvex │next │
└────┴───┘
邻接表中每个表结点均有两个域:
① 邻接点域adjvex
存放与vi相邻接的顶点vj的序号j。
② 链域next
将邻接表的所有表结点链在一起。
注意:
若要表示边上的信息(如权值),则在表结点中还应增加一个数据域。
(2)头结点结构
┌────┬─────┐
│vertex │firstedge │
└────┴─────┘
顶点vi邻接表的头结点包含两个域:
① 顶点域vertex
存放顶点vi的信息
② 指针域firstedge
vi的邻接表的头指针。
注意:
① 为了便于随机访问任一顶点的邻接表,将所有头结点顺序存储在一个向量中就构成了图的邻接表表示。
② 有时希望增加对图的顶点数及边数等属性的描述,可将邻接表和这些属性放在一起来描述图的存储结构。
代码:
#include<iostream>
using namespace std;
#define MAX_VERTEX_NUM 50//定义图的最大顶点数
typedef char VertexData;
typedef struct EdgeNode //表结点
{
int adjvex; //邻接点域
EdgeNode *next; //边结点所对应的下一个边结点
} EdgeNode;
typedef struct VertexNode//头结点
{
VertexData data;
EdgeNode *firstedge; //头结点所对应的第一个边结点
}VertexNode;
typedef struct AdjList
{
int VexNum,ArcNum; //定义图的顶点数和边数
VertexNode vertex[MAX_VERTEX_NUM]; //定义头结点数组
}AdjList;
void CreateGraph(AdjList *adj,int *n) //n为指针传值
{
int e,s,d;
cout<<"输入顶点数和边数"<<endl;
cin>>*n>>e;//输入顶点数和边数。
adj->VexNum=*n;
adj->ArcNum=e;
EdgeNode *q=NULL; //定义一个指向边节点的指针,并初始化为NULL
//初始化表头结点
int i;
for(i=1;i<=*n;i++)
{
cout<<"输入第"<<i<<"个结点的顶点名称"<<endl;
cin>>adj->vertex[i].data; //顶点名称,是一个字符
adj->vertex[i].firstedge=NULL;
}
for(i=1;i<=e;i++)
{
cout<<"输入第"<<i<<"条边的起点和终点"<<endl;
cin>>s>>d;//输入边的起始和终止
q=(EdgeNode *)malloc(sizeof(EdgeNode));//创建一个表结点
if(q==NULL)
return;
q->adjvex=d;
q->next=adj->vertex[s].firstedge; //新加入的节点都是在头结点之后,原来在头结点之后的节点要后移。
adj->vertex[s].firstedge=q;
}
}
void DisplayGraph(AdjList *adj)
{
int n=adj->VexNum;//顶点个数,后面要遍历每一个点点
EdgeNode *q=NULL; //定义一个指向边节点的指针,并初始化为NULL
int i;
for( i=1;i<=n;i++)
{
q=adj->vertex[i].firstedge;
if(q==NULL) //表示头结点后面没有跟其他结点
{
cout<<"没有从"<<adj->vertex[i].data<<"出发的节点"<<endl;
}
else
{
cout<<"从结点"<<adj->vertex[i].data<<"出发的边有"<<endl;
while(q!=NULL)
{
cout<<adj->vertex[i].data<<"->"<<adj->vertex[q->adjvex].data<<endl; //在“初始化表头结点”时已经将每个顶点的序号与名字对应起来,通过q->adjvex确定对应的(头)结点及其名字
q=q->next;
}
}
}
}
void main( )
{
int n;
AdjList *adj=(AdjList *)malloc(sizeof(AdjList));
CreateGraph(adj,&n);
DisplayGraph(adj);
}