邻接表数组模拟

刚在Acwing上看完Y总的教学,其中在模拟图的时候讲了数组模拟邻接表的方法,用了三个数组,一开始笨人蒙蔽了N久,后面手写推了一遍,理了理过程,现在才理解了,写个文章记个笔记,相信应该也有其他小伙伴第一次看到的时候挺蒙蔽,希望这篇文章能帮到你

知识点比较简单,图分为有向图无向图,无向图就是特殊的有向图,无向图其实就可以理解为双向图,所以会实现有向图,就可以实现无向图

我们使用三个数组,分为是数组e,数组ne,数组h,以及下标idx(注意!! 下标 idx 不等于 结点的编号,请一定要区分!!!!),来记录邻接表,然后再写一个add函数, add (int  a,  int  b)  目的是让编号为 a 的结点指向 编号为 b 的结点

插嘴一句,这里说一下各个数组以及下标idx的作用,结合后面的例子就更好理解了

首先是 h 数组,这个数组是一开始就要有的,因为邻接表每个编号对应的结点都要做一次头结点,然后这个头结点比如连了个A结点,那么头结点可以去往A结点。h 数组的初始值全部是 -1,意思是甚至为"空指针",因为还没往里插入(调用add)结点呢,所以当然都是空的了

既然是数组模拟邻接表,那我们知道,正常的链表都是一块一块或者说很多个结点连在一起的,那我们是怎么用数组表示的呢?

可以这样理解,每次调用add函数,可以看到idx都加了1,其实idx的值就代表了插入的结点的个数,idx的每个值对应一个插入的结点。

比如,idx = 5 的时候调用 add(7, 9)那么就会执行 e[5] = 9, ne[5] = h[7], h[7] = idx++;这样的语句,那么这是什么意思呢,就是当前要插入的这个结点,对应的图上的编号就是 9 ,那是谁指向这个对应图上编号 9 的结点,这个结点又指向谁呢,其实不难发现, h[7] 指向这个结点,这个结点指向原本编号为 7 的头队列指向的第一个结点。

什么意思?假设原本头结点 7 指向编号为10的结点,那邻接表中应该是这样

7 -> 10

之后 ne[5] = h[7] 也就是 idx == 5 的结点指向 头结点7 指向的首个结点,经过这一步,邻接表发生了变化,现在是这样子的连接情况

7 -> 10

9 -> 10

最后只需要让头结(对应图上编号7的点)指向图上编号为9的点

7 -> 9

再之后,这个链式关系就成了

7 -> 9 -> 10

下面看 add 函数的实现方法,其实很简单(%%%Y总)

//初始化变量
int h[N], e[M], ne[M], idx;
memset(h, -1, sizeof h);
//初始的时候,h数组中全为-1

//add函数的实现,让结点编号为a的结点指向结点编号为b的结点
void add(int a, int b){
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx ++;
}

感觉可能前面有点啰嗦,如果还是不懂,请一定耐心在草稿纸上推一边过程,看各个数组的值,多试几个,你马上就懂了。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值