深度理解链式前向星

来源:互联网 发布:二战德国知乎 编辑:程序博客网 时间:2024/06/05 21:03

转载出自http://blog.csdn.net/acdreamers/article/details/16902023#comments


我们首先来看一下什么是前向星.


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

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


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

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


那么对于下图:





我们输入边的顺序为:


1 2

2 3

3 4

1 3

4 1

1 5

4 5


那么排完序后就得到:


编号:     1      2      3      4      5      6      7

起点u:    1      1      1      2      3      4      4

终点v:    2      3      5      3      4      1      5


得到:


head[1] = 1    len[1] = 3

head[2] = 4    len[2] = 1

head[3] = 5    len[3] = 1

head[4] = 6    len[4] = 2


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



如果用链式前向星,就可以避免排序.


我们建立边结构体为:


struct Edge

{

     int next;

     int to;

     int w;

};


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


另外还有一个数组head[],它是用来表示以i为起点的第一条边存储的位置,实际上你会发现这里的第一条边存储的位置其实

在以i为起点的所有边的最后输入的那个编号.


head[]数组一般初始化为-1,对于加边的add函数是这样的:


[cpp] view plain copy
  1. void add(int u,int v,int w)  
  2. {  
  3.     edge[cnt].w = w;  
  4.     edge[cnt].to = v;  
  5.     edge[cnt].next = head[u];  
  6.     head[u] = cnt++;  
  7. }  

初始化cnt = 0,这样,现在我们还是按照上面的图和输入来模拟一下:


edge[0].to = 2;     edge[0].next = -1;      head[1] = 0;

edge[1].to = 3;     edge[1].next = -1;      head[2] = 1;

edge[2].to = 4;     edge[2],next = -1;      head[3] = 2;

edge[3].to = 3;     edge[3].next = 0;       head[1] = 3;

edge[4].to = 1;     edge[4].next = -1;      head[4] = 4;

edge[5].to = 5;     edge[5].next = 3;       head[1] = 5;

edge[6].to = 5;     edge[6].next = 4;       head[4] = 6;


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


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

比如以上图为例,以节点1为起点的边有3条,它们的编号分别是0,3,5   而head[1] = 5


我们在遍历以u节点为起始位置的所有边的时候是这样的:


for(int i=head[u];~i;i=edge[i].next)


那么就是说先遍历编号为5的边,也就是head[1],然后就是edge[5].next,也就是编号3的边,然后继续edge[3].next,也

就是编号0的边,可以看出是逆序的.

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怀孕的猫生病了怎么办 宝宝生病咳嗽啥都不吃怎么办 怀孕了感冒了怎么办啊 2个月宝宝生病了怎么办 刚刚怀孕了就生病了怎么办 一岁多宝宝总是发烧咳嗽生病怎么办 7个月宝宝生病怎么办 4个月宝宝老是生病怎么办 孕早期嗓子有痰怎么办 鼻炎早晨起床鼻涕带血怎么办 鼻子破皮了结痂怎么办 擤鼻子耳朵好像堵住了怎么办 鼻子和脸上起皮怎么办 鼻子擦鼻涕擦红怎么办 鼻子下面擦红了怎么办 鼻子擤鼻涕破皮怎么办 哭完鼻子不通气怎么办 擦鼻子擦多了疼怎么办 擤鼻涕时耳朵听不见了怎么办 吸鼻涕耳朵感觉被塞怎么办 擤鼻涕多了头疼怎么办 鼻子擤出鼻息肉怎么办 擤鼻涕鼻子破了怎么办 下水道里有鼻涕虫的怎么办 家里井口处有很多鼻涕虫怎么办 花生地里有蜗牛怎么办 菜园里有好多虫怎么办 心里莫名的急该怎么办 老感觉心烦气燥怎么办 什么事都不想做怎么办心里烦躁 咳嗽流鼻涕身体发热怕冷怎么办 不感冒流清鼻涕怎么办 刚怀孕感冒了怎么办鼻塞流鼻涕 孕妇打喷嚏流鼻涕怎么办速效办法 宝宝流鼻涕一个月了怎么办 一个月婴儿感冒咳嗽流鼻涕怎么办 怎么办感冒能好得快些 一个月的宝宝流鼻涕怎么办 鼻炎犯了一直流鼻涕怎么办 宝宝流鼻涕鼻子擦破了怎么办 宝宝流鼻涕鼻子擦红了怎么办