Prim算法通过不断地增加生成树的顶点来得到最小生成树。在算法的任一时刻,一部分顶点已经添加到生成树的顶点集合中,而其余的顶点尚未加到生成树中。此时,Prim算法通过选择边(u,v),使得(u,v)的权值是所有u在生成树中但v不在生成树中的边的权值的最小者,从而找到新的顶点v并把它添加到生成树中,最后得到生成树的所有EDGE。
下面是代码
template <class EdgeType>
Edge<EdgeType> * Prim(Graph<EdgeType>& G, int s)//Prim法建立最小生成树
{
int i, j;
Edge<EdgeType> *MST;//存储最小生成树的边
EdgeType *minWeight;//表示每个节点到生成树节点中的最小权值
int *neighbor;//表示每个未进入生成树的节点,对应生成树中的最小权值节点的编号 -1表示已经在生成树节点集中
int n = G.vertexNum;
minWeight = new EdgeType[n];
neighbor = new int[n];
MST = new Edge<EdgeType>[n - 1];
for (i = 0; i < n; i++)
{
minWeight[i] = AFFINITY;
neighbor[i] = s;
}
neighbor[s] = -1;
Edge<EdgeType> e;
for (e = G.FirstEdge(s); G.IsEdge(e); e = G.NextEdge(e))
{
minWeight[e.end] = e.weight;
}
for (i = 0; i < n - 1; i++)
{
EdgeType min = AFFINITY;
int v = -1;//标记下一个要进入生成树的节点编号
for (j = 0; j < n; j++)
{
if (minWeight[j]<min&&neighbor[j]>-1)//找到目前最小权值的未进入生成树的节点的条件
{
min = minWeight[j];
v = j;
}
}
if (v > 0)//进行将最小权值的节点加入到生成树中并且向MST添加新的边,还有更新两个数组的信息
{
Edge<EdgeType> temp(neighbor[v], v, min);
MST[i] = temp;
neighbor[v] = -1;
for (e = G.FirstEdge(v); G.IsEdge(e); e = G.NextEdge(e))
{
if (neighbor[e.end] != -1 && minWeight[e.end] > e.weight)
{
neighbor[e.end] = v;
minWeight[e.end] = e.weight;
}
}
}
}
delete[] minWeight;
delete[] neighbor;
return MST;
}