/** * Prim 算法构建最小生成树(节点必须含有权重)<br/> * * 当中每个顶点包含两个标记:(1)指出了最近的树中顶点和边的权重; (2)被选中的顶点和边加粗表示<br/> * * 加入节点u:<br/> * (1)把u*从集合V-Vt移动到树的顶点集合Vt中(V为已加入树的节点的集合,Vt为还没加入树的节点的集合)<br/> * (2)对于集合V-Vt中每一个剩下的顶点u,如果它用一条比u当前距离标记更短的变和u*相连,分别把它的标记更新为u*以及u与u*之间的权重<br/> * <br/> * test: 0 3 0 6 5 3 0 1 0 4 0 1 0 0 4 6 0 0 0 2 5 4 4 2 0<br/> * test: 0 3 0 0 6 5 3 0 1 0 0 4 0 1 0 6 0 4 0 0 6 0 8 5 6 0 0 8 0 2 5 4 4 5 2 0 * * <br/>算法效率:<br/>邻接矩阵,优先队列数组 O(V^2) * <br/>邻接链表,优先队列堆 O(ElogV) * @author chenxuegui * */ public class Prim { // 节点数 static int i = 6; // 输入5个点的权重举证 public static void main(String[] args) { int[][] weight = new int[i][i]; // 初始化权重矩阵,没有通路的以0表示 for (int k = 0; k < i * i; k++) { weight[k / i][k % i] = Integer.valueOf(args[k]); } // 用hash队列充当优先队列 Map<Integer, Integer> map = new HashMap<>(); // 节点输出的顺序 List<Integer> list = new ArrayList<>(); // 初始化优先队列 for (int k = 0; k < i; k++) { map.put(k, k == 0 ? -1 : weight[0][k]); } Prim p = new Prim(); p.prim(weight, map, list, i); for (int i : list) { System.out.println(i); } } /** * * 实现prim算法的核心部分,加入权值最小的点 * * @param weight * @param map * @param list * @param i * 节点数 * @param u * 上一个加入节点 */ private void prim(int[][] weight, Map<Integer, Integer> map, List<Integer> list, int i) { for (int k = 0; k < i; k++) { Iterator<Integer> it = map.keySet().iterator(); // 取得当前优先队列中最优选择 int minKey = 0; int minValue = Integer.MAX_VALUE; while (it.hasNext()) { int key = it.next(); if (map.get(key) < minValue && map.get(key) != 0) { minValue = map.get(key); minKey = key; } } // 把当前最优点(即距离最短的点)加入list中 list.add(minKey); map.remove(minKey); // 跟新当前优先队列中的点的权值 it = map.keySet().iterator(); while (it.hasNext()) { int key = it.next(); int value = map.get(key); if ((map.get(key) > weight[minKey][key] && weight[minKey][key] != 0) || (map.get(key) == 0)) value = weight[minKey][key]; map.put(key, value); } } } }
原文:http://blog.csdn.net/chenxuegui1234/article/details/18601929