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)不参加后续最短边的选取;

 未完待续,,,

 

 

 

原文地址:https://www.cnblogs.com/jeff-wgc/p/4484168.html