最小生成树-Kruskal(克鲁斯特算法)

1.直接附代码

    /**
     * 克鲁斯卡尔(Kruskal)算法-最小生成树
     */
    public void kruskal() {
        int index = 0; //结果数组的索引
        int[] vends = new int[mVexs.length]; //用于保存已有最小生成树中每个顶点在该最小树中的终点(表示第i个顶点对应的终点是j,则这么存vends[i]=j)
        Edge[] rets = new Edge[mEdgeNum]; //结果数组,用于存kruskal最小生成树的边
        Edge[] edges; //图对应的所有的边

        //获取图中所有的边
        edges = getEdges();
        //将图中所有的边按照由小到大的顺序排序
        sortEdges(edges, mEdgeNum);
        for (int i = 0; i < mEdgeNum; i++) {
            int p1 = getPostion(edges[i].from);
            int p2 = getPostion(edges[i].to);  //获取第i条边的起点的位置和终点的位置
            int m=getEnd(vends,p1);
            int n=getEnd(vends,p2);
            //如果两个顶点都最终指向同一个顶点,则会造成回路,此时判断是否造成回路,如果不造成回路,则将边放于kruskal最小生成树的边数组中 
            if(m!=n){
                vends[m]=n;
                rets[index++]=edges[i];
            }
        }


        for(int i=0;i<vends.length;i++){
            System.out.println(vends[i]);
        }

        int length=0;
        for(int i=0;i<index;i++){
            length+=rets[i].weight;
        }
        System.out.println("Kruskal:"+length);
        for(int i=0;i<index;i++){
            System.out.println(rets[i].from+"->"+rets[i].to);
        }

    }






    /**
     * 获取图中的边
     *
     * @return
     */
    private Edge[] getEdges() {
        int index = 0;
        Edge[] edges;
        edges = new Edge[mEdgeNum];
        for (int i = 0; i < mVexs.length; i++) {
            ENode node = mVexs[i].firstEdge;
            while (node != null) {
                //如果是无向图的话,同一个边,方向不同,将会存取一条
                if (node.ivex > i) {
                    edges[index++] = new Edge(mVexs[i].data, mVexs[node.ivex].data, node.weight);
                }
                node = node.nextEdge;

            }
        }
        return edges;

    }


    /**
     * 对边进行排序(由小到大)
     *
     * @param edges
     * @param mEdgeNum
     */
    public void sortEdges(Edge[] edges, int mEdgeNum) {
        for (int i = 0; i < mEdgeNum; i++) {
            for (int j = i + 1; j < mEdgeNum; j++) {
                if (edges[i].weight > edges[j].weight) {
                    Edge temp = edges[i];
                    edges[i] = edges[j];
                    edges[j] = temp;
                }
            }

        }
    }


    //获取i的终点,最终指向终点,加入C->D,D->E,已知D的终点是E,vends[4]=5;C->D,vends[2]=4;此时getEnd(i=2)求得的结果便是5,相当于通过D间接指向E
    private int getEnd(int[] vends, int i) {

        while (vends[i] != 0) {
            i = vends[i];
        }
        return i;
    }

2.原理:

3.算法分析:

转载于:https://my.oschina.net/u/2263272/blog/1610260

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值