首先来看下面这个图:
他所对应的邻接表为:
思路是这样的:
由顶点出发,先访问与它相连接的顶点,找到权值最小的顶点(标记为顶点2)的那个边。选中这条边和对应的顶点。
如果这个顶点和他刚刚选中的那条边对面的那个顶点的其他连线的顶点有边。
那么进行比较,选择权值最小的。因为他和上一个顶点有相同的边。此时,把那边false掉,不参与下面的比较。
随后选择第二个顶点,最小边的权值,然后重复上面的操作
具体代码如下:
// 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;
}
}
}
}