最小生成樹-Kruskal(克魯斯特算法)

1.直接附代碼java

/**
     * 克魯斯卡爾(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.原理:node

3.算法分析:算法

相關文章
相關標籤/搜索