主要内容 #
- 邻接矩阵存储方式简介
- 邻接表存储方式简介
1. 邻接矩阵存储方式简介 #
使用数组存储图时,需要使用两个数组,一个数组存放图中顶点本身的数据(一维数组),另外一个数组用于存储各顶点之间的关系(二维数组)即邻接矩阵。
存储图中各顶点本身数据,使用一维数组就足够了;存储顶点之间的关系时,要记录每个顶点和其它所有顶点之间的关系,所以需要使用二维数组。
邻接矩阵的英文名是 adjacency matrix。它的形式是 bool adj[n][n] , 这里需要存 n 个节点,adj[x][y] 表示节点x与节点y 之间是否有边,如果边有权值的话 , 用 int adj[n][n] 直接把边权存进去。
有向图需要 x 与 y 有边则需要存 adj[x][y] 与 adj[y][x] 表示有双向导通 , 无向图则 x -> y 则存 adj[x][y] 就行了 。
include<stdio.h> int adj[MAXN][MAXN],n,m; // n 为节点数 , m 为边数 int main() { scanf("%d %d",&n,&m); for(int i=1;i<=m;i++) { int x,y,v; scanf("%d %d %d",&x,&y,&v); adj[x][y]=adj[y][x]=v;//向x,y间添加一个权值为v的边(无向) //有向图为adj[x][y]=v; } return 0; }
它的优点是 , 在查询两点间是否有边时 , 时间复杂度为 O(1) , 但是缺点是它存边却是极占内存,它的空间(内存)复杂度是 O(n^2) . 对于一个稀疏的图(边相对于点数的平方比较少)来说,用邻接矩阵来存的话,成本偏高。
如果n*m超过3×1e7,内存就超过128MB了,所以当看到类似的 n,m=<1e4时就不要用邻接矩阵 , 需要考虑其他的存储方式。
2. 邻接表存储方式简介 #
邻接表(Adjacency List)是图的一种链式存储结构,既可以存储无向图(网),也可以存储有向图(网)。
邻接表存储图的核心思想是:将图中的所有顶点存储到顺序表中(也可以是链表),同时为各个顶点配备一个单链表,用来存储和当前顶点有直接关联的边或者弧(边的一端是该顶点或者弧的弧尾是该顶点)。
举个简单的例子,下图是一张有向图和它对应的邻接表:
#include<stdio.h> struct node { int to[1010]; //存储与当前节点相接的节点 int v[1010]; //两节点间的边的权值 int olen; //出度 //int ilen; //入度 }edge[1010]; int n,m; int main() { scanf("%d %d",&n,&m); for(int i=1;i<=m;i++) { int x,y,v1; scanf("%d %d %d",&x,&y,&v1); edge[x].len++;edge[y].len++; edge[x].to[edge[x].len]=y;edge[y].to[edge[x].len]=x; edge[x].v[edge[x].len]=edge[y].to[edge[x].len]=v1;//向x,y间添加一个权值为v的边(无向) /*有向图为 edge[x].len++; edge[x].to[edge[x].len]=y; edge[x].v[edge[x].len]=v1; */ } return 0; }