MST之kruskal算法
一、普里姆(Prim)算法
1.基本思想:设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是G的最小生成树, T的初始状态为U={u0}(u0∈V),TE={},重复执行下述操作:在所有u∈U,v∈V-U的边中找一条代价最小的边(u, v)并入集合TE,同时v并入U,直至U=V。即:
(1)从连通网络 G = { V, E }中的某一顶点 u0 出发,选择与它关联的具有最小权值的边(u0, v),将其顶点加入到生成树的顶点集合U中。
(2)以后每一步从一个顶点在U中,而另一个顶点不在U中的各条边中选择权值最小的边(u, v),把它的顶点加入到集合U中。如此继续下去,直到网络中的所有顶点都加入到生成树顶点集合U中为止。
2.示例:
3.实现:
1 void MiniSpanTree_PRIM(MGraph G, VertexType u) 2 { 3 // 用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边。 4 // 记录从顶点集U到V-U的代价最小的边的辅助数组定义: 5 // struct { 6 // VertexType adjvex; 7 // VRType lowcost; 8 // } closedge[MAX_VERTEX_NUM]; 9 k = LocateVex ( G, u ); 10 for ( j=0; j<G.vexnum; ++j ) 11 { // 辅助数组初始化 12 if (j!=k) 13 { closedge[j].adjvex=u; closedge[j].lowcost=G.arcs[k][j].adj; } 14 } 15 closedge[k].lowcost = 0; // 初始,U={u} 16 for (i=1; i<G.vexnum; ++i) 17 { // 选择其余G.vexnum-1个顶点 18 k = minimum(closedge); // 求出T的下一个结点:第k顶点 19 // 此时closedge[k].lowcost = 20 // MIN{ closedge[vi].lowcost | closedge[vi].lowcost>0, vi∈V-U } 21 printf(closedge[k].adjvex, G.vexs[k]); // 输出生成树的边 22 closedge[k].lowcost = 0; // 第k顶点并入U集 23 for (j=0; j<G.vexnum; ++j) 24 if (G.arcs[k][j].adj < closedge[j].lowcost) 25 { 26 // 新顶点并入U后重新选择最小边 27 closedge[j] = { G.vexs[k], G.arcs[k][j].adj }; 28 } 29 } 30 }
二、克鲁斯卡尔(Kruskal)算法
1. 基本思想:设无向连通网为G=(V, E),令G的最小生成树为T=(U, TE),其初态为U=V,TE={ },然后,按照边的权值由小到大的顺序,考察G的边集E中的各条边。若被考察的边的两个顶点属于T的两个不同的连通分量,则将此边作为最小生成树的边加入到T中,同时把两个连通分量连接为一个连通分量;若被考察边的两个顶点属于同一个连通分量,则舍去此边,以免造成回路,如此下去,当T中的连通分量个数为1时,此连通分量便为G的一棵最小生成树。
2.示例:
3.实现:
1 1. 初始化:U=V; TE={ }; 2 2. 循环直到T中的连通分量个数为1 3 2.1 在E中寻找最短边(u,v); 4 2.2 如果顶点u、v位于T的两个不同连通分量,则 5 2.2.1 将边(u,v)并入TE; 6 2.2.2 将这两个连通分量合为一个; 7 2.3 在E中标记边(u,v),使得(u,v)不参加后续最短边的选取;
未完待续,,,
悠游天地间 all rights reserved. © 2013 -- 1 << 64