zoukankan      html  css  js  c++  java
  • 图的最小子树算法--Kruskal和Prim

    一、Kruskal

    1.算法思想:每次挑最小的边生成子树,不断合并子树生成最小子树

    2.算法步骤

    (1)构造一个边类,放两个顶点和边长,还有一个isvisit用来知道该边是否被访问过

    class Edge//
    {
        String A;
        String B;
        int length;
        boolean isvisit=false;
        //getter setter
    }

    (2)初始化数据

            HashMap<String,String> Points=new HashMap<>();//放顶点,和顶点所属的子树群
            ArrayList<Edge> Edges=new ArrayList<>();//放边的信息
            Edges.add(new Edge("A","B",2));
            Edges.add(new Edge("A","D",4));
            Edges.add(new Edge("A","C",5));
            Edges.add(new Edge("B","C",4));
            Edges.add(new Edge("C","D",6));
            Edges.add(new Edge("B","E",5));
            Edges.add(new Edge("D","F",7));
            Edges.add(new Edge("C","E",3));
            Edges.add(new Edge("C","F",4));
            Edges.add(new Edge("E","F",1));
            printKruskal(Points,Edges);//调用函数

    (3)写工具函数

    selectMin()挑选最小边 

    getGroup() 获得子树群信息,用来合并子树

    private static Edge selectMin(ArrayList<Edge> edges) {
            int min=999;
            int index=-1;
            for(int i=0;i<edges.size();i++)
            {
                if(edges.get(i).isvisit==false&&edges.get(i).getLength()<min)
                {
                    index=i;
                    min=edges.get(i).getLength();
                }
            }
            edges.get(index).setIsvisit(true);
            //System.out.println("!"+edges.get(index).getA()+"<=>"+edges.get(index).getB()+" length="+edges.get(index).getLength());
            return edges.get(index);
        }

    private static ArrayList<String> getGroup(String str,HashMap<String, String> points) 
        {
            ArrayList<String> result=new ArrayList<>();
            for(Entry<String,String> entry:points.entrySet())
            {
                if(entry.getValue().equals(str))
                {
                    result.add(entry.getKey());
                }
            }
            return result;
        }

    (4)逻辑处理和输出结果

    private static void printKruskal(HashMap<String, String> points,ArrayList<Edge> edges) 
        {
            ArrayList<Edge> result=new ArrayList<>();
            while(result.size()<5)
            {  
            Edge e=selectMin(edges);
            while(points.get(e.getA())!=null&&points.get(e.getA()).equals(points.get(e.getB())))
            {
                e=selectMin(edges);
            }
            if(points.get(e.getA())==null&&points.get(e.getA())==null)
            {
                points.put(e.getA(), e.getA());
                points.put(e.getB(), e.getA());
            }
            else if(points.get(e.getA())==null)
            {
                points.put(e.getA(), e.getB());
            }
            else if(points.get(e.getB())==null)
            {
                points.put(e.getB(), e.getA());
            }
            else
            {
                ArrayList<String> groupB=getGroup(points.get(e.getB()),points);
                for(String str:groupB)
                {
                    points.put(str, e.getA());
                }
            }
            result.add(e);
            System.out.println(e.getA()+"<=>"+e.getB()+" length="+e.getLength());
            }
    
        }

    3.结果截图

     二、Prim

    1.算法思想:从一个顶点出发,不断挑选已有数可到达的最小边,直到生成最小生成树

    2.算法步骤:

    (1)构造边类:同上

    (2)数据初始化:同上

    (3)逻辑处理:

            ArrayList<Edge> result=new ArrayList<>();
            ArrayList<String> now=new ArrayList<>();//已有顶点
            now.add("A");//从A出发
            while(now.size()<6)
            {
                int min=999;
                Edge minEdge=null;
                for(Edge e:edges)
                {
                    for(int i=0;i<now.size();i++)
                    {
                        if(now.get(i).equals(e.getA())||now.get(i).equals(e.getB()))
                        {
                            if(!e.isIsvisit()&&e.getLength()<min)
                            {
                                min=e.getLength();
                                minEdge=e;
                            }
                        }
                    }
                }
                minEdge.setIsvisit(true);
                if(now.contains(minEdge.getA()))
                {
                    now.add(minEdge.getB());
                }
                else
                {
                    now.add(minEdge.getA());
                }
                System.out.println(minEdge.getA()+"<=>"+minEdge.getB()+" length="+minEdge.getLength());
                result.add(minEdge);
            }

    3.结果截图

  • 相关阅读:
    摄像机镜头详细知识 镜头选型
    镜头Lens Image circle像圈的解释是什么意思
    IC封装的热特性
    接收灵敏度
    步进电机选型
    步进电机步距角、相数、转矩
    锂电池充电的原理
    通过反射了解集合泛型的本质
    用方法对象进行反射
    java反射获取方法名称,参数类型
  • 原文地址:https://www.cnblogs.com/blogofjzq/p/9250852.html
Copyright © 2011-2022 走看看