邻接表

来源:互联网 发布:htconemini知乎 编辑:程序博客网 时间:2024/06/09 18:52





用邻接表存储图:

n代表顶点个数(编号1~n),m表示边的条数,接下来有m行。

例如 

4 5

1 4 9

4 3 8

1 2 5

2 4 6

1 3 7


用邻接表来存储这个图的代码如下:

int n,m,i;int u[111],v[111],w[111];//数组大小设置要比m的最大值大1 int first[111],next[111];//要比n的最大值大1scanf("%d%d",&n,&m);for(i=1;i<=n;i++){//1~n顶点暂时都没有边 first[i]=-1;} for(i=1;i<=m;i++){scanf("%d%d%d",&u[i],&v[i],&w[i]);next[i]=first[u[i]];first[u[i]]=i;} 

这是用数组实现邻接表,而没有使用真正的指针链表,按照读入的顺序为每一条边进行编号(1~m),first数组的1~n号单元格分别用来存储1~n号顶点的第一条边的编号,初始时因为没有边加入所以都是-1,first[ u[i] ]保存顶点u[i]的第一条边的编号,next[i]存储“编号为i”的“下一条边”的编号。

读入第一条边:i=1,是以1号顶点(u[1]=1)为起始点的第一条边,next[1]=-1,first[1]=1;

读入第二条边:i=2,是以4号顶点(u[2]=4)为起始点的第一条边,next[2]=-1,first[4]=2;

读入第三条边:i=3,是以1号顶点(u[3]=1)为起始点的第二条边,next[3]=1,first[1]=3;

读入第四条边:i=4,是以2号顶点(u[4]=2)为起始点的第一条边,next[4]=-1,first[2]=4;

读入第五条边:i=5,是以1号顶点(u[5]=1)为起始点的第三条边,next[5]=3,first[1]=5;


那么如何遍历每一条边呢?比如1号顶点的第一条边是编号为5的边(1,3,7),2号顶点的第一条边是编号为4的边(2,4,6),3号顶点没有出向边,4号顶点的第一条边是编号为2的边(2,4,6)。  在找到1号顶点的第一条边后,剩下的边都可以在next数组中依次找到。如右上图所示

此时遍历某个顶点的边的时候的遍历顺序正好与读入的顺序相反,因为在为每个顶点插入边的时候都是直接插入“链表”的首部而不是尾部,遍历每个顶点的边,其代码如下:

for(i=1;i<=n;i++){k=first[i];while(k!=-1){printf("%d %d %d\n",u[k],v[k],w[k]);k=next[k];    }}