我们这里用普利姆算法实现。
普利姆算法的知识在以前文章中写过链接在下面:
题目如下:
应用普里姆算法实现求带权联通图最小生成树的,对下图调用该算法(假设从顶点1出发)依次输出其最小生成树的各条边对应的顶点及权值。
代码如下:
#include<stdio.h>
#define MAXV 8
#define INF 32767
typedef char InforType;
typedef struct
{
int no;//顶点编号
InforType info;
}VertexType;
typedef struct
{
int edges[MAXV][MAXV];//邻接矩阵数组
int n,e;//顶点数,边数
VertexType vexs[MAXV];//存放顶点信息
} MatGraph;//完整的图邻接矩阵类型
void CreateMat(MatGraph *G)//创建邻接矩阵
{
int i,j;
for(i=0;i<G->n;i++)
{
for(j=0;j<G->n;j++)
{
G->edges[i][j]=INF;
}
}
for(i=0;i<G->n;i++)
{
j=i;
G->edges[i][j]=0;
}
//给邻接矩阵赋值
G->edges[0][1] = G->edges[1][0] = 4;
G->edges[0][2] = G->edges[2][0] = 3;
G->edges[1][2] = G->edges[2][1] = 5;
G->edges[1][3] = G->edges[3][1] = 5;
G->edges[2][3] = G->edges[3][2] = 5;
G->edges[2][4] = G->edges[4][2] = 5;
G->edges[3][4] = G->edges[4][3] = 4;
G->edges[1][5] = G->edges[5][1] = 9;
G->edges[3][5] = G->edges[5][3] = 7;
G->edges[3][6] = G->edges[6][3] = 6;
G->edges[5][6] = G->edges[6][5] = 3;
G->edges[3][7] = G->edges[7][3] = 5;
G->edges[4][7] = G->edges[7][4] = 6;
G->edges[6][7] = G->edges[7][6] = 2;
//给结点赋编号
G->vexs[0].no=1;
G->vexs[1].no=2;
G->vexs[2].no=3;
G->vexs[3].no=4;
G->vexs[4].no=5;
G->vexs[5].no=6;
G->vexs[6].no=7;
G->vexs[7].no=8;
}
void Prim(MatGraph *G,int v)//普里姆算法
{
int lowcost[MAXV];
int mindist;
int closest[MAXV],i,j,k;
for(i=0;i<G->n;i++)
{
lowcost[i]=G->edges[v][i];
closest[i]=v;
}
for(i=1;i<G->n;i++)
{
mindist=INF;
for(j=0;j<G->n;j++)
if(lowcost[j]!=0&&lowcost[j]<mindist)
{
mindist=lowcost[j];
k=j;
}
printf("边(%d,%d)权为:%d\n",G->vexs[closest[k]],G->vexs[k],mindist);
lowcost[k]=0;
for(j=0;j<G->n;j++)
if(lowcost[j]!=0&&G->edges[k][j]<lowcost[j])
{
lowcost[j]=G->edges[k][j];
closest[j]=k;
}
}
}
int main()
{
MatGraph G;
G.n=8;
int i,j;
CreateMat(&G);
printf("邻接矩阵为:\n");
for(i=0;i<G.n;i++)
{
for(j=0;j<G.n;j++)
{
if(G.edges[i][j]==32767)
printf("INF ");
else
printf("%-3d ",G.edges[i][j]);
}
printf("\n");
}
printf("最小生成树为:\n");
Prim(&G,0);
return 0;
}
运行结果: