图的表示
对于一张图 ,可以用两种标准的表示方法表示。一种是将图作为邻接链表的组合,另一种则是将图作为邻接矩阵来看待两种表示方法都可以表示无向图和无向图。当图为稀疏图时(边的条数 远远小于点的数量 的图)时通常采用邻接链表,如此节省空间开销。反之,当图为稠密图( 接近 的图)的情况下,则采用邻接矩阵。此外,如果需要直接判断任意两个结点之间是否有边连接,可能也要用邻接矩阵。
对于图 来说,其邻接链表表示由一个包含 个链表的数组 所组成,其中每个节点都有一条链表。对于每个节点 ,邻接链表 包含所有与节点u之间有边相连的节点v,即 包含图 中所有与u邻接的节点(也可以说,该链表里包含指向这些节点的指针)。每个邻接链表中的顶点一般以任意顺序存储。
- 如果 是一个无向图,那么所有邻接表的长度之和为 ,因为如果 是一条无向边,那么u会出现在v的邻接表中,v也会出现在u的邻接表中。
- 如果 是一个有向图,则对于边 中,节点v将会出现在u的邻接表里,因此,所有邻接链表的长度之等于
- 但不管是有向图还是无向图,邻接表需要的存储空间均为 。
- 对邻接表稍作变动,即可用来表示加权图,即每条边都有着相应权值的图,权值通常由加权函数 给出。例如,设 是一个加权函数为w的加权图。对每一条边 ,权值 和顶点 一起存储在 的邻接表中。
邻接矩阵存边Code
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,u,v,w,a[1000][1000];
int main(){
scanf("%d%d",&n,&m);//给出n个点,m条边,要求建立邻接表存图
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);//表示u和v连了一条权值为w的边
a[u][v]=a[v][u]=w;//无向边,表示u向v连了一条w的边,v也向w连了一条w的边
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%d",a[i][j]);
//打印邻接矩阵,表示i向a[i][j]连了一条权值为val[i][j]的边
}
printf("\n");
}
//如果要找与节点x相连的边有哪些
for(int i=1;i<=n;i++){
if(a[x][i]>0){
printf("%d %d %d\n",x,i,a[x][i]);
}
}
return 0;
}
邻接链表存边Code
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,u,v,w,a[1000][1000],val[1000][1000],sum[1000];
int main(){
scanf("%d%d",&n,&m);//给出n个点,m条边,要求建立邻接表存图
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);//表示u和v连了一条权值为w的边
sum[u]++;a[u][sum[u]]=v;val[u][sum[u]]=w;
sum[v]++;a[v][sum[v]]=w;val[v][sum[v]]=w;
//无向边,表示u向v连了一条w的边,v也向w连了一条w的边
}
for(int i=1;i<=n;i++){
for(int j=1;j<=sum[i];j++){
printf("%d %d %d\n",i,a[i][j],val[i][j]);
//打印邻接表,表示i向a[i][j]连了一条权值为val[i][j]的边
}
printf("\n");
}
//如果要找与节点x相连的边有哪些
for(int i=1;i<=sum[x];i++){
printf("%d %d %d\n",x,a[x][i],val[x][i]);
}
return 0;
}
作者:zsjzliziyang
QQ:1634151125
转载及修改请注明
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/82023122