1.问题
举一个实例,画出采用Prim算法构造最小生成树的过程。
2.解析
已知图V = {…} 我们构造一棵最小生成树T
第一步:随意选取起点
第二步:在前一步的基础上寻找最小权值
第三步:继续寻找最小权值,之后以此类推,直到遍历完所有的节点。
实例:
图V如下图所示
①
任意选择一个点
这里我们选择A点
从A点出发有两条路,一条通向B(权值为3),一条通向D(权值为4)
我们选择权值较小的点B
此时被选中的点:A B
②
与B相邻的点:C(权值为3)、D(权值为5)
与A相邻的点:D(权值为4)
我们选取权值最小的点 C
此时被选中的点:A B C
③
接下来
D与AB相邻(DA权值4,DB权值5),E与C相邻(CE权值7)
取最小D
此时被选中的点:A B C D
④
最后取权值最小(DE)的E点
最小生成树如图所示
3.设计
void MiniSpanTree(MGraph *G)
{
int min, i, j, k;
int adjvex[MaxVex]; //保存相关顶点下标
int lowcost[MaxVex]; //保存相关顶点间边的权值
lowcost[0] = 0; //初始化第一个权值为0,即V0加入生成树
adjvex[0] = 0; //初始化第一个顶点下标为0
//初始化操作
for (i=1; i<G->numVertexes; ++i)
{
lowcost[i] = G->arc[0][i];
adjvex[i] = 0; //将v0顶点与之有边的权值存入数组 并初始化都为v0的下标
} //adjvex[i],i是其他节点的标记,adjvex[i]=0即是把0~n的节点都与节点0关联起来
for (i=1; i<G->numVertexes; ++i)
{
min = INFINITY;
j = 1;
k = 0; //保存权值最小的顶点
//遍历v-u集合中剩下的节点
while (j<G->numVertexes)
{
//如果两个顶点之间存在边并且权值小于min
if (lowcost[j]!=0 && lowcost[j]<min)
{
min = lowcost[j];
k = j;
}
++j;
}
printf("(%d, %d)", adjvex[k], k); //输出当前顶点边中权值最小的边
lowcost[k] = 0; //将当前顶点的权值设为0,表示此顶点已经完成任务
//更新新节点与其他节点之间的最小花费和关联
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;
}
}
}
}