算法代码:
Status PrimMiniSpanTree(MGraph G,int v)//v为生成树的第一个顶点由用户指定
{
int min,k,j,i;
lowcost[MAXVEX];
adjvex[MAXVEX];
for(i =0 ; i < G.vexnums; i++)
{
lowcost[i] = G.arc[v][i];//初始化lowcost数组为生成树第一个顶点到每一个顶点的距离
adjvex[i] = v;//初始每一个顶点都邻接到生成树第一个顶点
}
//lowcost[v] = 0;表示加入到了生成树中了,但是我觉得在初始化中已经被置为0了所以觉得这个没多大用
//也许是增加可读性吧
for(i = 0; i < G.vexnums; i++)
{
min = INFINITY;//让min成为一个不可能到达的极大值
while(j = 0; j < G.vexnums; j++)
{
if(lowcost[j] != 0 && lowcost[j] < min)//第一个判断为是否已经加入生成树,加入了不做处理
{
min = lowcost[j];//经过判断把最小的一个权值找出来
k = j;//将最小下标保存在k里面
}
}
//将找到的最小的权值邻接的下标的lowcost加入最小生成树
lowcost[k] = 0;
//对新入的顶点的处理,此处就打印就行了
printf("%d",k);
//对lowcost数组进行调整,这个循环不做注释,在最后再说
for(j = 0; j < G.vexnums; j++)
{
if(lowcost[j] != 0 && G.arc[k][j] < lowcost[j])
{
lowcost[j] = G.arc[k][j];
adjvex[j] = k;
}
}
}
}
由于对lowcost数组的调整个人觉得是Prim算法中的主要思想,所以拿到最后来详细总结。
Prim的主要算法就是从一个顶点出发,第一步把所有与这个顶点邻接的权值加入lowcost数组
再从lowcost数组里面找出最小的一个来,把这条边连接的顶点加入生成树,同时保持lowcost数组不变
用新加入的点遍历所有未加入生成树的点(if语句中的lowcost[j]!=0的作用),如果有小于之前lowcost数组的值
就把lowcost对应下标的值改为与这个点邻接的权值,并把最小值邻接的下标改为新加入的点。
大概思想感觉有贪心法有一点相似,就是要从当前所有的生成树的顶点邻接的顶点的边里面选出最小的一个边
并把这个边的顶点加入生成树,再从这个点扩散。简单的说就是加入一个顶点的过程要经过把以前的Lowcost数组
的值和最新加入的顶点所邻接的顶点的权值中选出邻接到相同顶点中权值比较小的存入Lowcost数组中。然后遍历
lowcost数组选出最小的权值的下标加入生成树再进行上一步。算法中的adjvex数组实际没多大的作用。