最小生成树(Prim实现)

本文介绍了一种使用C语言实现的图数据结构,并详细展示了如何通过Prim算法求解无向图的最小生成树问题。该算法首先构建图的基本框架,接着实现了顶点与边的增删操作,并最终通过Prim算法找出所有顶点相连且权重最小的树形子图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <stdbool.h>
  5 
  6 #define INFINITY 0x3f3f3f3f
  7 #define MaxVertexNodeNumSize 1000
  8 #define MaxVertexNodeNameSize 100
  9 
 10 struct VertexBodyNode
 11 {
 12     char VertexName[MaxVertexNodeNameSize];
 13     int ArcWeight;
 14     int VertexIndex;
 15     struct VertexBodyNode *Next;
 16 };
 17 
 18 struct VertexHeadNode
 19 {
 20     char VertexName[MaxVertexNodeNameSize];
 21     int VertexWeight;
 22     struct VertexBodyNode *Next;
 23 };
 24 
 25 struct _Graph
 26 {
 27     struct VertexHeadNode VertexHeadNodeList[MaxVertexNodeNumSize];
 28     int ArcNum,VertexNum;
 29 };
 30 
 31 int VertexName2Index(struct _Graph *UnsignedGraph,char *VName)
 32 {
 33     int i;
 34     for(i = 0; i < UnsignedGraph -> VertexNum; i ++)
 35     {
 36         if(strcmp(UnsignedGraph -> VertexHeadNodeList[i].VertexName,VName)==0)
 37         {
 38             return i;
 39         }
 40     }
 41     return -1;
 42 }
 43 
 44 void AddOneArc(struct _Graph *UnsignedGraph,int ArcIndex_1,int ArcIndex_2,int AWeight)
 45 {
 46     struct VertexBodyNode *BNode_1 = malloc(sizeof(struct VertexBodyNode));
 47     struct VertexBodyNode *BNode_2 = malloc(sizeof(struct VertexBodyNode));
 48 
 49     strcpy(BNode_1 -> VertexName,UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].VertexName);
 50     strcpy(BNode_2 -> VertexName,UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].VertexName);
 51     BNode_1 -> ArcWeight = AWeight;
 52     BNode_2 -> ArcWeight = AWeight;
 53     BNode_1 -> VertexIndex = ArcIndex_1;
 54     BNode_2 -> VertexIndex = ArcIndex_2;
 55     BNode_1 -> Next = BNode_2 -> Next = NULL;
 56 
 57     struct VertexBodyNode *TmpPointer;
 58     TmpPointer = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
 59     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
 60     {
 61         TmpPointer = TmpPointer -> Next;
 62     }
 63     if(TmpPointer==NULL)
 64     {
 65         UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next = BNode_2;
 66     }
 67     else
 68     {
 69         TmpPointer -> Next = BNode_2;
 70     }
 71 
 72     TmpPointer = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
 73     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
 74     {
 75         TmpPointer = TmpPointer -> Next;
 76     }
 77     if(TmpPointer==NULL)
 78     {
 79         UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next = BNode_1;
 80     }
 81     else
 82     {
 83         TmpPointer -> Next = BNode_1;
 84     }
 85 }
 86 
 87 void DeleteOneArc(struct _Graph *UnsignedGraph,int ArcIndex_1,int ArcIndex_2)
 88 {
 89     struct VertexBodyNode *TmpPointer_1,*TmpPointer_2;
 90 
 91     TmpPointer_1 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
 92     TmpPointer_2 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
 93 
 94     while(TmpPointer_2!=NULL && TmpPointer_2->VertexIndex!=ArcIndex_2)
 95     {
 96         TmpPointer_1 = TmpPointer_2;
 97         TmpPointer_2 = TmpPointer_2 -> Next;
 98     }
 99 
100     if(TmpPointer_2==NULL)
101     {
102         return ;
103     }
104     else if(TmpPointer_1 == TmpPointer_2)
105     {
106         UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next = NULL;
107         free(TmpPointer_2);
108     }
109     else
110     {
111         TmpPointer_1 -> Next = TmpPointer_2 -> Next;
112         free(TmpPointer_2);
113     }
114 
115     TmpPointer_1 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
116     TmpPointer_2 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
117 
118     while(TmpPointer_2!=NULL && TmpPointer_2->VertexIndex!=ArcIndex_1)
119     {
120         TmpPointer_1 = TmpPointer_2;
121         TmpPointer_2 = TmpPointer_2 -> Next;
122     }
123 
124     if(TmpPointer_2==NULL)
125     {
126         return ;
127     }
128     else if(TmpPointer_1 == TmpPointer_2)
129     {
130         UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next = NULL;
131         free(TmpPointer_2);
132     }
133     else
134     {
135         TmpPointer_1 -> Next = TmpPointer_2 -> Next;
136         free(TmpPointer_2);
137     }
138 }
139 
140 struct _Graph *UGCreat(int ArcSum,int VertexSum)
141 {
142     int i,j;
143     struct _Graph *UnsignedGraph = malloc(sizeof(struct _Graph));
144     UnsignedGraph -> ArcNum = ArcSum;
145     UnsignedGraph -> VertexNum = VertexSum;
146 
147     for(i = 0; i < VertexSum; i ++)
148     {
149         scanf("%s %d",UnsignedGraph -> VertexHeadNodeList[i].VertexName,&UnsignedGraph -> VertexHeadNodeList[i].VertexWeight);
150     }
151 
152     for(i = 0; i < VertexSum; i ++)
153     {
154         UnsignedGraph -> VertexHeadNodeList[i].Next = NULL;
155     }
156 
157     for(i = 0; i < ArcSum; i ++)
158     {
159         char Arc_1[MaxVertexNodeNameSize];
160         char Arc_2[MaxVertexNodeNameSize];
161         int ArcIndex_1;
162         int ArcIndex_2;
163         int ArcWeight;
164 
165         scanf("%s %s %d",Arc_1,Arc_2,&ArcWeight);
166 
167         ArcIndex_1 = VertexName2Index(UnsignedGraph,Arc_1);
168         ArcIndex_2 = VertexName2Index(UnsignedGraph,Arc_2);
169 
170         AddOneArc(UnsignedGraph,ArcIndex_1,ArcIndex_2,ArcWeight);
171     }
172     return UnsignedGraph;
173 }
174 
175 void Travel(struct _Graph *UnsignedGraph)
176 {
177     char StartingPoint[MaxVertexNodeNameSize];
178     char OverPoint[MaxVertexNodeNameSize];
179 
180     printf("Input start and over\n");
181     scanf("%s %s",StartingPoint,OverPoint);
182 
183     int StartIndex = VertexName2Index(UnsignedGraph,StartingPoint);
184     int OverIndex = VertexName2Index(UnsignedGraph,OverPoint);
185 
186     struct VertexBodyNode *TmpPointer;
187     TmpPointer = UnsignedGraph -> VertexHeadNodeList[StartIndex].Next;
188     while(TmpPointer != NULL && TmpPointer -> Next != NULL)
189     {
190         if(OverIndex==TmpPointer -> VertexIndex)
191         {
192             printf("Distance:%d GetVertexPointSum:%d",TmpPointer->ArcWeight
193                    ,UnsignedGraph -> VertexHeadNodeList[StartIndex].VertexWeight+UnsignedGraph -> VertexHeadNodeList[OverIndex].VertexWeight);
194             break;
195         }
196         else
197         {
198             TmpPointer = TmpPointer -> Next;
199         }
200     }
201 }
202 
203 void PrimMST(struct _Graph *UnsignedGraph)
204 {
205     int i;
206     int ResultTail[UnsignedGraph->VertexNum];
207     int ResultWeight[UnsignedGraph->VertexNum];
208     int Visit[UnsignedGraph->VertexNum];
209     int OtherWeight[UnsignedGraph->VertexNum];
210     int ResultTailEnd;
211     int ResultWeightEnd;
212     memset(OtherWeight,0x3f,sizeof(OtherWeight));
213     memset(Visit,0,sizeof(Visit));
214 
215     struct VertexBodyNode *TmpPointer;
216     TmpPointer = UnsignedGraph -> VertexHeadNodeList[0].Next;
217     ResultTail[ResultTailEnd++] = 0;
218     while(TmpPointer != NULL)
219     {
220         OtherWeight[TmpPointer->VertexIndex] = TmpPointer -> ArcWeight;
221         TmpPointer = TmpPointer -> Next;
222     }
223 
224     for(i = 1; i < UnsignedGraph->VertexNum; i ++)
225     {
226         int TmpIndex = 0;
227         int WeightMin;
228         int WeightMinIndex = 0;
229         WeightMin = INFINITY;
230 
231         while(TmpIndex < UnsignedGraph->VertexNum)
232         {
233             if(Visit[TmpIndex]==0 && OtherWeight[TmpIndex]<WeightMin)
234             {
235                 WeightMin = OtherWeight[TmpIndex];
236                 WeightMinIndex = TmpIndex;
237             }
238             TmpIndex ++;
239         }
240 
241         ResultTail[ResultTailEnd++] = WeightMinIndex;
242         ResultWeight[ResultWeightEnd++] = WeightMin;
243         Visit[WeightMinIndex] = 1;
244 
245         //update
246         TmpPointer = UnsignedGraph -> VertexHeadNodeList[WeightMinIndex].Next;
247         while(TmpPointer != NULL)
248         {
249             if(Visit[TmpPointer->VertexIndex]==0 && TmpPointer->ArcWeight<OtherWeight[TmpPointer->VertexIndex])
250             {
251                 OtherWeight[TmpPointer->VertexIndex] = TmpPointer->ArcWeight;
252             }
253             TmpPointer = TmpPointer -> Next;
254         }
255     }
256     
257     for(i = 0;i < ResultTailEnd-1;i ++)
258     {
259         TmpPointer = UnsignedGraph -> VertexHeadNodeList[ResultTail[i+1]].Next;
260         while(TmpPointer != NULL)
261         {
262             if(TmpPointer->ArcWeight==ResultWeight[i])
263             {
264                 printf("%s ¡ª¡ª%s Distance:%d\n",UnsignedGraph->VertexHeadNodeList[ResultTail[i+1]].VertexName
265                                                 ,UnsignedGraph->VertexHeadNodeList[TmpPointer->VertexIndex].VertexName
266                                                 ,ResultWeight[i]);
267                 break;
268             }
269             TmpPointer = TmpPointer -> Next;
270         }
271     }
272 }
273 
274 int main()
275 {
276     struct _Graph *G = UGCreat(8,5);
277     PrimMST(G);
278 //    Travel(G);
279     return 0;
280 }
281 
282 /*
283         beijing 18
284         zhengzhou 10
285         hefei 9
286         nanjing 12
287         guangzhou 14
288         beijing zhengzhou 7
289         beijing hefei 9
290         beijing nanjing 8
291         zhengzhou hefei 5
292         hefei nanjing 3
293         zhengzhou guangzhou 7
294         hefei guangzhou 8
295         nanjing guangzhou 6
296 */

 

转载于:https://www.cnblogs.com/Asurudo/p/9427497.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值