邻接表(Adjacency List)
简介(Introduction)
邻接表是图的一种最主要存储结构,用来描述图上的每一个点。对于图的每个顶点建立一个容器( \(n\) 个顶点建立 \(n\) 个容器),第 \(i\) 个容器中的结点包含顶点 \(v_i\) 的所有邻接顶点。
描述(Description)
- 通过 \(head\) 可以定位到每一类所构成的链表
- 当需要插入新的节点时,可以通过 \(head\) 定位到新的数据节点所属类别的表头,然后进行 头插
示例(Example)
-
邻接表存储有向图:
-
邻接表存储无向图:
-
例如:插入 \((1, 2), (2, 3),(2, 5),(3,6),(5,4),(5,1)\) 六条边后,邻接表的信息如下:
代码(Code)
- 写法一:
const int N = 边数; int ve[N], we[N], ne[N], head[N], tot; // 加入有向边 x -> y ,权值为 z void add(int x, int y, int z) { ve[++ tot] = y, we[tot] = z; // 真实数据 ne[tot] = head[x], head[x] = tot; // 在表头 x 处插入 } // 遍历 void print(int x) { for (int i = head[x]; i; i = ne[i]) { int j = ver[i], w = edge[i]; // 找到一条有向边(x, j), 权值为 w // 具体逻辑 // printf("%d ", j); } }
- 写法二:
const int N = 边数; int e[N], w[N], ne[N], h[N], idx; void add(int a, int b, int c) { // 加边 e[idx] = b, w[idx] = c; ne[idx] = h[a], h[a] = idx ++ ; } void print(int a) { // 遍历 for (int i = h[a]; ~i; i = ne[i]) { int j = e[i], w = w[i]; // 找到一条有向边(a, j), 权值为 w // 具体逻辑 // printf("%d ", j); } }
注:需要先
memset(h, -1, sizeof h);
- \(vector\) 存储:
const int N = 点数; struct Edge { int to; // 终点 int w; // 边的权值 }; vector<edge>g[N]; // g[i] 中 i 表示起始位置 void add(int from, int to, int c) { Edge e = {to, c}; g[from].push_back(e); // 向 vector 的最后添加一条边 } // 遍历 void print(int a) { for (int i = 0; i < g[a].size(); i ++ ) // 具体逻辑 // printf("%d ", g[a][i].to); }