对于图来说,邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的。因此我们考虑另外一种存储结构方式:邻接表(Adjacency List),即数组与链表相结合的存储方法。
邻接表的处理方法是这样的。
1、图中顶点用一个一维数组存储,另外,对于顶点数组中,每个数据元素还需要存储指向第一个邻接点的指针,以便于查找该顶点的边信息。
2、图中每个顶点vi的所有邻接点构成一个线性表,由于邻接点的个数不定,所以用单链表存储,无向图称为顶点vi的边表,有向图称为顶点vi作为弧尾的出边表。
例如图7-4-6就是一个无向图的邻接表结构。
若是有向图,邻接表的结构是类似的,如图7-4-7,以顶点作为弧尾来存储边表容易得到每个顶点的出度,而以顶点为弧头的表容易得到顶点的入度,即逆邻接表。
对于带权值的网图,可以在边表结点定义中再增加一个weight的数据域,存储权值信息即可,如图7-4-8所示。
下面示例无向图的邻接表创建:
#include<iostream>
#include<stdlib.h>
#define MAXVEX 10/*最大顶点数*/
#define INFINITY 65656/*表示权值无穷*/
using namespace std;
typedef int EdgeType;
typedef char VertexType;
typedef struct EdgeNode /*边表结点*/
{
int adjvex;//存放结点下标
struct EdgeNode *next;//边表指针
}EdgeNode;
typedef struct VertexNode/*顶点表结点*/
{
VertexType data;//元素
EdgeNode *first;//边表头指针
} VertexNode,AdjList[MAXVEX];
typedef struct
{
AdjList adjList; //结构体数组
int numNodes,numEdges;/*图中当前顶点数和边数 */
}GraphAdjList;
/*建立无向图的邻接表表示*/
void CreateALGraph(GraphAdjList *Gp)
{
int i,j,k;
EdgeNode *pe;
cout<<"请输入顶点数和边数(空格分隔):"<<endl;
cin>>Gp->numNodes>>Gp->numEdges;
cout<<"请输入顶点信息"<<endl;
for(i=0;i<Gp->numNodes;i++) //输入顶点
cin>> Gp->adjList[i].data;
Gp->adjList[i].first=NULL; /*将边表置为空表*/
/*建立边表*/
for(k=0;k<Gp->numEdges;k++)
{
cout<<"请输入边(Vi,Vj)的顶点序号i,j(从0开始,空格分隔,i≠j,且i,j<"<<Gp->numNodes<<")"<<endl;
cin>>i>>j;
pe=(EdgeNode *)malloc(sizeof(EdgeNode));
pe->adjvex=j;//邻接序号为j
pe->next=Gp->adjList[i].first;
Gp->adjList[i].first=pe;
}
}
int main(void)
{
GraphAdjList Gp;
CreateALGraph(&Gp);
return 0;
}