树是一种特殊的图,与图的存储方式相同。
对于无向图中的边ab,存储两条有向边a->b, b->a。
因此我们可以只考虑有向图的存储:
-
邻接矩阵:g[a][b] 存储边 a -> b
-
邻接表
数组邻接表
存储
1 2 3 4 5 6 7 8 9 10 11
| int h[N], e[N], w[N], ne[N], idx;
idx = 0; memset(h, -1, sizeof h);
void addedge(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; }
|
遍历
时间复杂度 O(n + m),n 表示点数,m 表示边数
深度优先遍历
1 2 3 4 5 6 7 8
| int dfs(int u) { st[u] = true; for(int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; if(!st[j]) dfs(j); } }
|
广度优先遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| queue<int> q; st[1] = true; q.push(1);
while(q.size()) { int t = q.front(); q.pop(); for(int i = h[t]; i != -1; i = ne[i]) { int j = e[i]; if(!st[j]) { st[j] = true; q.push(j); } } }
|
vector 邻接表
存储
1 2 3 4 5 6 7 8 9 10 11 12 13
| struct Edge { int to, w; };
vector<Edge> e[N];
for(int i = 0; i < N; i++) e[i].clear();
void addedge(int a, int b, int w) { e[a].push_back({b, w}); }
|
遍历
1
| for(int i = 0; i < e[u].size(); i++)
|
链式前向星
存储
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| struct Edge { int to, w; int ne; }e[N]; int h[N], idx;
idx = 0; memset(h, -1, sizeof h);
void addedge(int a, int b, int w) { e[idx] = {b, w, h[a]}; h[a] = idx++; }
|
遍历
1
| for(int i = h[a]; i != -1; i = e[i].ne)
|