最小生成树--prim算法

prim算法生成最小生成树

先描述下prime算法:

N={V,{E}}  其中,顶点集V和边集{E}

从U={u0} u0是V的子集,TE={}开始。在所有在U中的结点和不足U中的结点中找到一条代价最小的边(u0,v0),合入TE,将v0。直到U=V。

具体实现如下:

#include <stdlib.h>
#include <stdio.h>
#define INFINITY 100
typedef struct
{
    int vexs[9];
 int arc[9][9];
 int numVertexes,numEdges;
}MGragh;

void CreateGragh(MGragh *G)
{
 int i,j,k,w;
 printf("input the vex and edges:");
 scanf("%d%d",&G->numVertexes,&G->numEdges);
 for (i=0; i<G->numVertexes; i++)
  G->vexs[i]=i;

 for (i=0; i<G->numVertexes; i++)
  for (j=0; j<G->numVertexes; j++)  
  {
   G->arc[i][j]=INFINITY;
         G->arc[i][i]=0;
  }
 printf("input the (i,j)edge's value:\n");
 for(k=0; k<G->numEdges;k++) 
 {
   scanf("%d%d%d",&i,&j,&w);
   G->arc[i][j]=w;
   G->arc[j][i]=G->arc[i][j];
 }
}

void MiniTree_Prim(MGragh *G)
{
 int min,i,j,k;
 int adjvex[9];
 int lowcost[9];
 lowcost[0]=0;// 标记顶点0已经在U中
 adjvex[0]=0;
 // U中仅有v0点的初始化
 for(i=1; i<G->numVertexes; i++)
 {
  lowcost[i]=G->arc[0][i];
  adjvex[i]=0;
 }
 
 for(i=1; i<G->numVertexes; i++)
 {
  //从U出发的边集中,到U-V顶点集中中找到最小的边lowcost
  min=1000;
  j=1;k=0;
  while(j<G->numVertexes)
  {
   if((lowcost[j]!=0)&&(min > lowcost[j]))
   {
    min=lowcost[j];//找到最小的边
    k=j ;//找到最小的边对应在U-V中的顶点,另一顶点已经在U中
   }
   j++;
  }
  printf("(%d,%d)\n",adjvex[k],k);
  lowcost[k]=0;//标记顶点k已经在U中
  //看k加入U后的集合中,是否存在更短的边
  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;
   }
  }
 }
}

void main()
{
 MGragh *gragh;
 gragh=(MGragh *)malloc(sizeof(MGragh));
 CreateGragh(gragh);
 MiniTree_Prim(gragh);
 system("pause");
}

输入:9 (顶点数)14(边数)

初始化边:

0 1 10
0 5 11
1 2 18
1 6 16
1 8 12
2 3 22
2 8 8
3 4 26
3 7 16
3 8 21
4 5 26
4 7 7
5 6 17
6 7 19

输出结果:

(0,1)
(0,5)
(1,8)
(8,2)
(1,6)
(6,7)
(7,4)
(7,3)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 分析,建立两个数组adjvex[MAXVEX] ;      如 adjvex[i] = j; // 表示与当前结点 i 连结的是结点 j

lowcost[MAXVEX]; 如 lowcoast[i]=j; // 表示到结点i的最小代价为j.当j=0时,表示标记该结点已经锁定为最小生成树中的结点。

#define INFINITY 65535

void MiniSpanTree_Prim(MGragh G)  // 采用邻接矩阵存储边的权值

{

    int  min, i, j, k;

    int  adjvex[MAXVEX] ;    

    int  lowcost[MAXVEX];

    lowcost[0]=0;  //初始化v0为第一个结点,值为0表示已经锁定。

    for (i=1; i<G.numVertexes; i++)

   {

        lowcost[i]=G.arc[0][i];

        adjvex[i]=0; //所有结点都与v0结点连边。viv0边

   } //至此,初始化完成。从v0结点开始。

   //下面要找与某结点(第一次是v0)连结的最小的顶点的边

   for(i=1; i<G.numVertexes; i++)

   {

       min=INFINITY;

       j=1;

       k=0; //标记最小结点

       while(j<G.numVertexes)

       {

            if (lowcost[j] != 0 && lowcost[j] < min)   //遍历所有到j结点的值,找到最小。

           {

                 min = lowcost[j];

                 k    =  j;

           }

           j++;

       }

       printf("(%d,%d)",adjVex[k],k); //找到lowcost[k]中k的l连结结点adjVex[k],组成边。即为最小生成树的其中的边。

       lowcost[k] = 0;

       //下面将结点k所连结的的所有结点的边信息存储。在下一次比较最小权值边时进行比较。

       for (j=1; j<G.numVextexes; j++)

       {

            if (lowcost[j] != 0 && G.arc[k][j]<lowcost[j])

            {

                lowcost[j] = G.arc[k][j]; //lowcost[j]是j 结点的最小边值

                adjvex[j]=k;   //重要,这里保证了通过lowcost[j]得到的 j,可以找到与它连结的结点 i .形成一条边。

            }

       }

   }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值