码迷,mamicode.com
首页 > 其他好文 > 详细

浅谈图的前向星遍历

时间:2015-02-26 16:45:43      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:前向星

个人见解,如有错误,欢迎指出。

作为一个算法新手,我就从我个人的角度来讲述前向星这种算法,我看到大多数都是建立一个边集的结构体,然后在结构体内放入边指向结点,边的前驱,和边权:

例如:

struct edge{//建立一个边集结构体
    int next;//好一点的把next换成了pre,从字面上来讲更好理解
    int w;//边的权值
    int v;//边指向结点,有的写成to
}e[maxn];

 

当然对于一个已经懂得了前向星的人来讲,这种写法也还是比较好理解的。下面进入主题:

同样的我们还是建立一个结构体,但是,我们把名字改成graph,没错,就是graph。表明我们是对一个图进行操作。

 

由于前向星是一种反向遍历的方式,我们把相应的next和v改成front和to,这样从字面生更好理解。我们按输入顺序对每条边赋予一个值,表明是第几条输入边(也就是说每条边都有一个独一无二的IP地址了)

即:使用链表方式存储图的边。last[i]用来记录以i为起点且为最后输入的一条边,front[j] 表示边j的前一条边(这里的前一条边不仅仅是指输入顺序在j的前面,而且还得和j拥
       有相同的起点),to[j]表示第j条边所指向的结点编号。即:令addr=last[i],之后不断用 addr=front[addr]即可得到链表中所有以结点i为起点的所有“边集的编号”,其中 
        to[addr]表示对应边指向的结点编号。那么这样做有什么用呢?比如我们想知道有没有一条从u到v的边,我们只需要这样遍历所有从u出发的边,看有无终点是v即可。

代码:

struct graph{
    int last[maxn],front[maxn],to[maxn],w[maxn],cnt;
    void init(){//初始化
        memset(front,-1,sizeof(front));//-1表示某条边不存在前驱边
        memset(to,0,sizeof(to));
        memset(last,0,sizeof(last));
        cnt=0;
    }
    void add(int u,int v,int W){
        cnt++;//使边的编号从1开始
        to[cnt]=v;//记录该边的指向结点
        w[cnt]=W;//记录该边的权值
        front[cnt]=last[u];//用尾插法把该边放入以u为起点的边集中
        last[u]=cnt;//更新以u为起点且为最后输入的边
        //如果是无向图,加入下面这句话
        /*
        swap(u,v);
        cnt++;
        to[cnt]=v;
        w[cnt]=W;
        front[cnt]=last[u];
        last[u]=cnt;
        */
    }
}G;


好了我的讲述就到这里了吧,个人认为这种写法还是比较好理解的,代码嘛也不是很长。

 

浅谈图的前向星遍历

标签:前向星

原文地址:http://blog.csdn.net/i_am_a_winer/article/details/43952457

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!