最小生成树详细解析-包教包会
定义
原谅我对最小生成树的定义其实都是很模糊的。
对于上面图左侧,这显然是一个带权重的无向图,而右侧的含义是,对于n个图节点,只用n-1条边就能将所有的节点连接在一起,哪怕再多加一条边,就会生成一个环。我们将这样的图生成的树叫生成树。
对于连通图而言,它一定有生成树,且有可能,存在多种生成树。我们将生成树中这n-1条边的权重和最小的那个生成树,叫做最小生成树。
求最小生成树的两种方法
首先咱们贴上原文的链接,这里我以一个初学者的心态将原文分析一下link
Kruskal 克鲁斯克尔算法
这个算法非常好理解,咱们先贴一张百度百科的图:
克鲁斯克尔算法的核心思想就是,首先将每个节点看做是一颗独立的树,然后找到一条最小代价的边,前提是这个边的左节点和右节点得是来自两颗不同的树。然后就这么迭代下去就完事儿了,你说简单不。
代码实现的话我说一下思路:其实就是维护一下一个升序的边集合,然后不断地找到最小边,并放到不断完善的最小生成图(其实就是个入选的边集合)去判断是不是满足条件。
Prim普里姆算法
这个角度稍微不太一样,它是将所有的节点分成两类,一类是已经被选中的节点,另一类是自由节点。
初始化时,所有节点都是自由节点。然后在自由节点中任选一个节点开始操作:
1.将这个任选节点放到被选中节点中,然后在剩下的自由节点中选择一个节点,这个节点距离任意一个被选中节点的距离是所有的自由节点的最小值,然后把这个自由节点当做被选中节点,同时将这个最小的分支记录下来。
2.循环执行步骤1,直到自由节点数量为0,完成任务。
其实,这个算法的正确性是可以验证的,用反证法即可,这里我就不再展开。
总结
感觉这两个算法还是蛮像的,不过思考的角度是完全不同的。总之是个朴素的算法。