最小生成树算法——Kruskal算法Java实现
2013-04-18 21:00
926 查看
闲来无事,写个算法,最小生成树的Kruskal算法,相对比Prim算法实现起来麻烦一点点
package trees; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.PriorityQueue; import java.util.Set; /** * 最小生成树的Kruskal算法, * For a connected weighted graph G, a spanning tree T of G is constructed as follows: * For the first edge e1 of T, we select any edge of G of minimum weight and for the second * edge e2 of T, we select any remaining edge of G of minimum weight. For the third edge e3 * of T,we choose any remaining edge of G of minimum weight that dose not produce a cycle with * the previousely selected edges. We continue in this manner until a spanning tree is produced. * @author xhw * */ public class KruskalMinimumSpanningTree { /** * @param args */ public static void main(String[] args) { double graph[][]={{0,1,4,4,5}, {1,0,3,7,5}, {4,3,0,6,Double.MAX_VALUE}, {4,7,6,0,2}, {5,5,Double.MAX_VALUE,2,0}}; double tree[][]=minimumSpanningTree(graph); if(tree==null) { System.out.println("no spanning tree"); System.exit(0); } PriorityQueue<Edge> edgeList=generateEdgeList(tree); for(Edge e:edgeList) { System.out.println(e); } } /** * 给定一个带权值的邻接矩阵(其中若i=j,权值为0,若i和j不可达权值为Double.max),返回一个最小生成树, * @param graph * @return */ public static double[][] minimumSpanningTree(double[][] graph) { int rlength=graph.length; int clength=graph[0].length; PriorityQueue<Edge> edgeList; edgeList=generateEdgeList(graph); double tree[][]=new double[rlength][clength]; /** * 初始化tree */ for(int i=0;i<rlength;i++) { for(int j=0;j<clength;j++) { if(i==j) tree[i][j]=0; else tree[i][j]=Double.MAX_VALUE; } } /** * map用于标识边的某个顶点属于哪个集合,认为顶点刚开始属于不同的集合,当选择一条边时,就合并两个集合,如果选择的边在同一个集合内,就代表有环路出现了 */ Map<Integer,Set<Integer>> map=new HashMap<Integer,Set<Integer>>(); int edgeCount=0; while(edgeCount<rlength-1&&!edgeList.isEmpty()) { Edge e=edgeList.poll(); Set<Integer> setU=map.get(e.u); Set<Integer> setV=map.get(e.v); //System.out.println(e); //边的两个顶点都未出现在其他集合中 if(setU==null&&setV==null) { Set<Integer> set=new HashSet<Integer>(); set.add(e.u); set.add(e.v); map.put(e.u, set); map.put(e.v, set); }//有一个顶点在其他集合中,一个不在,将不在的那个顶点集合合并进去 else if(setU==null&&setV!=null) { map.put(e.u, setV); setV.add(e.u); } else if(setU!=null&&setV==null) { map.put(e.v, setU); setU.add(e.v); }//分别在不同的集合中,合并两个集合 else if(setU!=setV) { for(int v:setV) { map.put(v, setU); } setU.addAll(setV); }//两个顶点在同一个结合中,会出现环路,舍弃 else { continue; } tree[e.u][e.v]=e.weight; tree[e.v][e.u]=e.weight; edgeCount++; } if(edgeCount==rlength-1) return tree; else return null; } /** * 生成边的排序好的队列 * @param graph * @return */ private static PriorityQueue<Edge> generateEdgeList(double[][] graph) { PriorityQueue<Edge> edgeList=new PriorityQueue<Edge>(); int rlength=graph.length; int clength=graph[0].length; for(int i=0;i<rlength;i++) { for(int j=i+1;j<clength;j++ ) { if(graph[i][j]>0&graph[i][j]<Double.MAX_VALUE) { Edge e=new Edge(i,j,graph[i][j]); edgeList.add(e); } } } return edgeList; } } class Edge implements Comparable<Edge> { int u; int v; double weight; public Edge(int u, int v, double weight) { super(); this.u = u; this.v = v; this.weight = weight; } @Override public int compareTo(Edge e) { if(e.weight==weight) return 0; else if(weight<e.weight) return -1; else return 1; } public String toString() { return u+"--"+v+":"+weight; } }
相关文章推荐
- 算法java实现--贪心算法--最小生成树问题--Kruskal算法
- prim 最小生成树算法 java实现
- Kruskal算法求解最小生成树的Java实现
- prim 最小生成树算法 java实现
- 【算法和数据结构】图(三)最小生成树之Kruskal算法(C++实现)
- java编写Kruskal算法实现最小生成树
- 最小生成树的Prim算法和Kruskal算法java代码实现
- 十二、图的算法入门--(3)最小生成树---Kruskal算法实现
- 【算法】Kruskal算法(解决最小生成树问题) 含代码实现
- java实现最小生成树的prim算法和kruskal算法
- 最小生成树算法——Prim和Kruskal算法的实现
- 最小生成树之Kruskal算法 Java实现
- java实现图的最小生成树(MST)的普利姆(Prim)算法
- 最小生成树-Kruskal算法 java代码实现
- 最小生成树的Prim算法和Kruskal算法java代码实现
- Kruskal算法实现最小生成树MST(java)
- Java实现最小生成树Kruskal算法
- 最小生成树-Kruskal算法 java代码实现
- 最小生成树的Kruskal算法java代码实现
- java实现图的最小生成树(森林)MST克鲁斯卡尔(Kruskal)算法