1 #include<stdio.h>
2 #include "iostream"
3 #include "stdlib.h"
4
5 #define MAXVERTEX 20
6
7 typedef struct {
8 char vexs[MAXVERTEX];//顶点向量
9 int arcs[MAXVERTEX][MAXVERTEX];//邻接矩阵
10 int vexnum, arcnum;//(无向)图当前顶点数和弧数
11 }Graph;
12
13 typedef struct {
14 char v, w;
15 int edge;
16 }Treever;
17
18
19
20 //创建图,读取:顶点数,顶点向量,邻接矩阵;-1代表无穷大;0是自环,不考虑
21 void creatGraph(Graph &G) {
22 scanf_s("%d\n", &G.vexnum);
23 for (int i = 0; i < G.vexnum; i++) {
24 scanf_s("%c", &G.vexs[i]);
25 }
26 int a = 0;
27 for (int i = 0; i < G.vexnum; i++)
28 {
29 for (int j = 0; j < G.vexnum; j++) {
30 scanf_s("%d", &G.arcs[i][j]);
31 if (G.arcs[i][j] > 0)
32 a++;
33 if (G.arcs[i][j] == -1)
34 G.arcs[i][j] = INT_MAX;
35 }
36 }
37 G.arcnum = a / 2;
38 }
39
40 void Prim(Graph & G, Treever MinTREE[]) {
41 int flag[MAXVERTEX] = { 0 };
42 int i, j, mincost = INT_MAX, key1=0,key2 = 0;
43 for (i = 1; i < G.vexnum; i++) {//n个顶点,则有n-1个边,即n-1个Treever
44 MinTREE[i].v = G.vexs[i];
45 MinTREE[i].edge = INT_MAX;
46 }
47
48 for (i = 1; i < G.vexnum; i++) {//i用来记录进行了n-1次循环
49 mincost = INT_MAX;
50 for (j = 1; j < G.vexnum; j++) {//比较矩阵key1行每个弧长与Tree对应的,改为小值
51 if (G.arcs[key1][j] < MinTREE[j].edge&&flag[j] != 1)
52 {
53 MinTREE[j].edge = G.arcs[key1][j];//改变弧长时同时改变对应的邻接点
54 MinTREE[j].w = G.vexs[key1];
55 }
56 if (MinTREE[j].edge < mincost&&flag[j] != 1)
57 {
58 mincost = MinTREE[j].edge;//记录最短弧长
59 key2 = j;
60 }
61 }
62 flag[key2] = 1;
63 key1 = key2;
64 }
65
66 }
67 //从小到大
68 void sortlist1(Graph & G, Treever list[]) {//构建排序邻接表(不重复,去掉对称),从小到大
69 int i, j, a = 1;
70 for (i = 0; i < G.vexnum; i++) {
71 for (j = i + 1; j < G.vexnum; j++) {
72 if (G.arcs[i][j] != INT_MAX) {
73 list[a].edge = G.arcs[i][j];
74 list[a].v = G.vexs[i];
75 list[a].w = G.vexs[j];
76 a++;
77 }
78 }
79 }
80 //选择排序
81 int min,mini=21;
82 Treever temp;
83 for (j = 1; j <= G.arcnum; j++)//list数组元素个数等于弧数
84 {
85 min = list[j].edge;
86 mini = j;
87 for (i = j+1; i <= G.arcnum; i++)
88 {
89 if (list[i].edge < min) {
90 min = list[i].edge;
91 mini = i;
92 }
93 }
94 if (mini != j) {
95 temp = list[mini];
96 list[mini] = list[j];
97 list[j] = temp;
98 }
99 }
100 }
101
102 int index(char h) {
103 int a = 0;
104 if (h >= '0'&&h <= '9')
105 a = h - '0';
106 else if (h >= 'a'&&h <= 'z')
107 {
108 a = h - 'a';
109 }
110 else
111 {
112 if (h >= 'A'&&h <= 'Z')
113 a = h - 'A';
114 }
115 return a;
116 }
117 int findroot(int root[], char l) {//不能只通过判断两点是否在同一集合上,来判断是否有回路;需要找根,根相同说明两点连上有回路
118 int a = index(l);
119 while (root[a] != -1)
120 a = root[a];
121 return a;
122 }
123
124 void Kruskal(Graph & G, Treever MinTREE[]) {
125 Treever list[MAXVERTEX];
126 sortlist1(G, list);
127 int root[MAXVERTEX],i,j,p1,p2,k=1;
128 for (i = 0; i < G.vexnum; i++)
129 root[i] = -1;
130 for (i = 1; i <= G.arcnum; i++) {
131 p1 = findroot(root, list[i].v);
132 p2 = findroot(root, list[i].w);
133 if (p1 != p2)
134 {
135 MinTREE[k] = list[i];
136 root[index(list[i].w)] = index(list[i].v);
137 k++;
138 }
139 }
140 }
141
142 int FirstAdj(Graph &G, int v) {
143 int i;
144 for (i = 0; i < G.vexnum; i++) {
145 if (G.arcs[v][i] < INT_MAX&&G.arcs[v][i] != 0)
146 return i;
147 }
148 return -1;
149 }
150
151 int NextAdj(Graph &G, int v, int w) {
152 int i;
153 for (i = w+1; i < G.vexnum; i++) {
154 if (G.arcs[v][i] < INT_MAX&&G.arcs[v][i] != 0)
155 return i;
156 }
157 return -1;
158 }
159
160 void DFS(Graph &G, int v,int visited[]) {
161 visited[v] = 1;
162 for (int w = FirstAdj(G, v); w >= 0; w = NextAdj(G, v, w))
163 if (!visited[w])
164 DFS(G, w, visited);
165 }
166
167 int connect(Graph&G) {//若连通,只从顶点0开始深度搜索,即可遍历全部顶点
168 int visited[MAXVERTEX] = { 0 };
169 DFS(G, 0, visited);
170 for (int i = 0; i < G.vexnum; i++) {
171 if (visited[i] == 0)
172 return 0;
173 }
174 return 1;
175 }
176 //从大到小
177 void sortlist2(Graph & G, Treever list[]) {//构建排序邻接表(不重复,去掉对称),从大到小
178 int i, j, a = 1;
179 for (i = 0; i < G.vexnum; i++) {
180 for (j = i + 1; j < G.vexnum; j++) {
181 if (G.arcs[i][j] != INT_MAX) {
182 list[a].edge = G.arcs[i][j];
183 list[a].v = G.vexs[i];
184 list[a].w = G.vexs[j];
185 a++;
186 }
187 }
188 }
189 //选择排序
190 int max,maxi = 21;
191 Treever temp;
192 for (j = 1; j <= G.arcnum; j++)//list数组元素个数等于弧数
193 {
194 max = list[j].edge;
195 maxi = j;
196 for (i = j + 1; i <= G.arcnum; i++)
197 {
198 if (list[i].edge > max) {
199 max = list[i].edge;
200 maxi = i;
201 }
202 }
203 if (maxi != j) {
204 temp = list[maxi];
205 list[maxi] = list[j];
206 list[j] = temp;
207 }
208 }
209 }
210
211
212 //去边法
213 void De_edge(Graph & G, Treever MinTREE[]) {
214 Treever list[MAXVERTEX];
215 sortlist2(G, list);
216 int key,a=1,ard=G.arcnum;
217 for (int i = 1; i <= ard; i++) {
218 key = G.arcs[index(list[i].v)][index(list[i].w)];
219 G.arcs[index(list[i].v)][index(list[i].w)] = G.arcs[index(list[i].w)][index(list[i].v)] = INT_MAX;
220 G.arcnum--;
221 if (!connect(G)) {
222 G.arcs[index(list[i].v)][index(list[i].w)] = G.arcs[index(list[i].w)][index(list[i].v)] = key;
223 G.arcnum++;
224 MinTREE[a] = list[i];
225 a++;
226 }
227 }
228
229 }
230
231 void print(Graph & G, Treever MinTREE[]) {
232 for (int i = 1; i < G.vexnum; i++)
233 printf("%c ,%d ,%c\n", MinTREE[i].v, MinTREE[i].edge, MinTREE[i].w);
234 }
235
236 int main() {
237 Graph G;
238 Treever MinTREE[MAXVERTEX];
239 creatGraph(G);
240 printf("Prim算法:\n");
241 Prim(G, MinTREE);
242 print(G, MinTREE);
243 printf("Kruskal算法:\n");
244 Kruskal(G, MinTREE);
245 print(G, MinTREE);
246 printf("去边法:\n");
247 De_edge(G, MinTREE);
248 print(G, MinTREE);
249 system("PAUSE");
250 }