最小生成树

  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 }

 

posted @ 2020-04-22 20:07  简单记录一下咯  阅读(146)  评论(0编辑  收藏  举报