用数组实现邻接表(c++)

图的邻接矩阵存储法,它的空间和时间复杂度都是N^2,而存储图的方法:邻接表,时间空间复杂度优化为O(M)。对于稀疏图来说,M要远远小于N ^ 2。最坏的情况下M就是N ^2,但多数情况下不会有那么多边。
先上数据:
4 5
1 4 9
4 3 8
1 2 5
2 4 6
1 3 7

第一行两个整数n m,n代表顶点个数(1-n),m代表边的条数,接下来m行,每行三个数x y z,表示定点x到定点y的距离为z。下面是用数组来实现邻接表的创建。

  int n,m,i;
  //u、v和w的数组大小要根据实际情况来设置,要比m的最大值要大1
  int u[6],v[6],w[6];
  //first和next的数组大小要根据实际情况来设置,要比n的最大值要大1
  int first[5],next[5];
  cin>>n>>m;
 //初始化first数组下标1~n的值为-1,表示1~n顶点暂时都没有边
  for(i=1;i<=n;i++)
      first[i]=-1;
 for(i=1;i<=m;i++)
 {
     cin>>u[i]>>v[i]>>w[i];//读入每一条边
     //下面两句是关键
     next[i]=first[u[i]];
     first[u[i]]=i;
 }

用u 、v、w三个数组来记录每条边的信息,即u[i]、v[i]、w[i]表示第i条边是从第u[i]号顶点到v[i]号顶点,权值为w[i],first数组的1-n号单元格分别来存储1-n号顶点的第一条边的编号,初始时都是-1。即first[u[i]]保存顶点u[i]的第一条边的编号,next[i]存储编号为i的边的前一条边的编号

编号为1的边是以1号顶点(即u[1])为起始点的第一条边,所以要将next[1]的值设为-1。
在这里插入图片描述

读入第2条边(4 3 8)
在这里插入图片描述

读入第3条边(1 2 5),将这条边的信息存储到u[3]、v[3]和w[3]中,这条边的编号为3,起始顶点是1号顶点。我们发现1号顶点已经有一条“编号为1 的边”了,此时将first[1]的值设为3,将next[3]的值设为1。next[i]存储的是“编号为i的边”的“前一条边”的编号。
在这里插入图片描述

读入第4条边(2 4 6)
在这里插入图片描述
读入第5条边(1 3 7),将这条边的信息存储到u[5]、v[5]和w[5]中,这条边的编号为5,起始顶点又是1号顶点。此时需要将first[1]的值设为5,并将next[5]的值改为3。
在这里插入图片描述

此时,如果4想遍历1号顶点的每一条边就很简单了。1号顶点的其中一条边的编号存储在first[1]中。其余的边则可以通过next数组寻找到
在这里插入图片描述

k=first[1];
while(k!=-1)
{
	cout<<u[k]<<v[k]<<w[k]<<endl;
	k=next[k];
}	

接下来就是如何遍历每一条边

 for(i=1;i<=n;i++)
 {
     k=first[i];
     while(k!=-1)
     {
         cout<<u[k]<<v[k]<<w[k]<<endl;
         k=next[k];
     }
 }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值