这是C++算法基础-搜索与图论专栏的第四十篇文章,专栏详情请见此处。
引入
在算法基础课的课程中,接下来会直接讲树与图的遍历,并没有专门讲树与图的存储,但想要对图进行操作,就需要先学习图的存储方式,所以我们今天单独来讲一下树与图的存储(其实这一部分也有讲解,只不过不在打卡题目的视频题解中,你可以在录播回放中看到)。
下面我们就来讲树与图的存储的实现。
过程
基本且常见的存储方式有两种:邻接矩阵和邻接表。
邻接矩阵
这个名字看上去很高端,说白了就是一个二维数组,存储边
上的权重,需要注意的是,若被存储的图是无向图,则需要对
和
两个位置进行操作。
邻接矩阵只适用于没有重边(或重边可以忽略)的情况。其最显著的优点是可以快速(在的时间内)查询一条边是否存在。但由于邻接矩阵在稀疏图上效率很低(尤其是在点数较多的图上,空间无法承受),所以一般只会在稠密图上使用邻接矩阵。
邻接表
邻接矩阵虽然很好写,但是浪费空间,这时,我们需要一种空间利用率高的方法,邻接表就很好。
对于每个点,开一个单链表,存储这个点所有可以走到的点。然后我们定义几个数组与变量,h数组存储每个点的单链表头结点,e数组存储边的终点,ne数组存储下一个边结点的索引,idx表示当前已经使用的边的数量,用于分配新边。
当我们想要增加一条边时,我们先将边的终点存入e数组的idx位置;然后,新边的next数组更新为这条边起点原来的头节点(链表插入头部);更新顶点a的头节点为当前边;最后,将idx自增以备下次使用。
此外,使用前不要忘记初始化。
下面给出邻接表的实现代码:
int h[N],e[N],ne[N],idx;
void add(int a,int b){
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
idx=0;
memset(h,-1,sizeof(h));
上一篇- C++算法基础专栏文章 下一篇-
每周六更新一篇文章,内容一般是自己总结的经验或是在其他网站上整理的优质内容
点个赞,关注一下呗~