图论最小生成树(MST):Kruskal 算法与 Prim 算法的贪心本质与工程选型
图论最小生成树MSTKruskal 算法与 Prim 算法的贪心本质与工程选型在图论算法与网络拓扑规划中“最小生成树Minimum Spanning TreeMST”是解决在保证图内所有顶点完全连通的前提下使得所选边的权重之和达到最小的经典问题。典型工业应用包括分布式集群机房之间的低成本光纤布线拓扑设计微服务跨机房网络广播树构建电路芯片布线与图像分割聚类。解决 MST 最著名的两大贪心算法分别是Kruskal 算法克鲁斯卡尔算法与Prim 算法普里姆算法。虽然两者都基于贪心选择性质Greedy-Choice Property与割边定理Cut Property但一个立足于“按边的权重全局排序”另一个立足于“从顶点的局部生长”。今天我们系统拆解这两种算法的数学本质、代码模板与工程选型权衡。割性质Cut Property最小生成树贪心正确性的终极数学基石在证明 MST 贪心算法的正确性时割性质是最核心的定理对于图 $G (V, E)$ 的任意一个割 $(S, V \setminus S)$横跨这个割的所有边中权重最小的那条轻量边Light Edge必然属于图的某棵最小生成树Kruskal 与 Prim 正是从不同角度不断寻找并加入这样的轻量边。graph TD subgraph Kruskal 算法: 边的全局贪心视角 A1[将全图所有边按权重从小到大严格排序] -- B1[依次遍历每条边 (u, v)] B1 -- C1{通过并查集检查 u 和 v 是否已连通?} C1 --|未连通| D1[将边加入生成树, 并查集 union(u, v), 计数器 count] C1 --|已连通| E1[丢弃该边 (防成环)] D1 -- F1{已选够 V-1 条边?} end subgraph Prim 算法: 顶点的局部生长视角 A2[选定任意起点加入已访问集合 S] -- B2[将与集合 S 相邻的所有割边放入最小堆] B2 -- C2[弹出当前最短的割边 (u, v)] C2 -- D2{顶点 v 是否已在集合 S 中?} D2 --|否| E2[将 v 纳入集合 S, 累加边权, 将 v 的新邻边推入堆] D2 --|是| C2 end一、Kruskal 算法边贪心 并查集稀疏图的绝对首选Kruskal 算法的逻辑极其清晰纯粹将图中的所有边按照权重 $w$ 从小到大排序初始时所有顶点自成独立的集合从小到大遍历排序后的边列表使用并查集Union-Find检查当前边的两个端点 $u$ 和 $v$ 是否属于同一个集合若不属于同一个集合union(u, v) true说明加入该边绝对不会成环将该边纳入最小生成树并累加权重若已在同一集合说明加入该边会构成冗余环路直接丢弃当成功选入了 $V - 1$ 条边时最小生成树构建完毕工业级 Java 代码实现LeetCode 1584 连接所有点的最小费用import java.util.*; public class KruskalMstSolution { // 边结构体 static class Edge implements ComparableEdge { int u, v, weight; public Edge(int u, int v, int weight) { this.u u; this.v v; this.weight weight; } Override public int compareTo(Edge o) { return Integer.compare(this.weight, o.weight); } } public int minCostConnectPoints(int[][] points) { int n points.length; ListEdge edges new ArrayList(); // 1. 构造所有点对之间的边 (曼哈顿距离) for (int i 0; i n; i) { for (int j i 1; j n; j) { int dist Math.abs(points[i][0] - points[j][0]) Math.abs(points[i][1] - points[j][1]); edges.add(new Edge(i, j, dist)); } } // 2. 将所有边按权重从小到大排序: O(E log E) Collections.sort(edges); // 3. 并查集贪心合并 UnionFind uf new UnionFind(n); int totalWeight 0; int edgeCount 0; for (Edge edge : edges) { if (uf.union(edge.u, edge.v)) { totalWeight edge.weight; edgeCount; if (edgeCount n - 1) { break; // 已经选满 n - 1 条边提前结束 } } } return edgeCount n - 1 ? totalWeight : -1; } }二、Prim 算法点生长 优先队列稠密图与矩阵图的利器与 Kruskal 面向边不同Prim 算法从某一个起始顶点出发像滚雪球一样不断向外“生长”维护一个集合 $S$初始时将顶点 0 放入 $S$维护一个最小堆PriorityQueue存储所有从集合 $S$ 伸向集合外部 $V \setminus S$ 的割边每次从堆中取出权重最小的边 $(u, v)$若顶点 $v$ 已经在集合 $S$ 中说明是内部边直接跳过否则将 $v$ 纳入集合 $S$累加边权并将顶点 $v$ 引出的所有连接到外部的新边全部推入堆中重复直到所有 $N$ 个顶点全部被纳入集合 $S$。public int minCostConnectPointsPrim(int[][] points) { int n points.length; boolean[] visited new boolean[n]; // 优先队列存 int[]{targetNode, weight} PriorityQueueint[] pq new PriorityQueue(Comparator.comparingInt(a - a[1])); pq.offer(new int[]{0, 0}); int totalWeight 0; int visitedCount 0; while (!pq.isEmpty() visitedCount n) { int[] curr pq.poll(); int u curr[0]; int w curr[1]; if (visited[u]) continue; // 已在集合中跳过 visited[u] true; totalWeight w; visitedCount; // 将与 u 相邻的未访问节点加入优先队列 for (int v 0; v n; v) { if (!visited[v]) { int dist Math.abs(points[u][0] - points[v][0]) Math.abs(points[u][1] - points[v][1]); pq.offer(new int[]{v, dist}); } } } return visitedCount n ? totalWeight : -1; }两大算法的复杂度与工程选型决策矩阵评估维度Kruskal 算法Prim 算法堆优化Prim 算法邻接矩阵朴素版算法操作主体边Edges顶点与割边Vertices Cut Edges顶点Vertices辅助数据结构边数组排序 并查集优先队列Min-Heap visited数组一维数组minDist[]时间复杂度$O(E \log E)$$O(E \log V)$$O(V^2)$空间复杂度$O(E)$$O(V E)$$O(V)$最佳适用场景稀疏图Sparse Graph$E \ll V^2$中等稠密图完全图 / 超稠密图Dense Graph$E \approx V^2$总结在实际工程开发与算法面试中如果图是以**边列表Edge List**形式给出或者图比较稀疏如交通公路网、网络拓扑Kruskal 算法配合并查集不仅代码极其好写运行速度也极具优势如果图是完全图如 LeetCode 1584 任意两点均有边连通使用朴素版 $O(V^2)$ 的 Prim 算法甚至比堆优化版更快免去了昂贵的堆操作与边对象创建。深刻理解割性质与数据结构选型最小生成树的各类变种题便能迎刃而解。

相关新闻

2026企业AI办公工具选型指南:从需求匹配到落地评估

2026企业AI办公工具选型指南:从需求匹配到落地评估

企业引入AI办公工具时,很多管理者容易陷入单一维度评估的误区。不少团队选型时,直接对比产品功能清单,或是以品牌知名度作为决策依据,还有部分团队只关注订阅成本,忽略工具与自身业务流程的适配程度。这类评估方式往往…

2026/10/24 19:52:04 阅读更多 →
分布式事务 Seata TCC 模式实战:Try-Confirm-Cancel 接口设计与空回滚/防悬挂治理

分布式事务 Seata TCC 模式实战:Try-Confirm-Cancel 接口设计与空回滚/防悬挂治理

分布式事务 Seata TCC 模式实战:Try-Confirm-Cancel 接口设计与空回滚/防悬挂治理在前面我们深入剖析了 Seata 的 AT 模式(依赖关系型数据库本地事务与 Undolog 自动补偿)。然而,在很多高并发、高性能、或者跨异构系统&#xff08…

2026/10/23 16:23:08 阅读更多 →
MFC与网页交互:CDHtmlDialog双向通信与PostMessage机制

MFC与网页交互:CDHtmlDialog双向通信与PostMessage机制

简介:压缩包内提供了一份MFC与网页交互示例工程,演示了在MFC窗口程序内嵌浏览器控件,通过ActiveX/COM桥接完成JavaScript与C函数互调、事件监听和数据交换,并兼顾了跨域安全和权限控制。压缩包共24个文件,以9个h头文件…

2026/10/25 8:12:36 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/25 11:19:54 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/25 22:36:10 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/26 4:52:12 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/25 10:02:42 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/26 5:00:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/26 3:16:46 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 10:02:43 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 13:21:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →