news 2026/5/12 0:10:13

Kruskal 最小生成树(MST)算法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kruskal 最小生成树(MST)算法

Kruskal 最小生成树(MST)算法

Prim算法是贪婪算法,类似于Kruskal算法。该算法始终从单个节点出发,经过多个相邻节点,以探索沿途所有连接的边。

该算法从一个空生成树开始。
其理念是维持两组顶点。第一组包含已包含在MST中的顶点,另一组包含尚未包含的顶点。
每一步,它都会考虑连接这两个集合的所有边,并从这些边中选择最小权重边。选定边后,将边的另一端点移动到包含MST的集合。

普里姆算法的工作原理
确定一个任意顶点作为MST的起始顶点。我们在上图中选择0。
按照步骤3到5,直到出现不包含在MST中的顶点(称为边缘顶点)。
找到连接任意树顶点与边缘顶点的边。
在这些边中找出最小值。
将选定的边添加到MST中。由于我们只考虑连接边缘顶点与其余边的边,因此从未得到一个环。
归还MST并离开
邻接矩阵表示的简单实现
按照上述步骤,利用上述Prim算法来求图的MST:

创建一个集合mstSet,跟踪MST中已包含的顶点。
为输入图中的所有顶点分配一个关键值。将所有键值初始化为无限。将第一个顶点的键值指定为0,这样它会被优先选中。
虽然mstSet不包含所有顶点
=> 选择一个mstSet 中不存在且有最小键值的顶点u。
=> 将u包含在mstSet中。
=> 更新 u 所有相邻顶点的键值。要更新键值,遍历所有相邻顶点。对于每个相邻顶点 v,如果边 u-v 的权重小于 v 的前一个键值,则将键值更新为 u-v 的权重。
使用关键值的目的是从切割中选择最小权重边。键值仅用于尚未包含在MST中的顶点,这些顶点的键值表示连接它们与MST中顶点集合的最小权重边。

