Ch08 kruscal算法

7/26/2019 Algorithm

# kruscal算法

也是求最小生成树(适合求稀疏的网)

思路:按照权值大小选择n-1条边,并保证不构成回路

1.排序

2.判断是否构成回路

  • 某个顶点的终点:把顶点排好后,与它连通的最大顶点,也就是标记同一棵树
  • 终点相同的两个顶点不能连起来,否则会构成回路

image-20230421002535633

image-20230421002603386

image-20230421002624880

image-20230421002655409

image-20230421002730430

image-20230421002743274

image-20230421002933065

image-20230421002948116

image-20230421002959227

import java.util.Arrays;


public class KruskalDemo {
	public static int INF = Integer.MAX_VALUE;
	public int edgenum = 0;//边的数量
	public int num;//节点的数量
	public char[] vertex;//顶点信息
	public int[][] weight;//边的权值,邻阶矩阵
	//存放边的数组
	public Edge[] edges;
	//存放结果数组
	public Edge[] results;
	//存放终点
	public int[] end;
	public KruskalDemo(int num, char[] vertex, int[][] weight) {
		this.num = num;
		this.vertex = vertex;
		this.weight = weight;
		
		for(int i = 0; i < num; i++) {
			for(int j = i + 1; j < num;j++) {
				if(this.weight[i][j] != INF) {
					edgenum++;
				}
			}
		}
		
		edges = new Edge[edgenum];
		results = new Edge[edgenum];
		end = new int[num];
		//把邻阶矩阵转换到边的集合里
		int m = 0;
		for(int i = 0; i < num; i++) {
			for(int j = i + 1; j < num;j++) {
				if(weight[i][j] != INF) edges[m++] = new Edge(i, j, weight[i][j]);
			}
		}
	}
	
	public void showGraph() {
		for(int i = 0; i < num;i++) {
			for(int j = 0; j < num;j++) {
			System.out.printf("%15d", weight[i][j]);
			}
			System.out.println();
		}
	}
	//对边进行排序
	public void sortEdge() {
		Arrays.sort(edges);
	}
	//获取某个顶点的终点
	public int getEnd(int vertex) {
		while(end[vertex] != 0) {
			vertex = end[vertex];
		}
		return vertex;
	}
	public void kruscal() {
		int index = 0;

		//1.对边进行排序
		this.sortEdge();
		//2.判断是否存在回路:看终点是否一样
		for(int i = 0; i < edgenum; i++) {
			int v1 = edges[i].v1;
			int v2 = edges[i].v2;
			int end1 = this.getEnd(v1);
			int end2 = this.getEnd(v2);
			if(end1 != end2) {
				results[index++] = edges[i];
				end[end1] = end2;
			}
			
			//输出
			for(int j: end) {
				System.out.print(j + " ");
			}
			System.out.println();
		}
		
		
	}

	public static void main(String[] args) {
		int num = 5;
		char[] vertex = new char[] {'A', 'B', 'C', 'D', 'E'};
		int[][] weight = new int[][] {
		    { 0, 5, INF, 8, 10 }, 
			{ 5, 0, 2, INF, 6 }, 
			{ INF, 2, 0, 3, INF },
			{ 8, INF, 3, 0, INF }, 
			{ 10, 6, INF, INF, 0 } 
		};
		KruskalDemo kruskal = new KruskalDemo(num, vertex, weight);
		kruskal.kruscal();

		for(Edge i: kruskal.results) {
			System.out.println(i);
		}
		for(int i = 0; i < kruskal.num; i++) {
			System.out.println(kruskal.getEnd(i));
		}
		
	}

}
//边的类
class Edge implements Comparable<Edge>{
	public int v1;
	public int v2;
	public int weight;
	public Edge(int v1, int v2, int weight) {
		super();
		this.v1 = v1;
		this.v2 = v2;
		this.weight = weight;
	}
	@Override
	public String toString() {
		return "Edge [v1=" + v1 + ", v2=" + v2 + ", weight=" + weight + "]";
	}
	@Override
	public int compareTo(Edge o) {
		if(this.weight < o.weight) return -1;
		else if(this.weight > o.weight) return 1;
		else {
			return 0;
		}
	}
	
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
Last Updated: 11/19/2024, 1:54:38 PM