Kruskal算法本质是贪心算法,而Prime算法是动态规划。
其实两者都是贪心的思想,只不过考虑的角度不同:
- Prim算法从顶点的角度出发,每次选择距离当前节点最近的节点加入,直到所有节点都加入。
- Kruskal算法从边的角度出发,每次总是选择权重最小的边加入,直到加入n-1条边为止。(如果加入一条边后出现回路,skip这条边)。
prim适合点多的稠密图,kruskal适合边多的。
从代码实现的角度: - Prim算法需要维持一个堆数据结构(实际实现中用priority_queue比较多)
- Kruskal算法需要union-find的数据结构。
Prim算法
该算法的时间复杂度为O(n²),与图中边数无关,该算法适合于点多的、稠密图;
基本思想:以点为对象,挑选与点相连的最短边来构成最小生成树。
Prim算法:设图G =(V,E),其生成树的顶点集合为U。
①、把v0放入U。
②、在所有u∈U,v∈V-U的边(u,v)∈E中找一条最小权值的边,加入生成树。
③、把②找到的边的顶点v加入U集合。如果U集合已有n个元素,则结束,否则继续执行②。
Kruskal算法
该算法的时间主要取决于边数,它较适合于边多的、稀疏图。
基本思想:以边为对象,不断地加入新的不构成环路的最短边来构成最小生成树。
与Prim算法的不同之处在于,Kruskal在找最小生成树结点之前,需要对所有权重边做从小到大排序。将排序好的权重边依次加入到最小生成树中,如果加入时产生回路就跳过这条边,加入下一条边。当所有结点都加入到最小生成树中之后,就找出了最小生成树。