news 2026/9/12 19:02:45

15-最小生成树:Prim与Kruskal

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
15-最小生成树:Prim与Kruskal

C语言数据结构系列:最小生成树篇

  • C语言数据结构系列(十五):最小生成树——Prim与Kruskal
    • 一、前言
    • 二、基本概念
      • 2.1 什么是生成树?
      • 2.2 什么是最小生成树?
    • 三、Prim算法
      • 3.1 思想
      • 3.2 步骤
      • 3.3 代码实现
    • 四、Kruskal算法
      • 4.1 思想
      • 4.2 步骤
      • 4.3 代码实现
    • 五、Prim vs Kruskal
    • 六、应用
    • 七、下篇预告

C语言数据结构系列(十五):最小生成树——Prim与Kruskal

🎯本篇目标:理解最小生成树概念,掌握Prim和Kruskal算法!
📝摘要:本文讲解最小生成树(MST)的核心概念,并深入对比两种经典算法——Prim 与 Kruskal。Prim 从点出发,适合稠密图;Kruskal 从边出发,借助并查集检测环,适合稀疏图。文中配有图解、步骤流程与完整 C 语言代码实现,帮助读者快速掌握两种算法的思想、步骤与适用场景。


一、前言

哈喽小伙伴们!👋

今天我们来学习最小生成树(MST)——用最少的边连接所有顶点!

应用场景:

  • 🔌 电网设计
  • 🛣️ 公路规划
  • 🌐 网络布线

二、基本概念

2.1 什么是生成树?

生成树:包含图中所有顶点的无环连通子图

2.2 什么是最小生成树?

最小生成树:边权值之和最小的生成树

4

2

3

5

1

A

B

C

D

MST:A-C(2), C-D(1), B-C(3) = 总权值6


三、Prim算法

3.1 思想

💡从点出发:从一个顶点开始,每次加入权值最小的边

3.2 步骤

1. 从A开始

2. 加入最小边A-C

3. 加入最小边C-D

4. 加入最小边B-C

3.3 代码实现

#defineINF99999voidprim(intgraph[][MAX],intn){intkey[MAX];// 到生成树的最小距离bool inMST[MAX];// 是否在MST中intparent[MAX];// 父节点for(inti=0;i<n;i++){key[i]=INF;inMST[i]=false;parent[i]=-1;}key[0]=0;// 从顶点0开始for(intcount=0;count<n-1;count++){// 找key最小且不在MST中的顶点intu=-1;for(intv=0;v<n;v++){if(!inMST[v]&&(u==-1||key[v]<key[u])){u=v;}}inMST[u]=true;// 更新邻接顶点的keyfor(intv=0;v<n;v++){if(graph[u][v]&&!inMST[v]&&graph[u][v]<key[v]){key[v]=graph[u][v];parent[v]=u;}}}printf("Prim MST:\n");for(inti=1;i<n;i++){printf("%c - %c : %d\n",parent[i]+'A',i+'A',key[i]);}}

四、Kruskal算法

4.1 思想

💡从边出发:按权值排序,依次加入不形成环的边

使用并查集检测环

4.2 步骤

1. 所有边排序

2. 选最小边C-D

3. 选次小边A-C

4. 选B-C,形成环则跳过

4.3 代码实现

typedefstruct{intu,v,weight;}Edge;intparent[MAX];intrank[MAX];voidinitUnionFind(intn){for(inti=0;i<n;i++){parent[i]=i;rank[i]=0;}}intfind(intx){if(parent[x]!=x){parent[x]=find(parent[x]);}returnparent[x];}boolunion(intx,inty){intpx=find(x),py=find(y);if(px==py)returnfalse;if(rank[px]<rank[py])parent[px]=py;elseif(rank[px]>rank[py])parent[py]=px;else{parent[py]=px;rank[px]++;}returntrue;}intcmp(constvoid*a,constvoid*b){return((Edge*)a)->weight-((Edge*)b)->weight;}voidkruskal(Edge edges[],intedgeNum,intn){qsort(edges,edgeNum,sizeof(Edge),cmp);initUnionFind(n);printf("Kruskal MST:\n");intcount=0;for(inti=0;i<edgeNum&&count<n-1;i++){if(union(edges[i].u,edges[i].v)){printf("%c - %c : %d\n",edges[i].u+'A',edges[i].v+'A',edges[i].weight);count++;}}}

五、Prim vs Kruskal

特性PrimKruskal
思想从点出发从边出发
时间O(V²)O(ElogE)
适用稠密图稀疏图
数据结构数组并查集

六、应用

  1. 电网设计

    • 最低成本连接所有城市
  2. 网络布线🌐

    • 最少网线连接所有电脑
  3. 聚类分析📊

    • 去掉最大边实现K类聚类

七、下篇预告

下一篇我们将学习最短路径:Dijkstra与Floyd


💡 Prim适合稠密图,Kruskal适合稀疏图!👍

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

POD-DMD加速CFD后处理:从模态提取到流场重构实战

简介&#xff1a;围绕POD与DMD的CFD后处理资源&#xff0c;面向流体力学研究者与CFD工程师&#xff0c;解决高维流场数据降维与动态演化特征提取难题。该方案将主成分分析与动态模式分解相结合&#xff0c;既提供POD低阶模态识别流场主结构&#xff0c;又利用DMD刻画时间频谱与…

作者头像 李华
网站建设 2026/9/12 19:00:32

Rubix 基础层:从云端到战车,同一套底座怎么跑

聊 Palantir 的架构&#xff0c;前面几篇我们把 Foundry、Ontology、AIP 都过了一遍。这些东西看起来各自独立&#xff0c;但有个问题我一直没正面回答&#xff1a;它们到底跑在哪&#xff1f; 一个客户在 AWS 上跑着 Foundry&#xff0c;另一头部队的单兵终端里跑着 AIP&#…

作者头像 李华
网站建设 2026/9/12 19:00:18

车载音频PAL架构与ResourceManager资源调度解析

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

作者头像 李华
网站建设 2026/9/12 18:58:30

Java数据库与数据存储:Redis

1. 引言 在当今互联网高并发场景下&#xff0c;数据库的性能瓶颈往往成为系统扩展的最大障碍。Redis 作为一款高性能的内存数据库&#xff0c;凭借其丰富的数据结构、极快的读写速度和灵活的持久化机制&#xff0c;已经成为 Java 后端开发中不可或缺的组件。 本文将系统性地介绍…

作者头像 李华
网站建设 2026/9/12 18:58:23

网络摄像机首次播放音视频延时出图像踩坑记录

ZLMediaKit / RTSP / H.264 播放音视频踩坑记录 - SDP、SPS、PPS 完整详解适用场景&#xff1a;RTSP 信令交互、addStreamProxy 拉流、WebRTC、H264 裸流、花屏、首帧黑屏、无法解码&#xff0c;绝大多数问题根源就是 SDP / SPS/PPS。1、SDP 是什么 SDP&#xff1a;Session Des…

作者头像 李华