链式前向星
示意图
链式前向星的代码非常模板话,但是在初学截断单看代码很难理解其中的原理。
下面着重对第 1 步和第 4 步的建图进行阐述:设为 0。
选取最近未使用的边的空间,此时边号 idx=02 有一条权值为 3 的边。
选取最近未使用的边的空间,此时边号idx=0
在 idx=0 处存储入度点 2 和权值 3
将 idx=0 处 nex 位置存为 head[0]=-1
将 head[0] 更新为当前的边号 idx=0
第 4 步[0, 3, 5] 表示 0 到 3 有一条权值为 5 的边。
选取最近未使用的边的空间,此时边号 idx = 3
在 idx=3 处存储入度点 2 和权值 3
将 idx=3 处 nex 位置存为head[0]=0 (注意,这是第 1 步时,存储的值)
将 head[0] 更新为当前的边号 idx=3
由于 head 数组始终指向最后存储的位置。因此在遍历 head[from] 时,与存储的顺序时相反的。(而邻接表在遍历时与存储顺序一致)
聪明的读者应该已经发现了,其实链式前向星就是另一种表现形式的邻接表。
数据结构
struct Edge {
int to; // 入度点
int val; // 权值
int nex; // 下一个节点
};
Edge edge[边数];
int head[点数];
int tot = 0; // 使用到了第几条边
操作
// 添加边
void addEdge(int from, int to, int value) {
// 根据tot的初始值确定使用的第一条边的边号
tot += 1;
edge[tot].to = to;
edge[tot].val = value;
edge[tot].nex = head[from];
head[from] = tot;
}
// 遍历
for (int i = head[from]; /*根据head初始值作为终止条件*/; i = edge[i].nex) {
int to = edge[i].to;
int val = edge[i].val;
}
