算法描述:
U为最小生成树中顶点的集合,初始U={u0};
从剩下的顶点中找到一个权值最小的直接相连的顶点V,把它加入U;
重复,直到所有的顶点都加入到U中。
代码:
#include <stdio.h>
#include <stdlib.h>
//图的邻接矩阵存储结构
typedef char VertexType;//顶点类型应由用户定义
typedef int EdgeType;//边上的权值类型应由用户定义
#define MAXVEX 9 //最大顶点数,应由用户定义
#define INFINITY 65535 //用65535代表无穷远,表示不相邻
typedef struct
{
//VertexType vexs[MAXVEX];//顶点表
EdgeType arc[MAXVEX][MAXVEX];//邻接矩阵,可看作边表
int numVertexes,numEdges;//图中当前的顶点数和边数
}MGraph;
//建立邻接矩阵
void CreateMGraph(MGraph *G)
{
int i,j;
G->numVertexes = 9;
G->numEdges=15;
//初始化图
for(i=0;i<G->numVertexes;i++)
for(j=0;j<G->numVertexes;j++)
{
if(i==j)
G->arc[i][j] = 0;
else
G->arc[i][j] =INFINITY;
}
G->arc[0][1]=10;
G->arc[0][5]=11;
G->arc[1][2]=18;
G->arc[1][6]=16;
G->arc[1][8]=12;
G->arc[2][3]=22;
G->arc[2][8]=8;
G->arc[3][4]=20;
G->arc[3][7]=16;
G->arc[3][8]=21;
G->arc[4][5]=26;
G->arc[4][7]=7;
G->arc[5][6]=17;
G->arc[6][7]=19;
//对称矩阵
for(i=0;i<G->numVertexes;i++)
for(j=i;j<G->numVertexes;j++)
G->arc[j][i] = G->arc[i][j];
}
//Prim算法生成最小生成树
void MiniSpanTree_Prim(MGraph G)
{
int min,i,j,k;
int adjvex[MAXVEX]; //保存相关顶点下标
int lowcost[MAXVEX]; //保存相关顶点间边的权值
lowcost[0]=0; //V0作为最小生成树的根开始遍历,权值为0
adjvex[0]=0; //V0第一个加入最小生成树
//初始化操作
for(i=1;i<G.numVertexes;i++)
{
lowcost[i]=G.arc[0][i];//将邻接矩阵第0行所有权值先加入数组
adjvex[i]=0; //初始化全部为V0的下标
}
//构造最小生成树的过程
for(i=1;i<G.numVertexes;i++)
{
min = INFINITY; //初始化最小权值为65535等不可能数值
j=1;
k=0;
//遍历全部顶点
while(j<G.numVertexes)
{
//找出lowcost数组已存储的最小权值
if(lowcost[j]!=0 && lowcost[j]<min)
{
min = lowcost[j];
k=j; //将发现的最小权值的下标存入k,以待使用
}
j++;
}
//打印当前顶点边上权值最小的边
printf("(%d,%d)",adjvex[k],k);
lowcost[k] = 0; //将当前顶点的权值设置为0,表示此顶点已经完成任务,进行下一个顶点的遍历
//邻接矩阵k行逐个遍历全部顶点
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;
}
}
}
}
int main()
{
MGraph G;
CreateMGraph(&G);
MiniSpanTree_Prim(G);
return 0;
}
结果: