C++邻接表(利用数组实现)

邻接表用来储存稀疏图很好(图为G<V,E>,若E<<V²,即边数小,则称为稀疏图),下面解释一下啊哈算法上关于邻接表的代码,有点绕。

首先需要2个数组,first[]和next[],first的作用是找某一点的第一条边(其实最后遍历邻接表是以读入的反方向来遍历的,比如1顶点的2条出边 1 4 9和1 2 5,输入顺序是1 4 9先,1 2 5 后,但遍历是先遍历1 2 5,再遍历1 4 9,所以这里用“某一点的第一条边”来解释也不太好,只能说能在first开始,找到所有边…),next的作用当然是往下找这个点所有的出边啦

//核心代码
for(int i=1;i<=m;i++)
	{
		cin>>u[i]>>v[i]>>w[i];
		next[i]=first[u[i]];
		first[u[i]]=i;
	}

啊哈first数组是初始化为-1,个人感觉没必要,直接默认0就行了
所以图中-1均改为0
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以上为读入的步骤,主要是理解这种方法的巧妙之处,如果理解不了也没事,就两句话,背过就行了(我就是背的)…

接下来是遍历(输出)过程

//核心代码
for(int i=1;i<=n;i++)
	{
		int k;
		k=first[i];//first的作用是找某一点的第一条边
		while(k!=0)
		{
			cout<<u[k]<<" "<<v[k]<<" "<<w[k]<<endl;
			k=next[k];//next作用是接着找该点所有出边
		}
	}

在这里插入图片描述

完整代码

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n,m;
	int u[99],v[99],w[99];
	int first[99]={0},next[99]={0};
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>u[i]>>v[i]>>w[i];
		next[i]=first[u[i]];
		first[u[i]]=i;
	}
	for(int i=1;i<=n;i++)
	{
		int k;
		k=first[i];
		while(k!=0)
		{
			cout<<u[k]<<" "<<v[k]<<" "<<w[k]<<endl;
			k=next[k];
		}
	}
	return 0;
}

样例
4 5
1 4 9
4 3 8
1 2 5
2 4 6
1 3 7

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C++ 中,我们可以使用邻接表来存储有向图。邻接表是一种基于链表的数据结构,它可以有效地存储图中的节点和边,并提供快速的遍历和搜索。 邻接表由一个数组和一个链表组成。数组的每个元素对应一个图中的节点,而链表则包含从该节点出发的所有边。具体实现过程如下: 1. 定义一个结构体来表示图中的边: ``` struct Edge { int to; // 边的终点 int weight; // 边的权重(如果有) Edge* next; // 指向下一条边的指针 }; ``` 2. 定义一个数组来存储节点和指向其邻接表的指针: ``` const int MAXN = 100; // 最大节点数 Edge* head[MAXN]; // 每个节点指向其邻接表的头指针 ``` 3. 对于每个节点,初始化其邻接表为空: ``` for (int i = 0; i < MAXN; i++) { head[i] = nullptr; } ``` 4. 对于每条边,创建一个新的 `Edge` 结构体,并将其添加到起点节点的邻接表中: ``` void addEdge(int from, int to, int weight) { Edge* e = new Edge; e->to = to; e->weight = weight; e->next = head[from]; head[from] = e; } ``` 完整代码如下: ``` #include <iostream> using namespace std; const int MAXN = 100; // 最大节点数 struct Edge { int to; // 边的终点 int weight; // 边的权重(如果有) Edge* next; // 指向下一条边的指针 }; Edge* head[MAXN]; // 每个节点指向其邻接表的头指针 void addEdge(int from, int to, int weight) { Edge* e = new Edge; e->to = to; e->weight = weight; e->next = head[from]; head[from] = e; } int main() { // 添加边 addEdge(0, 1, 1); addEdge(0, 2, 2); addEdge(1, 2, 3); addEdge(2, 3, 4); // 输出邻接表 for (int i = 0; i < MAXN; i++) { if (head[i] != nullptr) { cout << i << ": "; for (Edge* e = head[i]; e != nullptr; e = e->next) { cout << "(" << e->to << ", " << e->weight << ") "; } cout << endl; } } return 0; } ``` 这个程序将会输出以下内容: ``` 0: (2, 2) (1, 1) 1: (2, 3) 2: (3, 4) ``` 其中,每行表示一个节点的邻接表,格式为 `节点编号: (邻居节点编号, 边权重) ...`。例如,第一行表示节点 0 与节点 2 之间有一条边权重为 2 的边,与节点 1 之间有一条边权重为 1 的边。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值