邻接矩阵&邻接表

邻接矩阵

逻辑结构分为两部分:V和E集合,其中,V是顶点,E是边。因此,用一个一维数组存放图中所有顶点数据;用一个二维数组存放顶点间关系(边或弧)的数据,这个二维数组称为邻接矩阵。邻接矩阵又分为有向图邻接矩阵和无向图邻接矩阵

​ ————百度百科

定义

  1. 对于无向图,邻接矩阵是对称的,对角线为 0
  2. 无向图中,任一顶点 i 的度为第 i 列(或第 i 行)所有非零元素的个数,在有向图中顶点 i 的出度为第 i 行所有非零元素的个数,而入度为第 i 列所有非零元素的个数
  3. 存图空间为 \(n^2\) , 由于无向图对称且对称轴为 0,仅需 \(n(n-1)/2\)

特点

容易判断两个点是否相连,方便求度,但对于一个稀疏图,空间上会浪费很多,所以要注意数据范围

int n, m, o[zx][zx];
cin >> n >> m;
for(int i = 1; i <= m; i++){
    cin >> u >> v;
    o[u][v] = 1;
//  o[v][u] = 1; 无向图,也可以比较一下u v的大小只存一个三角形的图  
}

不知道为什么看到网上的大佬们写30多行的指针 就很迷,心慌慌

邻接表

直接举栗子 o( =∩ω∩= )

4 5 //4个点 5条边
1 4 9 //点 点 边权
4 3 8
1 2 5
2 4 6
1 3 7

img img

上面右图为链表表示的邻接表,是不是看到指针很激动, 下面介绍一下不用指针的邻接表

使用数组实现,每个点都存从这个点出发的所有边,,此时要给每条边编号,如下图

img 这里用三个数组记录(u,v,w)

再用一个数组first存每个顶点其中一条边的编号(为了方便枚举每个顶点所连的边),例如1 4 9,表示为first[1] = 1; 若一个点 i 出度为 0,则令first[i] = -1; 在读入前,先给first数组初始化为 1;

img img

1 4 9 是以1为起点扫到的第一条边,next数组赋值为 -1 , 4 3 8 同理

img img

现在读入1 2 5, 把 first[1] 更新为 3,让 next[3] 存原来 first[1] 的值,这样就能连起来了

img img

不难发现,遍历顶点1的所有边就跳来跳去就行了

建表

int n, m, u[zx], v[zx], w[zx], fisrt[zx], next[zx];
cin >> n >> m;
for(int i = 1; i <= n; i++) first[1] = -1;
for(int i = 1; i <= m; i++){
    cin >> u[i] >> v[i] >> w[i];
    next[i] = first[u[i]];
    first[u[i]] = i;
}

遍历其中一个点 i

int k = first[i];
while(k != -1){
    k = next[k];
    .....
}

遍历全部

for(int i = 1; i <= n; i++){
    int k = first[i];
    while(k != -1){
        k = next[k];
        .....
    }
}

啊,一个建图也没啥好讲的,**毕竟都是大佬 **

✿✿ヽ(°▽°)ノ❀

posted @ 2020-07-15 17:10  hulne  阅读(1014)  评论(4编辑  收藏  举报