链式前向星存图
链式前向星存图
首先我们要开四个数组,分别为$head[a],to[i],nxt[i],val[i]$,表示以$a$为起点的第一条边的编号,第$i$条边所指向的点,第$i$条边的下一条边的编号,第$i$条边的权值。
我们是链表将一条边储存在数组之中。加边的时候有四条语序:
void add(int a,int b,int c) //表示将一条从a指向b的权值为c的有向边添加到链表之中
{
nxt[++idx]=head[a]; //idx为边的编号,++idx是将新边赋予编号,将新边的nxt指向原来head[a]指向的
//边的编号,这样能保证原来边的编号不失去。
to[idx]=b; //将新边的to赋值成为b,表示这条边指向b
val[idx]=c; //将新边的val赋值成为c,表示这条边的边权为c
head[a]=idx; //让head[a]指向当前边的编号,表示这条边是从a来的
}
我们应该怎么找到这些边呢?下面以找到$p$为开始点的所有边。
int main()
{
for(int i=head[p];i;i=nxt[i]) //我们可以通过head数组找到以p为开头的第一条边,并用nxt一直找下
//去,因为head数组最开始为0,所以当i等于0时,就是结束。
printf("%d %d %d
",p,to[i],val[i]);
}
这是链式前向星存储图,因为这是有向边,所以存储无向边是只需要拆成两条相反的有向边就可以,注意数组要开二倍。
链式前向星和邻接矩阵的对比
在边数远远小于点数的平方时,一般运用链式前向星来储存边,这样可以大大减小空间,但是链式前向星不能在$O(1)$时间内找到任意一条边。