链式前向星

Posted yodel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链式前向星相关的知识,希望对你有一定的参考价值。

关于前向星


 

 

前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序,

并记录下以某个点为起点的所有边在数组中的起始位置和存储长度,那么前向星就构造好了.

用len[i]来记录所有以i为起点的边在数组中的存储长度.

用head[i]记录以i为边集在数组中的第一个存储位置.

 

前向星的实现


 

 

先举个例子吧,给一个有向图,读入各边的起点和终点

 

 

 

边数:7
起点    终点
1        2
2        3
3        4
1        4
4        5
5        1
5        3

我们先把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序

排序后得到:

1: 1 2
2: 1 4
3: 2 3
4: 3 4
5: 4 5
6: 5 1
7: 5 3

然后我们用len,head数组进行存储操作

head[1]=1,len[1]=2
head[2]=3,len[2]=1
head[3]=4,len[3]=1
head[4]=5,len[4]=1
head[5]=6,len[5]=2

这样的储存方式很直观,一般的新手都喜欢用

但是利用前向星会有排序操作,如果用快排时间至少为O(nlog(n))

这时候我们就需要引入一个更加优秀的算法——链式前向星

 

链式前向星


 

 

由于在很多图论算法中都要用到链式前向星的存储方式,所以正确深入地理解链式前向星是每一个OIer都应该做到的

先来看看代码

先建个结构体

struct Edge{
    int next,to;
    int w;//this is the weight of each edge
}edge[M+5];//M is the total_number of the graph_edges

 

其中edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的下一条边的存储位置,edge[i].w为边权值.

然后再加一个head数组,用head[i]记录以i为边集在数组中的最后一个存储位置.

int head[M];//M is the total_number of the graph_edges

有了结构体,我们该如何建边呢,别着急,先放上代码

int cnt=0;
void add(int u,int v,int w){
    edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;
}

 

很明显,head[i]保存的是以i为起点的所有边中编号最大的那个,而把这个当作顶点i的第一条起始边的位置.

这样在遍历时是倒着遍历的,也就是说与输入顺序是相反的,不过这样不影响结果的正确性.

建好了边,我们又改如何遍历呢

for(int u=1;u<=n;u++)//n is the total_number of points
for(int i=head[u];~i;i=edge[i].next)

至此,基础概念的讲解就结束了

以上是关于链式前向星的主要内容,如果未能解决你的问题,请参考以下文章

前向星和链式前向星

前向星链式前向星实现以及它的遍历

链式前向星

图的存储:链式前向星(边集数组)

链式前向星

链式前向星