巧妙使用邻接表存储图

在这里插入图片描述
这里用 u、v 和 w 三个数组用来记录每条边的具体信息,即 u[i]、v[i]和 w[i]表示 第i 条边是从第 u[i]号顶点到 v[i]号顶点(u[i]àv[i]),且权值为 w[i]。

再用一个 first 数组来存储每个顶点其中一条边的编号。以便待会我们来枚举每个顶点所有的边(你可能会问:存储其中一条边的编号就可以了?不可能吧,每个顶点都需要存储其所有边的编号才行吧!甭着急,继续往下看)。比如1号顶点有一条边是 “1 4 9”(该条边的编号是 1),那么就将 first[1]的值设为 1。如果某个顶点 i 没有以该顶点为起始点的边,则将 first[i]的值设为-1。现在我们来看看具体如何操作,初始状态如下。
在这里插入图片描述
读入第 1 条边(1 4 9),将这条边的信息存储到 u[1]、v[1]和 w[1]中。同时为这条边赋予一个编号,因为这条边是最先读入的,存储在 u、v 和 w 数组下标为 1 的单元格中,因此编号就是 1。这条边的起始点是 1 号顶点,因此将 first[1]的值设为 1。

另外这条“编号为 1 的边”是以 1 号顶点(即 u[1])为起始点的第一条边,所以要将 next[1]的值设为-1。也就是说,如果当前这条“编号为 i 的边”,是我们发现的以 u[i]为起始点的第一条边,就将 next[i]的值设为-1
在这里插入图片描述
读入第 2 条边(4 3 8),将这条边的信息存储到 u[2]、v[2]和 w[2]中,这条边的编号为 2。这条边的起始顶点是 4 号顶点,因此将 first[4]的值设为 2。另外这条“编号为 2 的边”是我们发现以 4 号顶点为起始点的第一条边,所以将 next[2]的值设为-1。
在这里插入图片描述
读入第 3 条边(1 2 5),将这条边的信息存储到 u[3]、v[3]和 w[3]中,这条边的编号为 3,起始顶点是 1 号顶点。我们发现 1 号顶点已经有一条“编号为 1 的边”了,如果此时将 first[1]的值设为 3,那“编号为 1 的边”岂不是就丢失了?我有办法,此时只需将 next[3]的值设为 1即可。现在你知道 next数组是用来做什么的吧。next[i]存储的是“编号为i的边”的“前一条边”的编号。
在这里插入图片描述
读入第 4 条边(2 4 6),将这条边的信息存储到 u[4]、v[4]和 w[4]中,这条边的编号为 4,起始顶点是 2 号顶点,因此将 first[2]的值设为 4。另外这条“编号为 4 的边”是我们发现以 2 号顶点为起始点的第一条边,所以将 next[4]的值设为-1。
在这里插入图片描述
读入第 5 条边(1 3 7),将这条边的信息存储到 u[5]、v[5]和 w[5]中,这条边的编号为 5,起始顶点又是 1 号顶点。此时需要将 first[1]的值设为 5,并将 next[5]的值改为 3。
在这里插入图片描述
此时,如果我们想遍历 1 号顶点的每一条边就很简单了。1 号顶点的其中一条边的编号存储在 first[1]中。其余的边则可以通过 next 数组寻找到。请看下图。
在这里插入图片描述
创建邻接表的完整代码如下:

//用邻接表存储图,降低时间复杂度 ,比较适用于稀疏图 
#include<iostream>
using namespace std;
int main()
{
	int u[6],v[6],w[6];
	int first[5],next[5];
	int n,m;
	cin>>n>>m;
	//first 数组初始化为-1,表示顶点之间没有边 
	for(int i=1;i<=5;i++)
	{
		first[i]=-1;
	}
	/*next存储编号为j的边的前一条边的编号
    如果当前这条“编号为j的边”,是我们发现的以u[j]为起始点的第一条边,
	就将next[i]的值设为-1
    */
	for(int j=1;j<6;j++)
	{
		cin>>u[j]>>v[j]>>w[j];
		next[j]=first[u[j]];
		first[u[j]]=j;
	}
	cout<<endl; 
	for(int i=1;i<6;i++)
	{
		int k=first[i]; //当前处理边的编号 
		 //当编号k不为-1时,即k不是以顶点i为起始点的第一条边时,执行whlle循环
		while(k!=-1)
		{
			cout<<u[k]<<" "<<v[k]<<" "<<w[k]<<endl;
			k=next[k];
		}
	}
	return 0;
}

在这里插入图片描述
可以发现使用邻接表来存储图的时间空间复杂度是 O(M),遍历每一条边的时间复杂度是也是 O(M)。如果一个图是稀疏图的话,M 要远小于 N2。因此稀疏图选用邻接表来存储要比邻接矩阵来存储要好很多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值