1、问题导入
链式前向星是引用在图上的一中特殊算法,如果用邻接矩阵(p[i][j]代表i点到j点的长度)来存储一张图,那么所占用的空间就是n2(n代表该图上点的个数),显然,n<=10000,而链式前向星来存储的话,就只有m的大小,对于大多数图(特例:完全图等)都比邻接矩阵所占空间小,更适合使用。
2、代码实现
链式前向星总的来说有两种方式:数组或结构体,而图又有有向图和无向图之分,博主就将这几种都列举出来了,共不同码风、不同需要的读者学习:
数组(有向图):
scanf("%d%d",&n,&m);//n个点,m条边 for(i=1;i<=m;i++) { scanf("%d%d%d",%x,&y,&z);//从x到y的长度为z; cnt++;//记录用 ne[cnt]=he[x];//前向,记录上一个 to[cnt]=y;//记录该边的指向 l[cnt]=z;//记录该边的长度 he[x]=cnt;//前向,更新点x的开始点 }
数组(无向图):
scanf("%d%d",&n,&m);//n个点,m条边 for(i=1;i<=m;i++) { scanf("%d%d%d",%x,&y,&z);//从x到y的长度为z; cnt++;//记录用 ne[cnt]=he[x];//前向,记录上一个 to[cnt]=y;//该边指向的点 l[cnt]=z;//长度 he[x]=cnt;//前向,更新点x的开始点 cnt++; ne[cnt]=he[y]; to[cnt]=x; l[cnt]=z; he[y]=cnt;//其实,无向图只是相当于加了x到y的有向边和y到x的有向边,相当于两条反向、同长度的边 }
数组(应用):
for (i=he[u];i;i=ne[i])//u点为端点 { int v=to[i];//v点是边i的指向 l[i]//u到v的长度 }
结构体(有向图):
scanf("%d%d",&n,&m);//n个点,m条边 for(i=1;i<=m;i++) { scanf("%d%d%d",%x,&y,&z);//从x到y的长度为z; cnt++;//记录用 bian[cnt].ne=he[x];//前向,记录上一个 bian[cnt].to=y;//该边指向的点 bian[cnt].l=z;//该边的长度 he[x]=cnt;//前向,更新点x的开始点 }
结构体(无向图):
scanf("%d%d",&n,&m);//n个点,m条边 for(i=1;i<=m;i++) { scanf("%d%d%d",%x,&y,&z);//从x到y的长度为z; cnt++;//记录用 bian[cnt].ne=he[x];//前向,记录上一个 bian[cnt].to=y;//该边指向的点 bian[cnt].l=z;//该边的长度 he[x]=cnt;//前向,更新点x的开始点 cnt++; bian[cnt].ne=he[y]; bian[cnt].to=x; bian[cnt].l=z; he[y]=cnt;//其实,无向图只是相当于加了x到y的有向边和y到x的有向边,相当于两条反向、同长度的边 }
结构体(应用):
for (i=he[u];i;i=bian[i].ne)//u点为端点 { int v=bian[i].to;//v点是边i的指向 bian[i].l//u到v的长度 }
博主码得喷血了……其实博主觉得这几种都差不多……
3、实际应用
这是博主自己写的最短路问题,其中,dijkstra的标准版就需要这种算法。