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.算法分析:算法