一种经典的邻接表的实现和遍历方式

来源:互联网 发布:linux 文件写权限 编辑:程序博客网 时间:2024/06/09 21:45


邻接表不和邻接矩阵只和点有若干联系,它和点与边都有密切的联系。

邻接表的实现需要四个东西,一个是记录边信息的数组、一个是表头、一个是当前操作边的序号、一个是add函数。(当然也少不了初始化函数了)

具体如下。

int which=1;int head[maxv];struct EDGE{    int d,w,next;    EDGE():next(-1){}}e[maxv];void add(int s, int d,int w){    e[which].d=d;    e[which].w=w;    e[which].next=head[s];    head[s]=which++;}void initforgraph(){    memset(head,-1,sizeof(head));    memset(e,0,sizeof(e));}

which表示当前操作的是哪一条边(是边的序号)(有些人喜欢用size、用n,其实都是习惯问题了。which到最后输入结束的时候也是边的数量)

head是表头,head【2】表示以2为起点的边的表。

e数组是记录边信息的,但是由于邻接表的特殊性,我们只需要记录他的终点、权值和下一条边的序号,而不是像克鲁斯卡尔算法中经典地储存起点、终点、权值这样子。

在插入边表的时候是前叉式,所以代码看上去好像是有点绕。

不了解前叉式建表的话建议先去看看链表的插入的几种方式。

这里注意下head一定要初始化为-1的。

不了解邻接表的话,也比较难看懂代码,建议学一下数据结构的图的相关知识。

当然这种实现方式不是使用教科书上的指针的实现方式,而是用数组模拟的。他们使用起来是一样的效果。



下面是遍历方式。

其实使用邻接表的图的遍历方式很像是BFS,由一个点发散的遍历他相邻的点(边)。

遍历方式是基于我上面给出的邻接表的实现方式的。


int main(){    initforgraph();    int t1,t2,t3;    for(int i=1;i<=M;i++)//M is the number of edges.    {        scanf("%d%d%d",&t1,&t2,&t3);//start, end, weight.        add(t1,t2,t3);    }    for(int i=1;i<=N;i++)    {        printf("起点是%d有\n",i);        for(int j=head[i];j!=-1;j=e[j].next)        {            printf("编号为%d的边\n",j);        }        printf("\n");    }}

下面的第一重循环是对所有的点进行循环,第二重循环是对以这个点为起点的所有的边的循环。


原创粉丝点击