最小代价生成树算法

  • 一颗带权无向图的生成树的代价cost是该生成树中所有边的代价(权重之和)。最小代价生成树(minimum cost spanning tree)就是一颗代价最小的生成树。
  • 可以采用三种不同的算法获得无向图的最小代价生成树。这三种算法采用的算法设计策略都是贪心法(greedy method)
    • Kruskal算法
    • Prim算法
    • Sollin算法

Kruskal算法

  • Kruskal算法:通过每次向当前最小代价树T中加入一条边的方法构造最终的最小生成树T。算法按照边的代价非递减的顺序选取,并加入T中。如果选取的边与T中的边不形成环路,则这条边加入到T中。由于图G是连通的,且具有n个顶点(n>0),所以最终恰好选取n-1条边加入到T中。
# Kruskal算法 伪代码
# E 边的集合
T={}; # T为最小生成树的边 
while(T 包含少于n-1条边 并且 E不为空){
  从E选择一条最小代价的边 (v,w);
  从E删除边 (v,w);
  if ((v,w) 在T中没有创造环路){
    add (v,w) 到 T 中;
  }else{
    discard (v,w);
  }
}
if (T 包含的边少于n-1条){
  print("no spanning tree!\n");
}

Prim算法

  • Prim算法:通过每次增加一条边的方法来构造一颗最小代价生成树。与Kruskal算法不同的是,在每一步,Prim所选取的边集形成一颗树,而Kruskal算法所选取的边集形成一个森林。Prim算法从只包含一个顶点的树T开始,该顶点可以是原图中的任意一个顶点。然后,把一条最小代价的边(u,v)加入T中,使T ∪ {(u,v)}仍是一棵树。重复上述加入边的过程指导T中包含了n-1条边为止。为了保证所加入的边不形成环路,要求在每一步所选取的边(u,v)的两个顶点u和v,只能有一个顶点在T中。
# Prim算法伪代码
T = {};
TV = {0}; # 满足条件的顶点集
while(T包含少于n-1条边){
  寻找一条代价最小的边(u,v),u ∈ TV && v ∉ TV;
  if(没有这样的边) break;
  add v to TV;
  add (u,v) to T;
}
if (T 包含的边少于n-1条){
  print("no spanning tree!\n");
}

Sollin算法

  • Sollin算法:Sollin算法在每一步为生成树T递归地选取若干条边。每一步处理开始时,所选取的边与图中的所有n个顶点形成一个生成森林。在每一步处理过程中,为森林中的每棵树都选取一条边,所选取的边都是恰有一个顶点在树上且代价最小。由于森林中的两棵树可能选取了同一条边,所以需要去掉同一条边被多次选取的情况。在开始时,所选取的边集为空。当最后结果只有一棵树或者再没有边可供选择时,算法结束。
# Sollin算法伪代码
T={};
# 初始化当前所有点生成的森林。
for v in Vertexs{
  add v to T;
}
while(T包含少于n-1条边){
  for t in T{
    为每个森林寻找最小代价的边加入森林。
  }
  合并森林。
  if (森林无变化)break;
}
if (T 包含的边少于n-1条){
  print("no spanning tree!\n");
}

参考来源 数据结构(C语言版)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值