最小生成树定义:
在一个具有V个节点的连通无向图中,找到一个子图,该子图包含原图的所有节点和部分连接边,且不能形成回路,同时子图边的权值总和最小。
最小生成树的算法:
根据对安全边的不同规则,有两种算法可以生成最小生成树。即Kruskal算法和Prim算法
Kruskal算法
Kruskal算法使用的贪婪准则是:从剩下的边中选择一条不会产生环路,且具有最小耗费的边加入已选择的边的集合中;
假设 G=(V,{E}) 是一个含有 n 个顶点的连通网,则按照 Kruskal算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。
该算法找到安全边的方法是:在所有连接森林中两颗不同树的边里面,找到权值最小的边。
步骤:
- 在带权值连通图中,按边的权值大小进行排序。
- 根据权值大小顺序判断集合是否需要该边,若集合需要该边,则将该边的两端节点加入到集合中,并使其连通。
- 循环第二步,直到所有节点都在集合中。
判断法则:当将边加入到已找到边的集合中时,是否会形成回路?
1.如果没有形成回路,那么直接将其连通。此时,对于边的集合又要做一次判断:这两个点是否在已找到点的集合中出现过?
①.如果两个点都没有出现过,那么将这两个点都加入已找到点的集合中;
②.如果其中一个点在集合中出现过,那么将另一个没有出现过的点加入到集合中;
③.如果这两个点都出现过,则不用加入到集合中。
2.如果形成回路,不符合要求,直接进行下一次操作。
下面根据带权值连通图对Kruskal算法的工作流程进行讲解:
上图为原图;连接边按照权值的大小排序:即;Kruskal算法按照权值从小到大进行判断,判断连接边节点是否属于集合A。
第一步:判断权值为1的连接边hg是否属于集合,由于开始集合为空,则将两个节点加入到集合,且连接该边,并判断是否属于回路;
第二步:判断权值为2的连接边ic是否属于集合,由于集合只有节点h和g,则将节点i和c加入到集合中,且连接该边,并判断是否属于回路;
第三步:判断权值为2的连接边gf是否属于集合,根据判断规则,把f加入到集合,且连接该边;
第四步:根据判断规则,将节点a和b加入到集合,且连接该边;
第五步:根据判断规则,连接该边cf;