链式前向星

转自B站的一个视频【AgOHの数据结构】你真的了解链式前向星吗?,感谢大佬们~

引言

无论是树,无向图,有向图,我们都需要使用一种数据结构来保存“图”(我们的树可以看作是特殊的图~)的结构,这种结构就是我们的链式前向星

我们如何存图?

1.邻接矩阵

在这里插入图片描述
如上图,使用邻接矩阵非常直观,但是它的空间复杂度达到了 O ( n 2 ) O(n^2) O(n2) 了。

2.邻接表

在这里插入图片描述
这种方法相比于邻接矩阵,它节约了很大的空间复杂度。实现邻接表常用的是使用vector数组,但是用时候vector数组的长度又会特别大。

若图是稀疏图,边很少,开二维数组a[][]很浪费;
若点很多(如10000个点),a[10000][10000]又会爆,只能用前向星做 (之前看过32M空间限制不要开超过 1000W 的int变量(C++))。
前向星的效率不是很高,优化后为链式前向星,直接介绍链式前向星。

所以,邻接表,邻接矩阵都不太好,大佬们就开发了一个新的存储图的数据结构——链式前向星。

3.链式前向星

其实,链式前向星就是一个邻接表。我们来对照看一下。
在这里插入图片描述

链式前向星在存储方面有两个部分组成。

(1)结构体E

struct E{
	int to,w,next;
}Edge[maxm];
int tot,Head[maxn];

有三个变量:

  • to:目的地,即边的destination;
  • w:边的权重,即weight;
  • next:下一个目的地的位置。

这三个变量,在前面的图中有体现,与邻接表进行了对应。

(2) Edge[maxm],totHead[maxn]

建立一个内存池Edge[maxm],有一个计数器变量tot指向内存池Edge[maxm]最近的没有被使用的结点,它是一个空结点。

Head数组是什么呢?
在这里插入图片描述
顾名思义,就是“头”(“首”),它在这个代码里面是Edge数组的下标,代表位置,初始化全部为-1(或者其他自定义也行)

(3) 遍历一个结点的所有边

我们来看一下如何遍历 一个结点u 所连向的所有的边的:

for(int i=Head[u];~i;i=Edge[i].next){
	int v = Edge[i].to;
	int w = Edge[i].w;
} 

(4) 加边函数AddEdge

链式前向星还有一个非常重要的加边函数AddEdge,那么它是如何运作的呢?

inline void AddEdge(int u,int v,int w){
	Edge[tot].to = v;
	Edge[tot].w = w;
	Edge[tot].next = Head[u];
	Head[u] = tot++; 
}

在这里插入图片描述
它不是在“链表”的最后插入的,而是在最前面插入的。

参考资料

  1. 【AgOHの数据结构】你真的了解链式前向星吗?
  2. 深度理解链式前向星
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值