邻接矩阵看上去是个不错的选择,首先是容易理解,第二是索引和编排都很舒服但是我们也发现,对于边数相对顶点较少的图,这种结构无疑是存在对存储空间的极大浪费。
因此我们可以考虑另外一种存储结构方式,例如把数组与链表结合一起来存储,这种方式在图结构也适用,我们称为邻接表(AdjacencyList)。
基本思想:对图的每个顶点建立一个单链表,存储该顶点所有邻接顶点及其相关信息。
每一个单链表设一个表头结点。
第i个单链表表示依附于顶点Vi的边(对有向图是以顶点Vi为头或尾的弧)。
图的邻接表存储法,又叫链式存储法。本来是要用链表实现的,但大多数情况下只要用数组模拟即可。
l邻接表(有向图)
l邻接表的处理方法是这样:
l图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过数组可以较容易地读取顶点信息,更加方便。
l图中每个顶点Vi的所有邻接点构成一个线性表,由于邻接点的个数不确定,所以我们选择用单链表来存储。
以下是用数组模拟邻接表存储的参考程序段(代码~):
#include<iostream> #include<cstdio> using namespace std; const int Maxn=1001; const int Maxm=100001; /* 样例 4 5 1 4 9 4 3 8 1 2 5 2 4 6 1 3 7 */ struct Edge{ int next;//边指针,指向下一条边的内存地址 int v; int u;//边所邻接的两个顶点 }edge[Maxm]; int num;//进行记录(内存的指针) int head[Maxn],n,m; void add(int uu,int vv,int dd) { edge[++num].next=head[uu]; edge[num].u=uu; edge[num].v=vv; head[uu]=num; } int main() { int uu,vv,dd; scanf("%d %d",&n,&m);//读入点数和边数 for(int i=1;i<=m;i++) { scanf("%d %d %d",&uu,&vv,&dd); add(uu,vv,dd); } cout<<"1"; for(int i=head[1];i!=0;i=edge[i].next) {//遍历从点1开始的所有边 cout<<"->"<<edge[i].v; } return 0; }