java编写Prim算法实现最小生成树(LazyPrim算法的优化版)

来源:互联网 发布:肺活量测量仪器软件 编辑:程序博客网 时间:2024/06/14 15:53

之前写的"java实现最小生成树问题"是用LazyPrim算法解决的,时间复杂度为O(ElogE),现在用的Prim算法的时间复杂度为O(ElogV)级别。

 PrimMST类中我将之前存储Edge的最小堆换成了存储权值的最小索引堆

类PrimMST

public class PrimMST {private SparseGraph sg;   //稀疏图private IndexMinHeap imh;   //最小索引堆(保存被标记节点相邻横切边的权值)private ArrayList<Edge> edgeTo=new ArrayList<Edge>(); //保存被标记节点相邻横切边private boolean marked[];private ArrayList<Edge> mst=new ArrayList<Edge>();  //存储最小生成树的Edgeprivate int mstWeight;    //最小的权值和public PrimMST(SparseGraph sg) {this.sg = sg;imh=new IndexMinHeap(sg.V());  //以图的顶点数为容量marked=new boolean[sg.V()];for(int i=0;i<sg.V();i++){marked[i]=false;edgeTo.add(null);}mst.clear();//Prim算法visit(0);while(!imh.isEmpty()){int v=imh.extractMinIndex();   //取出当前被访问节点的相邻横切边权值中的最小值的Edge索引assert(edgeTo.get(v)!=null);   mst.add(edgeTo.get(v));        //将这条Edge加入最小生成树visit(v);}mstWeight=mst.get(0).wt();for(int i=1;i<mst.size();i++){mstWeight+=mst.get(i).wt();}}private void visit(int v){assert(!marked[v]);marked[v]=true;ArrayList<Edge> arr=sg.getGraph(v);Iterator<Edge> ite=arr.iterator();while(ite.hasNext()){Edge e=ite.next();int w=e.other(v);if(!marked[w]){if(edgeTo.get(w)==null){      //判断这条Edge是否已经被加入了edgeToimh.insert(w, e.wt());   //将当前被访问的v点的相邻横切边的权值插入imh   edgeTo.set(w, e);        //将当前被访问的v点的相邻横切边加入edgeTo}else if(e.wt()<edgeTo.get(w).wt()){   imh.set(w, e.wt());    //修改w节点的权值edgeTo.set(w, e);      //修改w点的横切边为新值}}}}public ArrayList<Edge> mstEdges(){return mst;}public int result(){return mstWeight;}public static void main(String[] args) {int N=20;  //顶点int M=200;   //边SparseGraph sg=new SparseGraph(N,false);for(int i=0;i<M;i++){sg.addEdge(new Random().nextInt(N), new Random().nextInt(N),new Random().nextInt(100)+1);//权值[1,101)}PrimMST la=new PrimMST(sg);System.out.println("最小生成树为");ArrayList<Edge> arr=la.mstEdges();for(int i=0;i<arr.size();i++){System.out.println("{"+arr.get(i).v()+"-"+arr.get(i).w()+",wt:"+arr.get(i).wt()+"}");}System.out.println();System.out.println("最小权值和为"+la.result());}}
结果如图:
下面比较一下两种算法的耗时,下面是比较代码:
                int N=20;  //顶点int M=200;   //边SparseGraph sg=new SparseGraph(N,false);for(int i=0;i<M;i++){sg.addEdge(new Random().nextInt(N), new Random().nextInt(N),new Random().nextInt(100)+1);//权值[1,101)}System.out.println("PrimMST耗时:");long startTime=System.nanoTime();   //获取开始时间PrimMST la=new PrimMST(sg);long endTime=System.nanoTime(); //获取结束时间  System.out.println("程序运行时间: "+(endTime-startTime)+" 纳秒"); System.out.println("LazyPrimMST耗时:");long s_startTime=System.nanoTime();   //获取开始时间LazyPrimMST lpm=new LazyPrimMST(sg);long s_endTime=System.nanoTime(); //获取结束时间  System.out.println("程序运行时间: "+(s_endTime-s_startTime)+" 纳秒"); 

比较结果如下图:



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宽松连衣裙显胖怎么办 牛仔裙老是卷边怎么办 毛边牛仔裙卷边怎么办 牛仔裤短裤卷边怎么办 牛仔裙太宽了怎么办 牛仔裙腰围小了怎么办 牛仔a字裙大了怎么办 牛仔a字裙易变形怎么办 红色皮衣染色了怎么办 羽绒服干了结块怎么办 羽绒服手洗后鸭毛堆在一起怎么办 白色羽绒服发霉了怎么办 早晨起床双脚冷怎么办 黑色棉衣粘毛怎么办 貂皮大衣旧了怎么办 pu皮床头掉皮怎么办 背心领子大怎么办鸡心 羊毛裙子缩水了怎么办 背带裙背带老掉怎么办 背带裙背带坏了怎么办 黑色衣服发红了怎么办 公司拖欠离职员工工资怎么办 windows系统坏了怎么办 背带裙肩带总掉怎么办 四个月宝宝干咳怎么办 4个多月宝宝干咳怎么办 小孩吃饭不嚼怎么办 四个月宝宝积食怎么办 新生儿睡枕头了怎么办 宝宝半夜练翻身怎么办 宝宝牙齿长歪怎么办 婴儿睡觉头歪怎么办 婴儿放在床就哭怎么办 宝宝米粉没吃完怎么办 宝宝吃米粉上火怎么办 幼儿发烧怎么办 两岁 七个月婴儿厌食怎么办 打卤时肉总是沾在一起怎么办 宝宝大便头干硬怎么办 婴儿辅食机的水怎么办 三岁宝宝牙痛怎么办