java 最小生成树_Prim最小生成树 - java实现

注意,图的最小生成树不一定只有一种

update:

之前的版本是结合我自己和up主的思路写的。今年复习,发现很难理解啊,于是严格按照up主的视频流程实现了一次

65a1f78cb58f3a36482ec4fc4d6c45fd.pngpublic class MinimumSpanningTree {

int[][] map;

public MinimumSpanningTree(int[][] map) {

this.map = map;

}

/**

* @param startNodeIndex 根节点下标

* @return 普里姆算法生成树,数组表示

*/ public int[] prim(int startNodeIndex) {

int[][] map = this.copyMap(this.map);

boolean[] selected = new boolean[map.length];

int[] minDist = new int[map.length];

int[] parent = new int[map.length];

// 初始化

for (int i = 0; i < selected.length; i++) {

selected[i] = false;

minDist[i] = Integer.MAX_VALUE;

parent[i] = -1;

} selected[startNodeIndex] = true;

parent[startNodeIndex] = Integer.MAX_VALUE;

/**

* 1. Update 更新所有与当前选中的顶点集相连的 minDist、parent * 2. Scan 扫描得 update 更新的顶点中(未选中的顶点),minDist 最小的定点 * 3. Add 将 Scan 中扫描到的点的 selected 更新 */ while (!this.isFinished(selected)) {

this.update(map, selected, minDist, parent);

int nodeIndex = this.scan(selected, minDist);

this.add(selected, nodeIndex);

}

return parent;

}

private void update(int[][] map, boolean[] selected, int[] minDist, int[] parent) {

for (int i = 0; i < selected.length; i++) {

// 遍历所有顶点

if (!selected[i]) {

// 找出未选入的节点下标i

int weight = Integer.MAX_VALUE;

for (int j = 0; j < selected.length; j++) {

if (selected[j]) {

// 找出已选入的节点下标j

if (map[i][j] < weight) {

// 如果当前选中的i、j边权,小于之前选中的

weight = map[i][j]; // 得到i、j边权

minDist[i] = weight; // 赋值

parent[i] = j;

} } } } } }

private int scan(boolean[] selected, int[] minDist) {

int minWeight = Integer.MAX_VALUE;

int index = -1;

for (int i = 0; i < minDist.length; i++) {

if (!selected[i] && minDist[i] < minWeight) {

index = i;

minWeight = minDist[i];

} } return index;

}

private void add(boolean[] selected, int nodeIndex) {

selected[nodeIndex] = true;

}

/**

* 判断是否所有顶点都被选中 * * @param selected

* @return

*/

private boolean isFinished(boolean[] selected) {

for (int i = 0; i < selected.length; i++) {

if (!selected[i]) {

return false;

} }

return true;

}

/**

* 复制新的地图 * * @param map 原地图

* @return 复制版地图

*/ private int[][] copyMap(int[][] map) {

int[][] newMap = new int[map.length][map[0].length];

System.arraycopy(map, 0, newMap, 0, map.length);

return newMap;

}

private void logBooleanArray(boolean[] arr) {

for (boolean value : arr) {

System.out.print(value + " ");

} System.out.println(" ");

}

private void logIntArray(int[] arr) {

for (int value : arr) {

System.out.print(value + " ");

} System.out.println(" ");

}

public static void main(String[] args) {

int max = Integer.MAX_VALUE;

int[][] map = {

{max, 4, max, max, max, max, max, 8},

{4, max, 8, max, max, max, max, 11, max},

{max, 8, max, 7, max, 4, max, max, 2},

{max, max, 7, max, 9, 14, max, max, max},

{max, max, max, 9, max, 10, max, max, max},

{max, max, 4, 14, 10, max, 2, max, max},

{max, max, max, max, max, 2, max, 1, 6},

{8, 11, max, max, max, max, 1, max, 7},

{max, max, 2, max, max, max, 6, 7, max}

};

MinimumSpanningTree minimumSpanningTree = new MinimumSpanningTree(map);

int[] res = minimumSpanningTree.prim(0);

for (int i = 0; i < res.length; i++) {

System.out.println(i + " ~ " + res[i]);

}

}}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值