【总结】图的储存于遍历

图的基本概念

  • 定义
    图 (Graph) 是由若干给定的 顶点(vertex) 及连接两顶点的 边(edge) 所构成的图形。

  • 功能
    用来描述某些事物之间的某种特定关系
    例如:顶点用于代表事物,而边用于表示两个事物间所具有某种关系。

  • 组成
    二元组:G=(V(G),E(G))

    • V(G):点集,对于集合 V 中的每个元素,我们称其为 顶点节点,简称
    • E(G):为 V(G) 中各结点之间边的集合,称为 边集
  • 种类

    • 无向图
      边没有指定的方向。
    • 有向图:
      边有指定的方向。
    • 带权图
      边上带有权值的图:
    • 正权图
      边权没有负数的图
    • 负权图
      边权有负数的图
  • 其它术语

    • 连通图 (connected graph) : 任意两点之间都有路径连接的图。

    • 自环 (loop): 对 E 中的边 e=(u,v),若 u=v,则 e 被称作一个自环。

    • 度 (degree) : 与一个顶点 v 关联的边的条数,记作。
      特别的,在有向图中有出度和入度。

      • 入度 (in-degree): 以点 v弧头 的边的数目称为该顶点的入度 。

      • 出度 (out-degre): 以点 v弧尾 的边的数目称为该顶点的出度。

    • 有向无环图 (DAG): 没有环的有向图。

图的存储及遍历

邻接矩阵

这是最简单的存储方式,我们定义一个二位 bool 数组 G, 若 Gi,j1,表示有边,否则无边。如果是无向图,则要双向存边。

const int MAXN = 1005;
bool G[MAXN][MAXN];
void dfs(int k) {
	printf("%d ", k);
	vis[k] = 1;
	for (int i = 1; i <= n; i++)
		if (G[k][i] && !vis[i])
			dfs(i);
}
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
	int x, y;
	scanf("%d %d", &x, &y);
	G[x][y] = 1;
}
dfs(1);

对于带权图我们就会换成 int 类型,Gi,j 的值,就是 ij 的边权。

const int MAXN = 1005;
int G[MAXN][MAXN];
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
	int x, y, w;
	scanf("%d %d %d", &x, &y, &w);
	G[x][y] = w;
}

邻接表

我们一边使用 vector 实现。

用来记录与每个点相邻的点。

const int MAXN = 1e4 + 5;
vector<int> G[MAXN];
for (int i = 1, u, v; i <= m; i++) {
    scanf("%d %d", &u, &v);
    G[u].push_back(v);
    G[v].push_back(u);
}
for (int i = 1; i <= n; i++) {
	sort(v[i].begin(), v[i].end(), cmp);
	for (int j = 0; j < v[i].size(); j++)
		printf("%d ", v[i][j]);
	printf("\n");
}

链式前向星

链式前向星就是数组实现的邻接表。

我个人还是喜欢用链式前向星。

const int MAXN = 2005, MAXM = 20005;
int n, m;
int head[MAXN], next[MAXM], ver[MAXM], edge[MAXM], tot;
void add(int x, int y, int z) {
	next[++tot] = head[x], head[x] = tot, ver[tot] = y, edge[tot] = z;
}
void dfs(int k) {
	vis[k] = 1;
	printf("%d ", k);
	for (int i = head[k]; i; i = next[i]) {
		int v = ver[i];
		if (!vis[v])
			dfs(v);
	}
}
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; i++) {
	int x, y, z;
	scanf("%d %d %d", &x, &y, &z);
	add(x, y, z), add(y, x, z);
}
dfs(1);
posted @   zhou_ziyi  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示