刚在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 ++;
}
感觉可能前面有点啰嗦,如果还是不懂,请一定耐心在草稿纸上推一边过程,看各个数组的值,多试几个,你马上就懂了。