数组邻接表储存图

图(有向图和无向图)的储存方法有邻接矩阵和邻接表两种储存方式。其中邻接表有两种实现方式:1.指针。2.数组
后者使用比较方便简洁,这里介绍一下用数组实现邻接表储存图
输入数据
4 5
1 4 9
4 3 8
1 2 5
2 4 6
1 3 7
4表示顶点个数 5表示输入的边数

用邻接表储存这个图,代码如下

#include<stdio.h>
int main(void)
{
 int n,m;//n表示顶点个数,m表示输入的边数; 这里用n=4(点),m=5(边);举例 
 int i,k;
 int u[6],v[6],w[6];//第一,二个数组是储存顶点的,第三个是储存该边的权值的;
 //这三个数组的大小要根据m来定,比m大一就行了;
 int first[5],next[6];
 //这两个数组也要看实际,first数组比n(顶点)大一,next数组比m(边)大一 
 scanf("%d %d",&n,&m);
 for(i=1;i<=n;i++)
 first[i]=-1;//初始化first数组,表示1~n顶点暂时还没有连接的边;
 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;//为边编号,保证遍历时u[],v[],w[]输出的准确 
 }
 printf("\n");
 /*其实就是 最终储存依次 从一个顶点出发的所有边(i其实就是这些边的编号) 
 下面是邻接表的遍历输*/
 for(i=1;i<=n;i++)
 {
  k=first[i];/*选出顶点 1 开始遍历  first可以理解为储存顶点编号,
  其实 也储存了最后一次输入边的编号*/ 
  while(k!=-1)//一直输出与该点连接的边直到没有(next【】==-1) 
  {
   printf("%d %d %d\n",u[k],v[k],w[k]);//其实k就是边的编号 
   k=next[k]; //变为该顶点连接的下一条边 的编号 
  }
 }
 return 0;
}

输入输出如下
在这里插入图片描述

first[5]= {5,4,-1,2}这里的值都是最后一次输入边的编号
next[6]={-1,-1,1,-1,3}
可以发现使用邻接表来储存图的时间空间复杂度是O(M),遍历每一条边的时间复杂度也是O(M)。如果是稀疏图的话,M要远小于N^2
我们可以使用邻接表来代替邻接矩阵降低时间复杂度,邻接表最坏的情况下才和邻接矩阵一样,但是一般情况下并不会有那么多边。

猜你喜欢

转载自blog.csdn.net/qq_43791377/article/details/86683159
今日推荐