closedge[5].adjvex = 3.
closedge[5].lowcost = 6.
以此类推,直至U = V;
下图给出了在用上述算法构造网图7.16的最小生成树的过程中:
Prim 算法实现:算法实现:
按照算法框架:
(1)U={u1},T={};
(2)while (U≠V)do
(u,v)=min{wuv;u∈U,v∈V-U }
T=T+{(u,v)}
U=U+{v}
(3)结束。
当无向网采用二维数组存储的邻接矩阵存储时,Prim 算法的C 语言实现为:
//记录从顶点集U到V—U的代价最小的边的辅助数组定义:
// struct{
// VertexType adjvex;
// VRType lowcost;
// }closedge[ MAX_VERTEX_NUM ]
void MiniSpanTree_PRIM (MGraph G,VertexType u){
//用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边。
k =LocateVex(G,u);
for(j=0; j<G.vexnum; ++j)
if(j!=k) closedge[j] ={u ,G.arcs[k][j].adj}; // {adjvex , lowcost}
closedge[k].lowcost =0; //初始,U={u}
for( i=1;i<G.vexnum;++i){ //选择其余G.vexnum-1个顶点
k=minimum(closedge);
printf(closedge[k].adjvex, G.vexs[k]);//输出生成树的边
//第k顶点并入U集
closedge[k].lowcost=0;
for(j=0; j<G.vexnum; ++j)
if (G.acrs[k][j].adj<closedge[j].lowcost) closedge[j]={G.vexs[k],G.arcs[k][j].adj};
}//for
}//MiniSpanTree
假设网中有n个顶点,则第一个进行初始化的循环语句的频度为n,第二个循环语句的频度为n-1。其中有两个内循环:其一是
在closedge[v].lowcost中求最小值,其频度为n-1;其二是重新选择具有最小代价的边,其频度为n。 由此,普里姆算法的时间
复杂度为O(n2),与网中的边数无关,因此适用于求边稠密的网的最小生成树。
2.克鲁斯卡尔(克鲁斯卡尔(Kruskal)) :由点到线,适合边稀疏的网。时间复杂度:由点到线,适合边稀疏的网。时间复杂度:O(e * loge)
Kruskal 算法是一种按照网中边的权值递增的顺序构造最小生成树的方法。一种按照网中边的权值递增的顺序构造最小生成树的方法。
基本思想是:
1) 设无向连通网为G=(V,E),令G 的最小生成树为T,其初态为T=(V,{}),即开始时,最小生成树T 由图G 中的n 个
顶点构成,顶点之间没有一条边,这样T 中各顶点各自构成一个连通分量。
2) 在E中选择代价最小的边,若该边依附的顶点落在T中不同的连通分量,则将此边加入到T中,否则舍弃此边而选择下一条
边(若该边依附的两个顶点属于同一个连通分量,则舍去此边,以免造成回路)。依此类推,当T 中的连通分量个数为1 时,
此连通分量便为G 的一棵最小生成树。