一、概述
链式前向星是一种用于存图的数据结构,与邻接矩阵和邻接表有着明显区别,他不会像邻接矩阵一样对于空间的极大浪费,同时也比邻接表更加适合用于深度优先搜索和广度优先搜索。它是一种在时间和空间上最优的存图结构。无论是建图还是遍历图效率最高的存图的方式。
二、代码
链式前向星的代码有一个边集结构体Edge数组和一个head数组组成。
其中Edge结构体代码为:
struct Edge{
int next;//next是与这条同起点的边的储存位置,通过递归将会将所有与此边起点相同的边全部找出
int to;//这是这条边的终点;
int w;//这是边权
}edge[maxn];
head数组就是每次将与此点相同起点的边所在edge[]数组中所在的位置记录下来,方便递归寻找。
head数组重置
memset(head,-1,sizeof(head));//一般重置为-1;如果是重置为0时注意边集必须从1开始,不然都会指向第0条边
链式前向星的建立
int cnt=1;
void add(int u,int v,int w)
{
edge[cnt].to=v;//表示当前起点能到的边
edge[cnt].next=head[u];//head[u]表示与edge[cnt](当前边)相同起点的边所在边集的储存位置
edge[cnt].w=w;
head[u]=cnt++;
}
举个栗子:
输入三组数据:
1 2 0
1 4 0
1 6 0
开始手动模拟:
-
edge[1].to=2,edge[1].next=-1,head[1]=1;//显而易见与当前边同起点的只有自己了。。。
-
edge[2].to=4,edge[2].next=1,head[1]=2;
-
edge[3].to=6,edge[3].next=2,head[1]=3;//可见的递归head[1]=3->2->1->(-1)就把当前以1点为起点的边全找出来了
链式前向星的遍历
for(int i=head[u];i>0;i=edge[i].next)//寻找以点u为起点的所有边,由栗子可见最终结束是-1的。
从递归的角度来说这个找边:首先我们存图的时候是根据每一次遇到相同的起点边就使本条边的next(也就是edge[x].next)指向上一条边的位置。由于储存位置呈递增状态,也就是一开始找时i是最大的且不断递归变小,直到为负数时遍历完毕。
三、总结
链式前向星的head[x]在我看来就是一个时刻指向最大的由x可以到达的点的指针,不断往后寻找相同起点的边然后指向最大可达点,询问时只需要进行递归既可。