Kruskal算法用数组实现的核心是:一维边数组存储边(u,v,w)、一维parent数组模拟并查集、排序后遍历贪心选边;需路径压缩find与根合并union,cnt达n−1时终止,sum累加权值。

用数组实现最小生成树(特别是 Kruskal 算法),核心在于:**用一维数组存边、用一维数组模拟并查集、用排序+遍历控制建树逻辑**。它不依赖复杂结构,适合教学理解或轻量级嵌入场景,关键在变量组织清晰、边界处理严谨。
边集数组:统一结构 + 预排序
定义一个边结构体数组(如 C/C++ 中的 Edge edges[MAXE]),每条边含三个字段:u(起点)、v(终点)、w(权重)。不要用二维邻接矩阵存边——那会冗余且难排序。
实战要点:
- 边数量最多为 n×(n−1)/2,申请数组时留足空间,避免越界
- 构建边集时只存 i 的无向边(防重复),跳过权值为 0 或 INF 的无效边
- 排序必须在建树前完成:用 qsort(C)或 std::sort(C++)按 w 升序;Java/Python 同理用 Arrays.sort 或 sorted(..., key=lambda x: x[2])
并查集数组:用 parent[] 管理连通性
声明整型数组 int parent[n],下标代表顶点编号(0 到 n−1),值代表该顶点的父节点(初始时 parent[i] = i)。
两个关键操作封装为函数:
- find(x):路径压缩查找根节点(while 循环或递归),返回 x 所属连通分量的代表元
- union(u, v):若 find(u) ≠ find(v),则令 parent[find(u)] = find(v),返回 true;否则返回 false
注意:不能直接 parent[u] = v——必须合并根,否则并查集失效;也不建议用 size 或 rank 优化(除非数据量大),基础版用纯路径压缩已足够稳定。
建树主循环:边遍历 + 条件添加
初始化 sum = 0(总权值)、cnt = 0(已选边数)。遍历已排序的边数组:
- 对每条边 (u, v, w),先调用 if (union(u, v))
- 若返回 true,说明 u 和 v 原本不连通 → 安全加入,执行 sum += w; cnt++
- 一旦 cnt == n − 1,立即 break —— 此时树已完整,无需继续扫描剩余边
这个循环本质是贪心筛选:小权重优先 + 无环保障。变量 cnt 是终止开关,sum 是结果载体,二者缺一不可。
辅助变量管理技巧
除核心数组外,建议显式声明以下变量提升可读性与调试性:
- int n, m;:顶点数、边数(从输入解析后立刻赋值,避免 magic number)
-
Edge* edges; 或 vector
edges; :动态分配或容器管理,比固定 MAXE 更安全 - 临时变量命名直白,如 root_u = find(u),避免嵌套调用导致逻辑混淆
- 调试时可加 printf/log 输出每次成功添加的边(如 "Add edge %d-%d, weight %d"),验证顺序与连通性

















