最小生成树(Kruskal实现)

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <stdbool.h>
  5 
  6 #define MaxVertexNodeNumSize 1000
  7 #define MaxVertexNodeNameSize 100
  8 
  9 struct VertexBodyNode
 10 {
 11     char VertexName[MaxVertexNodeNameSize];
 12     int ArcWeight;
 13     int VertexIndex;
 14     struct VertexBodyNode *Next;
 15 };
 16 
 17 struct VertexHeadNode
 18 {
 19     char VertexName[MaxVertexNodeNameSize];
 20     int VertexWeight;
 21     struct VertexBodyNode *Next;
 22 };
 23 
 24 struct _Graph
 25 {
 26     struct VertexHeadNode VertexHeadNodeList[MaxVertexNodeNumSize];
 27     int ArcNum,VertexNum;
 28 };
 29 
 30 int VertexName2Index(struct _Graph *UnsignedGraph,char *VName)
 31 {
 32     int i;
 33     for(i = 0; i < UnsignedGraph -> VertexNum; i ++)
 34     {
 35         if(strcmp(UnsignedGraph -> VertexHeadNodeList[i].VertexName,VName)==0)
 36         {
 37             return i;
 38         }
 39     }
 40     return -1;
 41 }
 42 
 43 void AddOneArc(struct _Graph *UnsignedGraph,int ArcIndex_1,int ArcIndex_2,int AWeight)
 44 {
 45     struct VertexBodyNode *BNode_1 = malloc(sizeof(struct VertexBodyNode));
 46     struct VertexBodyNode *BNode_2 = malloc(sizeof(struct VertexBodyNode));
 47 
 48     strcpy(BNode_1 -> VertexName,UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].VertexName);
 49     strcpy(BNode_2 -> VertexName,UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].VertexName);
 50     BNode_1 -> ArcWeight = AWeight;
 51     BNode_2 -> ArcWeight = AWeight;
 52     BNode_1 -> VertexIndex = ArcIndex_1;
 53     BNode_2 -> VertexIndex = ArcIndex_2;
 54     BNode_1 -> Next = BNode_2 -> Next = NULL;
 55 
 56     struct VertexBodyNode *TmpPointer;
 57     TmpPointer = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
 58     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
 59     {
 60         TmpPointer = TmpPointer -> Next;
 61     }
 62     if(TmpPointer==NULL)
 63     {
 64         UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next = BNode_2;
 65     }
 66     else
 67     {
 68         TmpPointer -> Next = BNode_2;
 69     }
 70 
 71     TmpPointer = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
 72     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
 73     {
 74         TmpPointer = TmpPointer -> Next;
 75     }
 76     if(TmpPointer==NULL)
 77     {
 78         UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next = BNode_1;
 79     }
 80     else
 81     {
 82         TmpPointer -> Next = BNode_1;
 83     }
 84 }
 85 
 86 void DeleteOneArc(struct _Graph *UnsignedGraph,int ArcIndex_1,int ArcIndex_2)
 87 {
 88     struct VertexBodyNode *TmpPointer_1,*TmpPointer_2;
 89 
 90     TmpPointer_1 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
 91     TmpPointer_2 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
 92 
 93     while(TmpPointer_2!=NULL && TmpPointer_2->VertexIndex!=ArcIndex_2)
 94     {
 95         TmpPointer_1 = TmpPointer_2;
 96         TmpPointer_2 = TmpPointer_2 -> Next;
 97     }
 98 
 99     if(TmpPointer_2==NULL)
100     {
101         return ;
102     }
103     else if(TmpPointer_1 == TmpPointer_2)
104     {
105         UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next = NULL;
106         free(TmpPointer_2);
107     }
108     else
109     {
110         TmpPointer_1 -> Next = TmpPointer_2 -> Next;
111         free(TmpPointer_2);
112     }
113 
114     TmpPointer_1 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
115     TmpPointer_2 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
116 
117     while(TmpPointer_2!=NULL && TmpPointer_2->VertexIndex!=ArcIndex_1)
118     {
119         TmpPointer_1 = TmpPointer_2;
120         TmpPointer_2 = TmpPointer_2 -> Next;
121     }
122 
123     if(TmpPointer_2==NULL)
124     {
125         return ;
126     }
127     else if(TmpPointer_1 == TmpPointer_2)
128     {
129         UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next = NULL;
130         free(TmpPointer_2);
131     }
132     else
133     {
134         TmpPointer_1 -> Next = TmpPointer_2 -> Next;
135         free(TmpPointer_2);
136     }
137 }
138 
139 struct _Graph *UGCreat(int ArcSum,int VertexSum)
140 {
141     int i,j;
142     struct _Graph *UnsignedGraph = malloc(sizeof(struct _Graph));
143     UnsignedGraph -> ArcNum = ArcSum;
144     UnsignedGraph -> VertexNum = VertexSum;
145 
146     for(i = 0; i < VertexSum; i ++)
147     {
148         scanf("%s %d",UnsignedGraph -> VertexHeadNodeList[i].VertexName,&UnsignedGraph -> VertexHeadNodeList[i].VertexWeight);
149     }
150 
151     for(i = 0; i < VertexSum; i ++)
152     {
153         UnsignedGraph -> VertexHeadNodeList[i].Next = NULL;
154     }
155 
156     for(i = 0; i < ArcSum; i ++)
157     {
158         char Arc_1[MaxVertexNodeNameSize];
159         char Arc_2[MaxVertexNodeNameSize];
160         int ArcIndex_1;
161         int ArcIndex_2;
162         int ArcWeight;
163 
164         scanf("%s %s %d",Arc_1,Arc_2,&ArcWeight);
165 
166         ArcIndex_1 = VertexName2Index(UnsignedGraph,Arc_1);
167         ArcIndex_2 = VertexName2Index(UnsignedGraph,Arc_2);
168 
169         AddOneArc(UnsignedGraph,ArcIndex_1,ArcIndex_2,ArcWeight);
170     }
171     return UnsignedGraph;
172 }
173 
174 void Travel(struct _Graph *UnsignedGraph)
175 {
176     char StartingPoint[MaxVertexNodeNameSize];
177     char OverPoint[MaxVertexNodeNameSize];
178 
179     printf("Input start and over
");
180     scanf("%s %s",StartingPoint,OverPoint);
181 
182     int StartIndex = VertexName2Index(UnsignedGraph,StartingPoint);
183     int OverIndex = VertexName2Index(UnsignedGraph,OverPoint);
184 
185     struct VertexBodyNode *TmpPointer;
186     TmpPointer = UnsignedGraph -> VertexHeadNodeList[StartIndex].Next;
187     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
188     {
189         if(OverIndex==TmpPointer -> VertexIndex)
190         {
191             printf("Distance:%d GetVertexPointSum:%d",TmpPointer->ArcWeight
192                    ,UnsignedGraph -> VertexHeadNodeList[StartIndex].VertexWeight+UnsignedGraph -> VertexHeadNodeList[OverIndex].VertexWeight);
193             break;
194         }
195         else
196         {
197             TmpPointer = TmpPointer -> Next;
198         }
199     }
200 }
201 
202 struct UnionFindSet
203 {
204     int *ID;
205     int *Auxiliary;
206     int GroupSum;
207     int WeightOriginalTotal;
208 };
209 
210 struct UnionFindSet* UnionFindSetInit(int WeightTotal)
211 {
212     struct UnionFindSet *UFSet = malloc(sizeof(struct UnionFindSet));
213 
214     UFSet -> GroupSum = WeightTotal;
215     UFSet -> WeightOriginalTotal = WeightTotal;
216 
217     UFSet -> ID = malloc(WeightTotal*sizeof(int));
218     UFSet -> Auxiliary = malloc(WeightTotal*sizeof(int));
219 
220     int i;
221     for(i = 0; i < WeightTotal; i ++)
222     {
223         UFSet -> ID[i] = i;
224     }
225     for(i = 0; i < WeightTotal; i ++)
226     {
227         UFSet -> Auxiliary[i] = 1;
228     }
229 
230     return UFSet;
231 }
232 
233 int UnionFindSetFind(struct UnionFindSet* UFSet,int WeightNum)
234 {
235     if(WeightNum>UFSet -> WeightOriginalTotal-1 || WeightNum<0)
236     {
237         return -1;
238     }
239 
240     while(WeightNum != UFSet -> ID[WeightNum])
241     {
242         WeightNum = UFSet -> ID[WeightNum];
243     }
244     return WeightNum;
245 }
246 
247 int UnionFindSetUnion(struct UnionFindSet* UFSet,int Weight_1,int Weight_2)
248 {
249     int WeightRoot_1 = UnionFindSetFind(UFSet,Weight_1);
250     int WeightRoot_2 = UnionFindSetFind(UFSet,Weight_2);
251 
252     if(WeightRoot_1 == -1 || WeightRoot_2 == -1)
253     {
254         return -1;
255     }
256     if(WeightRoot_1 == WeightRoot_2)
257     {
258         return 1;
259     }
260 
261     if(UFSet -> Auxiliary[WeightRoot_1] < UFSet -> Auxiliary[WeightRoot_2])
262     {
263         UFSet -> ID[WeightRoot_1] = WeightRoot_2;
264         UFSet -> Auxiliary[WeightRoot_2] += UFSet -> Auxiliary[WeightRoot_1];
265     }
266     else
267     {
268         UFSet -> ID[WeightRoot_2] = WeightRoot_1;
269         UFSet -> Auxiliary[WeightRoot_1] += UFSet -> Auxiliary[WeightRoot_2];
270     }
271 
272     UFSet -> GroupSum --;
273     return 0;
274 }
275 
276 bool UnionFindSetIsConnected(struct UnionFindSet* UFSet,int Weight_1,int Weight_2)
277 {
278     return (UnionFindSetFind(UFSet,Weight_1) == UnionFindSetFind(UFSet,Weight_2));
279 }
280 
281 struct KruskalElem
282 {
283     int VertexIndex_1;
284     int VertexIndex_2;
285     int ArcWeight;
286 };
287 
288 int CmpStruction(const void *a,const void *b)
289 {
290     struct KruskalElem *c = (struct KruskalElem *)a;
291     struct KruskalElem *d = (struct KruskalElem *)b;
292 
293     return  c->ArcWeight > d->ArcWeight ? 1 : 0;
294 }
295 
296 void KruskalMST(struct _Graph *UnsignedGraph)
297 {
298     struct UnionFindSet *UFSet = UnionFindSetInit(UnsignedGraph->VertexNum);
299     struct KruskalElem SortedArcList[2*UnsignedGraph->ArcNum];
300     int SortedArcListEnd = 0;
301     
302     int i;
303     for(i = 0; i < UnsignedGraph->VertexNum; i ++)
304     {
305         struct VertexBodyNode *TmpPointer;
306         TmpPointer = UnsignedGraph -> VertexHeadNodeList[i].Next;
307         while(TmpPointer != NULL)
308         {
309             SortedArcList[SortedArcListEnd].VertexIndex_1 = i;
310             SortedArcList[SortedArcListEnd].VertexIndex_2 = TmpPointer -> VertexIndex;
311             SortedArcList[SortedArcListEnd++].ArcWeight = TmpPointer -> ArcWeight;
312             TmpPointer = TmpPointer -> Next;
313         }
314     }
315     
316     qsort(SortedArcList,2*UnsignedGraph->ArcNum,sizeof(struct KruskalElem),CmpStruction);
317     for(i = 0;i < 2*UnsignedGraph->ArcNum;i ++)
318     {
319         if(!UnionFindSetIsConnected(UFSet,SortedArcList[i].VertexIndex_1,SortedArcList[i].VertexIndex_2))
320         {
321             printf("%s ¡ª¡ª%s Distance:%d
",UnsignedGraph->VertexHeadNodeList[SortedArcList[i].VertexIndex_1].VertexName
322                                           ,UnsignedGraph->VertexHeadNodeList[SortedArcList[i].VertexIndex_2].VertexName
323                                           ,SortedArcList[i].ArcWeight);
324             UnionFindSetUnion(UFSet,SortedArcList[i].VertexIndex_1,SortedArcList[i].VertexIndex_2);
325         }
326     }
327 }
328 
329 int main()
330 {
331     struct _Graph *G = UGCreat(8,5);
332     KruskalMST(G);
333 //    Travel(G);
334     return 0;
335 }
336 
337 /*
338         beijing 18
339         zhengzhou 10
340         hefei 9
341         nanjing 12
342         guangzhou 14
343         beijing zhengzhou 7
344         beijing hefei 9
345         beijing nanjing 8
346         zhengzhou hefei 5
347         hefei nanjing 3
348         zhengzhou guangzhou 7
349         hefei guangzhou 8
350         nanjing guangzhou 6
351 */
原文地址:https://www.cnblogs.com/Asurudo/p/9427493.html