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

xiaoxiao2021-02-28  107

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

邻接表的实现需要四个东西,一个是记录边信息的数组、一个是表头、一个是当前操作边的序号、一个是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"); } }

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

转载请注明原文地址: https://www.6miu.com/read-48715.html

最新回复(0)