如题 自用笔记 如有错误欢迎及时指正
所用存储结构与基本操作见下文
对于求取任意一个带权无向连通图的最小生成树的问题,在要求总的权值最小的情况下,最直接的想法就是将连通网中的所有边按照权值大小进行升序排序,从小到大依次选择。由于最小生成树本身是一棵生成树,一颗最小生成树必然满足以下两点:
a).树中任意顶点之间有且仅有一条路径,即树中不能存在回路;
b.)具有n个顶点的连通图,其最小生成树中只能有 n-1 条边,这 n-1 条边连通着 n 个顶点;
Kruskal算法
基本思想
算法每轮选取与已求出的MST不构成回路的最小权值边,直到图变为n个顶点n-1条边的连通图为止。
设图中有e条边,其时间性能为O(eloge) ,是对边归并的算法,适合边稀疏图求取MST。
算法描述与正确性
描述:
1.将边按照权值从小到大排列;
2.遍历第一条边并将其加入MST里,判断是否出现回路;
3.如果出现回路则跳过,否则将该边加入MST;
4.继续遍历其余边验证,直到所有的边都遍历完;
正确性:
将边按权值大小排序完成后,将第一条边加入MST后,必然得到一颗MST,加入第二条边时,MST依旧成立。
加入第三条边时,若三条边形成回路,则略过该边,已知边集合已按权值从小到大排序,此时MST仍然成立,若加入第三条边不形成回路时,将其直接加入MST,MST仍然成立。
综上,在n个顶点图中遍历n-1条边后,必然求出一颗MST。
实现时要做的工作
1.获取图中所有边,需要一个结构体和数组来保存;
2.边从小到大排序,方便之后归并;
3.判定已选边是否构成回路(有多种方法,为便于讨论仅给出一个);
判定回路方法:设置两个变量保存当前所选边的起始顶点与结尾顶点下标,找到这两个顶点在已求出MST中的终点下标,比较两者的终点下标是否相等,相等则加入该边到MST中会出现回路,否则加入该边到MST中不会出现回路。
辅助工具
//辅助结构体
typedef struct EdgeData{
VertexType start; //边起始顶点
VertexType end; //边结尾顶点
int weight; //边权值
} EData;
//按权值从小到大对边排序
void SortEdges(EData *edges, int length){
int i,j;
for (i=0; i<length; i++){
for (j=i+1; j<length; j++){
if (edges[i].weight > edges[j].weight){
// 交换"第i条边"和