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