import java.io.*; import java.lang.*; import java.util.*; class MST { // A utility function to find the vertex with minimum // key value, from the set of vertices not yet included // in MST int minKey(int key[], Boolean mstSet[]) { // Initialize min value int min = Integer.MAX_VALUE, min_index = -1; for (int v = 0; v < mstSet.length; v++) if (mstSet[v] == false && key[v] < min) { min = key[v]; min_index = v; } return min_index; } // A utility function to print the constructed MST // stored in parent[] void printMST(int parent[], int graph[][]) { System.out.println("Edge \tWeight"); for (int i = 1; i < graph.length; i++) System.out.println(parent[i] + " - " + i + "\t" + graph[parent[i]][i]); } // Function to construct and print MST for a graph // represented using adjacency matrix representation void primMST(int graph[][]) { int V = graph.length; // Array to store constructed MST int parent[] = new int[V]; // Key values used to pick minimum weight edge in // cut int key[] = new int[V]; // To represent set of vertices included in MST Boolean mstSet[] = new Boolean[V]; // Initialize all keys as INFINITE for (int i = 0; i < V; i++) { key[i] = Integer.MAX_VALUE; mstSet[i] = false; } // Always include first 1st vertex in MST. // Make key 0 so that this vertex is // picked as first vertex key[0] = 0; // First node is always root of MST parent[0] = -1; // The MST will have V vertices for (int count = 0; count < V - 1; count++) { // Pick the minimum key vertex from the set of // vertices not yet included in MST int u = minKey(key, mstSet); // Add the picked vertex to the MST Set mstSet[u] = true; // Update key value and parent index of the // adjacent vertices of the picked vertex. // Consider only those vertices which are not // yet included in MST for (int v = 0; v < V; v++) // graph[u][v] is non zero only for adjacent // vertices of m mstSet[v] is false for // vertices not yet included in MST Update // the key only if graph[u][v] is smaller // than key[v] if (graph[u][v] != 0 && mstSet[v] == false && graph[u][v] < key[v]) { parent[v] = u; key[v] = graph[u][v]; } } // Print the constructed MST printMST(parent, graph); } public static void main(String[] args) { MST t = new MST(); int graph[][] = new int[][] { { 0, 2, 0, 6, 0 }, { 2, 0, 3, 8, 5 }, { 0, 3, 0, 0, 7 }, { 6, 8, 0, 0, 9 }, { 0, 5, 7, 9, 0 } }; // Print the solution t.primMST(graph); } }

输出
Edge Weight
0 - 1 2
1 - 2 3
0 - 3 6
1 - 4 5
时间复杂度:O(V2由于我们使用邻接矩阵,如果输入图用邻接列表表示,那么借助二元堆,Prim算法的时间复杂度可以简化为O((E+V) * logV)。辅助空间:O(V)

使用优先队列和邻接列表的高效实现
对于邻接列表表示,我们可以实现 O(((E+V)*log(V)),因为我们可以在 O(V + E) 时间内找到每个顶点的所有相邻,并且在 O(Log V) 时间内通过优先队列获得最小值。

我们使用优先队列(最小堆)来始终选择权重最小的边。
将第一个顶点及其权重推入队列。
当队列不空时,提取最小权重边。
如果顶点未被访问,将其权重加到变量(res)上,并标记为已访问。
将该顶点所有未访问的相邻顶点推入队列。
处理完所有顶点后,返回以 res(分辨率)存储的总权重。

import java.util.PriorityQueue; import java.util.ArrayList; class GFG { // Returns total weight of the Minimum Spanning Tree static int spanningTree(int V, ArrayList<ArrayList<int[]>> adj) { // Min-heap storing {weight, vertex} PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[0] - b[0]); boolean[] visited = new boolean[V]; int res = 0; // Start from node 0 pq.add(new int[]{0, 0}); while(!pq.isEmpty()) { int[] p = pq.poll(); int wt = p[0]; int u = p[1]; if(visited[u]) continue; res += wt; visited[u] = true; // Push adjacent edges for(int[] v : adj.get(u)) { if(!visited[v[0]]) { pq.add(new int[]{v[1], v[0]}); } } } return res; } public static void main(String[] args) { int V = 3; ArrayList<ArrayList<int[]>> adj = new ArrayList<>(); for(int i = 0; i < V; i++) adj.add(new ArrayList<>()); adj.get(0).add(new int[]{1, 5}); adj.get(1).add(new int[]{0, 5}); adj.get(1).add(new int[]{2, 3}); adj.get(2).add(new int[]{1, 3}); adj.get(0).add(new int[]{2, 1}); adj.get(2).add(new int[]{0, 1}); System.out.println(spanningTree(V, adj)); } }

输出
4
时间复杂度:O(((E+V)*log(V)),其中V是顶点数,E是边数。
辅助空间:O(E+V),其中V是顶点数,E是边数

它是如何运作的?
核心基于MST的一个基本性质,称为割性质(如果我们将顶点划分为两组(即割),那么穿越该割的最轻边必须是图中某个MST的一部分。由于我们总是考虑割顶点,因此从不形成循环。

Prim算法的优缺点
优势:

Prim算法保证能在连通加权图中找到MST。
使用二元堆或斐波那契堆时,其时间复杂度为 O((E+V)×log(V)),其中 E 是边数,V 是顶点数。
与其他一些MST算法相比,它是一个相对简单易懂和实现的算法。
缺点:

与Kruskal算法类似,Prim算法在多边密集图上可能较慢,因为它需要至少遍历所有边一次。
Prim算法依赖优先级队列,这会占用额外内存,并在非常大的图中使算法变慢。
起始节点的选择会影响MST输出,这在某些应用中可能并不理想。

编程资源 https://pan.quark.cn/s/7f7c83756948 更多资源 https://pan.quark.cn/s/bda57957c548
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/6 1:22:19

语音分离技术终极指南:从基础概念到高效实战方案

语音分离技术终极指南&#xff1a;从基础概念到高效实战方案 【免费下载链接】FunASR A Fundamental End-to-End Speech Recognition Toolkit and Open Source SOTA Pretrained Models, Supporting Speech Recognition, Voice Activity Detection, Text Post-processing etc. …

作者头像 李华
网站建设 2026/5/3 19:17:03

LLM成本优化终极指南:从账单恐慌到精准控制

LLM成本优化终极指南&#xff1a;从账单恐慌到精准控制 【免费下载链接】langfuse Open source observability and analytics for LLM applications 项目地址: https://gitcode.com/GitHub_Trending/la/langfuse 面对每月飙升的LLM调用费用&#xff0c;你是否感到束手无…

作者头像 李华
网站建设 2026/4/30 4:43:04

Qwen-Image-2512-ComfyUI实战案例:电商海报生成系统3天上线部署

Qwen-Image-2512-ComfyUI实战案例&#xff1a;电商海报生成系统3天上线部署 1. 从零到上线&#xff1a;三天搭建电商海报自动化系统 你有没有遇到过这样的场景&#xff1f;运营团队每天要出十几张商品海报&#xff0c;设计师加班加点还是赶不上节奏&#xff0c;文案改了又改&…

作者头像 李华
网站建设 2026/5/11 10:18:49

Qwen3-0.6B部署难题破解:API Key为空的正确处理方式

Qwen3-0.6B部署难题破解&#xff1a;API Key为空的正确处理方式 1. 认识Qwen3-0.6B&#xff1a;轻量级大模型的新选择 你可能已经听说过通义千问系列&#xff0c;但这次的 Qwen3-0.6B 真的有点不一样。它不是那种动辄上百亿参数、需要堆叠多张A100才能跑起来的“巨无霸”&…

作者头像 李华
网站建设 2026/5/5 2:24:26

Qwen3-0.6B电商推荐系统:轻量模型落地完整流程

Qwen3-0.6B电商推荐系统&#xff1a;轻量模型落地完整流程 1. 轻量级大模型为何适合电商推荐场景 在当前AI应用快速落地的背景下&#xff0c;越来越多企业开始关注如何将大语言模型&#xff08;LLM&#xff09;真正用起来。尤其是电商行业&#xff0c;每天面临海量用户行为数…

作者头像 李华
网站建设 2026/5/9 10:15:40

Open-AutoGLM避坑指南:常见问题全解析

Open-AutoGLM避坑指南&#xff1a;常见问题全解析 1. 项目介绍与核心价值 1.1 Open-AutoGLM 是什么&#xff1f;它能做什么&#xff1f; Open-AutoGLM 是由智谱AI推出的开源手机端AI智能体框架&#xff0c;基于其自研的 AutoGLM 多模态大模型构建。简单来说&#xff0c;它是…

作者头像 李华