数据结构图论之普里姆算法

算法思想:可取图中任意一个顶点V作为生成树的根,之后若要往生成树上添加顶点W,则在顶点V和W之间必定存在一条边。并且该边的权值在所有连通顶点V和W之间的边中取值最小。

一般情况下,假设n个顶点分成两个集合:U(包含已落在生成树上的结点)和V-U(尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边

代码:

//最小生成树 普里姆算法
//最小生成树 普里姆算法    采用邻接矩阵存储
void MiniSpanTree(MGraph *G)
{
 int min, i, j, k;
 int adjvex[MaxVex];  //保存相关顶点下标
 int lowcost[MaxVex]; //保存相关顶点间边的权值
 lowcost[0] = 0;   //初始化第一个权值为0,即V0加入生成树
 adjvex[0] = 0;   //初始化第一个顶点下标为0

 for (i=1; i<G->numVertexes; ++i)
 {
  lowcost[i] = G->arc[0][i];
  adjvex[i] = 0;    //将v0顶点与之有边的权值存入数组  并初始化都为v0的下标
 }

 for (i=1; i<G->numVertexes; ++i)
 {
  min = INFINITY;

  j = 1;
  k = 0;

  while (j<G->numVertexes)
  {
   //如果两个顶点之间存在边并且权值小于min
   if (lowcost[j]!=0 && lowcost[j]<min)
   {
    min = lowcost[j];
    k = j;
   }

   ++j;
  }
  printf("(%d, %d)", adjvex[k], k); //输出当前顶点边中权值最小的边
  lowcost[k] = 0;      //将当前顶点的权值设为0,表示此顶点已经完成任务
  for (j=1; j<G->numVertexes; ++j)
  {
   if (lowcost[j]!=0 && G->arc[k][j]<lowcost[j])
   {
    lowcost[j] = G->arc[k][j];
    adjvex[j] = k;
   }
  }
 }

 
此图表示将0作为生成树的根,然后把与相关的顶点权值存在lowcost数组中.这里1,2,3结点的权值保存在lowcost中(  lowcost[i] = G->arc[0][i];)
而那些没有相邻接的顶点,权值将是无穷大,紫色表示与0相关的
int min, i, j, k;
 int adjvex[MaxVex];  //保存相关顶点下标
 int lowcost[MaxVex]; //保存相关顶点间边的权值
 lowcost[0] = 0;   //初始化第一个权值为0,即V0加入生成树
 adjvex[0] = 0;   //初始化第一个顶点下标为0

 for (i=1; i<G->numVertexes; ++i)
 {
  lowcost[i] = G->arc[0][i];
  adjvex[i] = 0;    //将v0顶点与之有边的权值存入数组  并初始化都为v0的下标
 }



那么在3个邻接点中选取权值最小的与0相邻接

 for (i=1; i<G->numVertexes; ++i)
 {
  min = INFINITY;//开始min赋值为无穷大

  j = 1;,k = 0;  k表示用来保存权值最小的顶点

  while (j<G->numVertexes)
  {
   //如果两个顶点之间存在边并且权值小于min
   if (lowcost[j]!=0 && lowcost[j]<min)//如果等于0就是本身顶点,不等于权值表示是是相邻接的顶点
   {
    min = lowcost[j];
    k = j;//保存最小的顶点值,这里k=2了
   }

   ++j;
  }
  //这里打印 0,2
  printf("(%d, %d)", adjvex[k], k); //输出当前顶点边中权值最小的边
lowcost[k] = 0;      //将当前顶点的权值设为0,表示此顶点已经完成任务

   图片
这里是关键
lowcost保存的是0与各个顶点的权值,而现在lowcost[2]=0表示此顶点收入到最小二叉树
2与之相邻的结点的权值是为arc[2][i];如果2与之向邻接的顶点和lowcost也相邻,那么把邻接2个的权值,最小的赋值给lowcost,
图中表示的灰色的线表示放弃此线,相当于把最小的权值赋值给lowcost
lowcost[k] = 0;      //将当前顶点的权值设为0,表示此顶点已经完成任务
  for (j=1; j<G->numVertexes; ++j)
  {
   if (lowcost[j]!=0 && G->arc[k][j]<lowcost[j]) //这里表示的就是最小的赋值给lowcost
   {
    lowcost[j] = G->arc[k][j];//lowcostd获取最小的权值
    adjvex[j] = k;
   }
  }


  图片
然后把2中与之相邻接的点找出权值最小的邻接,然后将此下标的lowcost=0;将此点纳入最小二叉树中
下面和上面一样的思想,那就不过多叙述了,根据上面,大家应该能看懂了 
图片
图片
图片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值