Prim算法作用是构造连通网的最小代价生成树。
算法思想:以任意一个点开始,找权值最小的一条边,将此边和两个顶点加入最小生成树集合,以最小生成树的点集合中的每一个点为起点,找寻终点不在集合中的权值最小的边,并将结果加入集合,重复这个操作,直至所有的点都已经加入集合。
相关数据定义:
/*
图的邻接矩阵表示
*/
typedef char VertexType;
typedef int EdgeType;
#define MAXVEX 100
#define INFINITY 65535
typedef struct
{
VertexType vexs[MAXVEX];
EdgeType arc[MAXVEX][MAXVEX];
int numVertexes,numEdges;
}MGraph;
算法代码:
/*
最小生成树Prim算法
目前最优方法,先从一个点开始,然后逐步扩大查询范围,在一定的范围内找最小权值的边
*/
void MiniSpanTree_Prim(MGraph G)
{
int min,i,j,k;
/*
记录边
*/
int adjvex[MAXVEX];
/*
下标表示节点编号,即第几个节点
值代表从下标到adjvex[下标]所代表的边的权值
*/
int lowcost[MAXVEX];
lowcost[0] = 0;
adjvex[0] = 0;
for(i=1;i<G.numVertexes;i++)
{
lowcost[i] = G.arc[0][i];
adjvex[i] = 0;
}
for(i=1;i<G.numVertexes;i++)
{
min = INFINITY;
j=1;
k=0;
/*
查询以某个顶点开始(第一次是0)权值最小的一个边
*/
while(j<G.numVertexes)
{
if(lowcost[j] != 0 &&lowcost[j] <min)
{
min = lowcost[j];
k = j;
}
j++;
}
printf("(%d,%d)",adjvex[k],k);
/*
记录已经找到最小值的边
*/
lowcost[k] = 0;
/*
与while循环功能类似,找出新加入的点的权值最小的邻接边
*/
for(j=0;j<G.numVertexes;j++)
{
if(lowcost[j]!=0 && G.arc[k][j] < lowcost[j])
{
lowcost[j] = G.arc[k][j];
/*
adjvex数组代表的是:adjvex[j] -> j 这条边
*/
adjvex[j] = k;
}
}
}
}