最小生成树--Prim算法

最近研究图论的算法,接触到构建最小生成树的prim算法(当然还有其他方法:Kruskal算法也可以构建),所以记录一下。
首先,什么是最小生成树?
百度百科给出的定义:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。
概念有点抽象,下面用一幅图来演示说明。
这里写图片描述

那么如何构建一棵最小生成树呢?有下面三个步骤:
1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:U={x},其中x为集合V中的任一节点(起始点),T={},为空;
3).重复下列操作,直到U=V:

    a、在集合E中选取全值最小的边<u,v>,其中u为集合U中的元素,而v不在U集合里面,
       并且v属于V(如果存在多条满足前述条件,即具有相同权值的边,则可以任意选取其中之一);
    b、将v加入集合U中,将<u,v>边加入集合T中;

4).输出:使用集合U和T,来描述所得到的最小生成树。

下面用图来展示上面给出的步骤:

这里写图片描述

代码如下:

/**
* prim最小生成树
*/
public  void prim(){
char[] code={'A','B','C','D','E','F','G'};
 ArrayList<Integer> u =new ArrayList<>();
 //默认A是第一个节点
 u.add(3);
 //T{}
 ArrayList<int[]> t =new ArrayList<>();
 //重复直到U=T
 while(u.size()!=this.verticeSize){
     int tmp=BGraph.MAXVERTICESIZE;
     int tmpi=0;
     int pi=0,pj=0;
     //找最短距离
     for (int i = 0; i < u.size(); i++) {
         tmpi=u.get(i);
         for (int j = 0; j < this.verticeSize; j++) {
             if(this.verticesEde[tmpi][j]!=0&&this.verticesEde[tmpi][j]<tmp){
                 tmp=this.verticesEde[tmpi][j];
                 pi=tmpi;
                 pj=j;
             }
         }
     }
     if(tmp!=BGraph.MAXVERTICESIZE){
        //找到最短距离
         t.add(new int[]{pi,pj,verticesEde[pi][pj]});
         u.add(pj);
         //代表已经访问过
         this.verticesEde[pi][pj]=0;
         this.verticesEde[pj][pi]=0;
     }
 }
 int sum=0;
 for (int i = 0; i < t.size(); i++) {
     int[] nums=t.get(i);
     sum+=nums[2];
    System.out.println(code[nums[0]]+"  ->  "+code[nums[1]]);
}
 System.out.println("最小生成树总代价:"+sum);
}


//测试代码
Graph graph=new Graph(7);
int[] a0={0,50,60,MAXVERTICESIZE,MAXVERTICESIZE,MAXVERTICESIZE,MAXVERTICESIZE};
int[] a1={50,0,MAXVERTICESIZE,65,40,MAXVERTICESIZE,MAXVERTICESIZE};
int[] a2={60,MAXVERTICESIZE,0,52,MAXVERTICESIZE,MAXVERTICESIZE,45};
int[] a3={MAXVERTICESIZE,65,52,0,50,30,42};
int[] a4={MAXVERTICESIZE,40,MAXVERTICESIZE,50,0,70,MAXVERTICESIZE};
int[] a5={MAXVERTICESIZE,MAXVERTICESIZE,MAXVERTICESIZE,30,70,0,MAXVERTICESIZE};
int[] a6={MAXVERTICESIZE,MAXVERTICESIZE,45,42,MAXVERTICESIZE,MAXVERTICESIZE,0};
graph.verticesEde[0]=a0;
graph.verticesEde[1]=a1;
graph.verticesEde[2]=a2;
graph.verticesEde[3]=a3;
graph.verticesEde[4]=a4;
graph.verticesEde[5]=a5;
graph.verticesEde[6]=a6;
graph.prim();

运行结果:
    A   ->  B
    B   ->  E
    E   ->  D
    D   ->  F
    D   ->  G
    G   ->  C
最小生成树总代价:257
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值