【大话数据结构C语言】45 最小生成树(普里姆算法)

举报
CodeAllen 发表于 2021/10/29 23:56:52 2021/10/29
【摘要】 欢迎关注我的公众号是【CodeAllen】,关注回复【1024】获取资源 程序员技术交流①群:736386324 ,程序员技术交流②群:371394777     首先明确下概念,我们把构造连通网的最小代价生成树叫做最小生成树(Minimum Cost Spanning Tree) 给定一个连...

欢迎关注我的公众号是【CodeAllen】,关注回复【1024】获取资源
程序员技术交流①群:736386324 ,程序员技术交流②群:371394777    

首先明确下概念,我们把构造连通网的最小代价生成树叫做最小生成树(Minimum Cost Spanning Tree)

给定一个连通网,求最小生成树的方法有:普里姆(Prim)算法 & 克鲁斯卡尔(Kruskal)算法

 

 

普里姆算法(Prim)

构建一个邻接矩阵

 

 

普里姆算法在找最小生成树时,将顶点分为两类,一类是在查找的过程中已经包含在树中的(假设为 A 类),剩下的是另一类(假设为 B 类)。

 

对于给定的连通网,起始状态全部顶点都归为 B 类。在找最小生成树时,选定任意一个顶点作为起始点,并将之从 B 类移至 A 类;然后找出 B 类中到 A 类中的顶点之间权值最小的顶点,将之从 B 类移至 A 类,如此重复,直到 B 类中没有顶点为止。所走过的顶点和边就是该连通图的最小生成树。

 

例如,通过普里姆算法查找图 2(a)的最小生成树的步骤为:

 

假如从顶点A出发,顶点 B、C、D 到顶点 A 的权值分别为 2、4、2,所以,对于顶点 A 来说,顶点 B 和顶点 D 到 A 的权值最小,假设先找到的顶点 B:

继续分析顶点 C 和 D,顶点 C 到 B 的权值为 3,到 A 的权值为 4;顶点 D 到 A 的权值为 2,到 B 的权值为无穷大(如果之间没有直接通路,设定权值为无穷大)。所以顶点 D 到 A 的权值最小:

最后,只剩下顶点 C,到 A 的权值为 4,到 B 的权值和到 D 的权值一样大,为 3。所以该连通图有两个最小生成树:

 

 

prim.c


  
  1. // Prim算法生成最小生成树
  2. void MiniSpanTree_Prim(MGraph G)
  3. {
  4.     int min, i, j, k;
  5.     int adjvex[MAXVEX];     // 保存相关顶点下标
  6.     int lowcost[MAXVEX];    // 保存相关顶点间边的权值
  7.     
  8.     lowcost[0] = 0;         // V0作为最小生成树的根开始遍历,权值为0
  9.     adjvex[0] = 0;          // V0第一个加入
  10.     
  11.     // 初始化操作
  12.     for( i=1; i < G.numVertexes; i++ )
  13.     {
  14.         lowcost[i] = G.arc[0][i];   // 将邻接矩阵第0行所有权值先加入数组
  15.         adjvex[i] = 0;              // 初始化全部先为V0的下标
  16.     }
  17.     
  18.     // 真正构造最小生成树的过程
  19.     for( i=1; i < G.numVertexes; i++ )
  20.     {
  21.         min = INFINITY;     // 初始化最小权值为65535等不可能数值
  22.         j = 1;
  23.         k = 0;
  24.         
  25.         // 遍历全部顶点
  26.         while( j < G.numVertexes )
  27.         {
  28.             // 找出lowcost数组已存储的最小权值
  29.             if( lowcost[j]!=0 && lowcost[j] < min )
  30.             {
  31.                 min = lowcost[j];
  32.                 k = j;      // 将发现的最小权值的下标存入k,以待使用。
  33.             }
  34.             j++;
  35.         }
  36.         
  37.         // 打印当前顶点边中权值最小的边
  38.         printf("(%d,%d)", adjvex[k], k);
  39.         lowcost[k] = 0;     // 将当前顶点的权值设置为0,表示此顶点已经完成任务,进行下一个顶点的遍历
  40.         
  41.         // 邻接矩阵k行逐个遍历全部顶点
  42.         for( j=1; j < G.numVertexes; j++ )
  43.         {
  44.             if( lowcost[j]!=0 && G.arc[k][j] < lowcost[j] )
  45.             {
  46.                 lowcost[j] = G.arc[k][j];
  47.                 adjvex[j] = k;  
  48.             }
  49.         }
  50.     }
  51. }

 

文章来源: allen5g.blog.csdn.net,作者:CodeAllen的博客,版权归原作者所有,如需转载,请联系作者。

原文链接:allen5g.blog.csdn.net/article/details/116618047

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。