最小生成树算法-kruskal:
graph[][] 图
lines[] 图的所有边
nodes[] 所有节点(初始值所有节点,每个节点的父子均为空)
static class Line{
public Line(int from, int to, int weight){
this.from = from;
this.to = to;
this.weight = weight;
}
int from;
int to;
int weight;
public int getFrom() {
return from;
}
public void setFrom(int from) {
this.from = from;
}
public int getTo() {
return to;
}
public void setTo(int to) {
this.to = to;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
1:对 lines 排序 遍历 lines
public static List<Line> getSortLines(int[][] graph){
List<Line> lines = new ArrayList<Kruskal.Line>();
for (int i = 0; i < graph.length; i++){
for (int j = 1; j < graph[i].length; j++){
lines.add(new Line(i, j, graph[i][j]));
}
}
LOG.d("before sort:", lines);
lines = sortList(lines);
LOG.d("after sort:", lines);
return lines;
}
public static List<Line> sortList(List<Line> lines){
Collections.sort(lines, new Comparator<Line>() {
@Override
public int compare(Line o1, Line o2) {
return o1.weight - o2.weight;
}
});
return lines;
}
2:从 lines 获取边 min。
3:判断边的起点 from,终点 to 是否在一个树上。
如果在一个树上回到 1,如果不在:from.next.add(to) 在nodes 中删除 to;(或者此处用 prev 数组表示父子节点关系,此处就要将 prev[to] = from )
注:此处可添加 sum+= min;用于计算最小生成树的路长总和。
4:直到所有节点在一个树中。
// lines所有边集合
// previous前驱节点集合
public static int kruskal(int[][] graph){
List<Line> lines = getSortLines(graph);
int[] previous = new int[graph.length];
for (int i = 0; i < graph.length; i++){
previous[i] = i;
}
int sum = 0;
for (int i = 0; i < lines.size(); i++){
int k = 0;
int j = 0;
for (k = lines.get(i).from; previous[k] != k;k = previous[k]){
}
for (j = lines.get(i).to; previous[j] != j; j = previous[j]){
}
LOG.d(k, " ", j);
if (k != j && lines.get(i).weight != GraphUtils.MAX){
LOG.d(lines.get(i));
previous[j] = previous[lines.get(i).from];
sum += lines.get(i).weight;
}
}
return sum;
}