最小生成树Prim算法的理解

本文详细介绍了Prim算法的基本原理及其用于构建最小生成树的过程。通过逐步添加顶点的方式,Prim算法能够有效地找出连接图中所有顶点的最短路径。文中还提供了具体的代码实现,帮助读者深入理解算法的工作机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    最小生成树算法中Prim是通用的一种算法。其大致的思想可以用通俗的语言去描述。首先看一段其他博客中的专业描述:

“设图G顶点集合为U,首先任意选择图G中的一点作为起始点a,将该点加入集合V,再从集合U-V中找到另一点b使得点b到V中任意一点的权值最小,此时将b点也加入集合V;以此类推,现在的集合V={a,b},再从集合U-V中找到另一点c使得点c到V中任意一点的权值最小,此时将c点加入集合V,直至所有顶点全部被加入V,此时就构建出了一颗MST。因为有N个顶点,所以该MST就有N-1条边,每一次向集合V中加入一个点,就意味着找到一条MST的边”。

    Prim算法的思想就是遍历所有最小权值的边,当然这种遍历是在依次添加顶点的基础上。通俗来讲,以下图为例,可以首先选择V1为为起点,然后遍历V = {v2,v3,v4,v5,v6}这其余的5个顶点;遍历完成后发现V3到V1的值最小,那么将V3加入到已经遍历的节点集合,暂时用W表示,则W={v1,v3},V1开始时默认起始点,已经加入;此时V = {v2,v4,v5,v6},然后遍历这几个顶点到W中顶点的权值哪个最小,然后选择哪个,下一个应该选择V6;依次类推,这就是Prim基本的算法思想,算法复杂度当然为n*n;

以下是《大话数据结构》中的代码实现,同时加了自己的一些理解注释

/*图的邻接矩阵定义*/
typedef char VertexType;
typedef int EdgeType;
#devine MAXVEX 100
#define INFINITY 65535
typedef struct
{
 VertexType vexs[MAXVEX];//顶点表
 EdgeType arc[MAXVEX][MAXVEX];//边表。可以表示权值的大小
 int numVertexes,numEdges;//边和顶点的最大个数
}MGraph;

void MiniSpanTree_Prim(MGraph G)
{
 int min,i,j,k;
 int adjvex[MAXVEX] ={0};//存放顶点的下标,可以看做一个存放已经被选中的顶点的集合
 int lowcost[MAXVEX] ={0};//存放边的权值
 
 /*先选择一个起始点,加入从0开始,我们的顶点采用自然数字0~MAXVEX*/
 adjvex[0] = 0;
 lowcost[0]=0;//初始化第一条边为0,代表节点0已经加入了adjvex的集合
 for(j=0;j<G.numVertexes;j++)
 {
  lowcost[j]=arc[0][j];//将与第一个节点边的权值存入到数组
  adjvex[j] = 0;//全都初始化为0的下标
 }
 /*开始遍历出去第一个节点的其他节点*/
 for(i=1;i<G.numVertexes;i++)
 {
  min = INFINITY;
  for(j=0;j<G.numVertexes;j++)
  {
   if(lowcost[j]!=0 && min>lowcost[j])
   {
    min = lowcost[j];
    k=j;//记录下当前这个点的下标
   }
   j++;
  }//循环退出时,便找到了离当前节点最近距离的点
     printf("(%d,%d)"adjvex[k],k);
  lowcost[k]=0;//代表第j个节点已经被遍历了。
  /*下边这个循环是来寻找新加入的节点与其他顶点的最小值,然后存入lowcost数组中,同时更新下标数组*/
  if(j=1;j>G.numVertexes;j++)
  {
   if(lowcost[j]!=0; && G.arc[k][j] < lowcost[j])
   {
       lowcost[j] = G.arc[k][j];//将较小值存入到lowcost中
    adjvex[j] = k;//将k的下边存入顶点数组
   }
   
  }
 }
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值