Prime算法是解决最小生成树的一个算法。
不管是Kruskal算法还是Prime算法去,其核心都是切分定理。
切分定理:
切分
把图中的节点分为两部分,称为一个切分(Cut);
横切边
如果一个边的两个端点,属于切分(Cut)不同的两边,这个边称为横切边(Crossing Edge);
切分定理
给定任意切分,横切边中权值最小的边必然属于最小生成树;
切分定理的证明可使用反正法,这里不给出证明,证明不了只需要知道切分定理的正确性就能推出Prime算法的正确性。
Prime算法:
Prime算法是切分定理的正向应用。首先选定一个顶点0,当选择一个顶点后就把它看成一个切分,一部分为已选顶点集合{0},另一部分为未选顶点集合{1,2,3,4,5}。那么此时会出现横切边{{0,1},{0,2},{0,3}}。
按照切分定理选择最小的边,{0,3}则为最小生成树的一条边。此时将{0,3}这条边加入到存储最小生成树的数据结构中,将顶点3加入到已选集合中{0,3},未选集合为{2,4,5},这时横向边集合也发生了改变{{0,2},{0,1},{0,3},{3,7},{3,5},{3,4}}。
可以观察到{0,3}这条边刚刚已经加入到最小生成树中了,已经不再是横向边了。
此时可按照切分定理,选择最小的横向边,将边的另一点加入到已选集合中。
按照这个算法继续往下执行到如图所示:
可发现横向边从{0,2}从橙色变成了绿色。其实很好理解,已选集合{0,2,3,4}中的{0,2}那条边已经没有机会再被选择了,他们内部已经构成了局部最小生成树了。
按照这个算法,直到所有顶点都在已选集合中,算法就计算结束了。
下面代码使用最小堆来实现Prime算法。
Prime代码