图算法:普里姆算法、迪杰斯特拉算法、弗洛伊德算法

prim1.h

  1 #ifndef PRIM_H
  2 #define PRIM_H
  3 
  4 //* 普里姆算法,求最小生成树 
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 #include <malloc.h>
  8 
  9 #define MAX_VERTEX_NUM 5
 10 #define INFINITY 1000//这里不能用INT_MAX,因为如果是整型正数的最大值,加一后反而变成最小值,这点要注意
 11 
 12 typedef int VRType;
 13 typedef int VertexType;
 14 typedef char InfoType;
 15 typedef enum{DG,DN,UDG,UDN}GraphKind;//图种类,分别表示有向图,有向网,无向图,无向网
 16 typedef enum{ERROR,OK}Status;
 17 typedef bool PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
 18 typedef bool PathMatrix2[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];
 19 typedef int ShortPathTable[MAX_VERTEX_NUM];
 20 typedef int ShortPathTable2[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
 21 
 22 typedef struct ArcCell//边信息
 23 {
 24     VRType adj;//边的权值
 25     InfoType *info;//边的其它信息,本示例中假设info均为空
 26 }ArcCell,ArcMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
 27 
 28 typedef struct  
 29 {
 30     VertexType vexs[MAX_VERTEX_NUM];
 31     ArcMatrix arc;
 32     int vexNum,arcNum;
 33     GraphKind kind;
 34 }MGraph;//使用数组形式表示图
 35 
 36 typedef struct  
 37 {
 38     VertexType adjvex;
 39     VRType lowcost;
 40 }closing[MAX_VERTEX_NUM];
 41 
 42 int Locate(MGraph g,VertexType v)
 43 {
 44     for(int i = 0;i < g.vexNum;i++)
 45     {
 46         if(g.vexs[i] == v)
 47         {
 48             return i;
 49         }
 50     }
 51     return -1;
 52 }
 53 
 54 Status CreateDG(MGraph &g)//构造有向图
 55 {
 56     VertexType v1,v2;
 57     VRType arcValue;
 58 
 59     printf("cerate the DG:\n");
 60     printf("please input the vexNum and arcNum:\n");
 61     scanf("%d %d",&g.vexNum,&g.arcNum);
 62 
 63     printf("\nplease input the value of the vertex:\n");
 64     for(int i = 0;i < g.vexNum;i++)
 65     {
 66         scanf("%d",&g.vexs[i]);
 67     }
 68 
 69     for(int i = 0;i < g.vexNum;i++)
 70     {
 71         for(int j = 0;j < g.vexNum;j++)
 72         {
 73             g.arc[i][j].adj = INFINITY;
 74             g.arc[i][j].info = NULL;
 75         }
 76     }
 77 
 78     printf("\nplease input the arc of the graph:\n");
 79     for(int i = 0;i < g.arcNum;i++)
 80     {
 81         scanf("%d %d %d",&v1,&v2,&arcValue);
 82         int l1 = Locate(g,v1);
 83         int l2 = Locate(g,v2);
 84         g.arc[l1][l2].adj = arcValue;
 85     }
 86 
 87     return OK;
 88 }
 89 
 90 Status CreateDN(MGraph &g)//构造有向网
 91 {
 92     VertexType v1,v2;
 93     VRType arcValue;
 94 
 95     printf("cerate the DN:\n");
 96     printf("please input the vexNum and arcNum:\n");
 97     scanf("%d %d",&g.vexNum,&g.arcNum);
 98 
 99     printf("\nplease input the value of the vertex:\n");
100     for(int i = 0;i < g.vexNum;i++)
101     {
102         scanf("%d",&g.vexs[i]);
103     }
104 
105     for(int i = 0;i < g.vexNum;i++)
106     {
107         for(int j = 0;j < g.vexNum;j++)
108         {
109             g.arc[i][j].adj = INFINITY;
110             g.arc[i][j].info = NULL;
111         }
112     }
113 
114     printf("\nplease input the arc of the graph:\n");
115     for(int i = 0;i < g.arcNum;i++)
116     {
117         scanf("%d %d %d",&v1,&v2,&arcValue);
118         int l1 = Locate(g,v1);
119         int l2 = Locate(g,v2);
120         g.arc[l1][l2].adj = arcValue;
121     }
122 
123     return OK;
124 }
125 
126 Status CreateUDG(MGraph &g)//构造无向图
127 {
128     VertexType v1,v2;
129     VRType arcValue;
130 
131     printf("cerate the UDG:\n");
132     printf("please input the vexNum and arcNum:\n");
133     scanf("%d %d",&g.vexNum,&g.arcNum);
134 
135     printf("\nplease input the value of the vertex:\n");
136     for(int i = 0;i < g.vexNum;i++)
137     {
138         scanf("%d",&g.vexs[i]);
139     }
140 
141     for(int i = 0;i < g.vexNum;i++)
142     {
143         for(int j = 0;j < g.vexNum;j++)
144         {
145             g.arc[i][j].adj = INFINITY;
146             g.arc[i][j].info = NULL;
147         }
148     }
149 
150     printf("\nplease input the arc of the graph:\n");
151     for(int i = 0;i < g.arcNum;i++)
152     {
153         scanf("%d %d %d",&v1,&v2,&arcValue);
154         int l1 = Locate(g,v1);
155         int l2 = Locate(g,v2);
156         g.arc[l1][l2].adj = arcValue;
157         g.arc[l2][l1].adj = arcValue;
158     }
159 
160     return OK;
161 }
162 
163 Status CreateUDN(MGraph &g)//构造无向网
164 {
165     VertexType v1,v2;
166     VRType arcValue;
167 
168     printf("cerate the UDN:\n");
169     printf("please input the vexNum and arcNum:\n");
170     scanf("%d %d",&g.vexNum,&g.arcNum);
171 
172     printf("\nplease input the value of the vertex:\n");
173     for(int i = 0;i < g.vexNum;i++)
174     {
175         scanf("%d",&g.vexs[i]);
176     }
177 
178     for(int i = 0;i < g.vexNum;i++)
179     {
180         for(int j = 0;j < g.vexNum;j++)
181         {
182             g.arc[i][j].adj = INFINITY;
183             g.arc[i][j].info = NULL;
184         }
185     }
186 
187     printf("\nplease input the arc of the graph:\n");
188     for(int i = 0;i < g.arcNum;i++)
189     {
190         scanf("%d %d %d",&v1,&v2,&arcValue);
191         int l1 = Locate(g,v1);
192         int l2 = Locate(g,v2);
193         g.arc[l1][l2].adj = arcValue;
194         g.arc[l2][l1].adj = arcValue;
195     }
196 
197     return OK;
198 }
199 
200 Status CreateMGraph(MGraph &g)
201 {
202     printf("please input the kind of the graph :\n");
203     scanf("%d",&g.kind);
204     switch(g.kind)
205     {
206     case DG:
207         return CreateDG(g);
208     case DN:
209         return CreateDN(g);
210     case UDG:
211         return CreateUDG(g);
212     case UDN:
213         return CreateUDN(g);
214     default:
215         return OK;
216     }
217 }
218 
219 void PrintMGraph(MGraph g)
220 {
221     printf("the vertex of the graph is :\n");
222     for(int i = 0;i < g.vexNum;i++)
223     {
224         printf("%d ",g.vexs[i]);
225     }
226     printf("\n");
227 
228     printf("the arc of the graph is :\n");
229     for(int i = 0;i < g.vexNum;i++)
230     {
231         for(int j = 0;j < g.vexNum;j++)
232         {
233             printf("%d ",g.arc[i][j].adj);
234         }
235         printf("\n");
236     }
237     printf("\n");
238 }
239 
240 int MinCostLocate(int num,closing clos)//这里传递图的节点数比传递图本身效率要高,所以主要参数的类型选择
241 {
242     int i;
243     for(i = 0;i < num;i++)//寻找第一个lowcost不为0的下标
244     {
245         if(clos[i].lowcost != 0)
246         {
247             break;
248         }
249     }
250     if(i == num)
251     {
252         return -1;
253     }
254     VRType vr = clos[i].lowcost;
255     int min = i;
256     for(i = i+1;i < num;i++)
257     {
258         if(vr > clos[i].lowcost && clos[i].lowcost > 0)
259         {
260             vr = clos[i].lowcost;
261             min = i;
262         }
263     }
264     return min;
265 }
266 
267 void MiniSpanTreePrim(MGraph g)//普里姆算法
268 {
269     VertexType v;
270     printf("please input the start vertex:\n");
271     scanf("%d",&v);//输入起始点值
272 
273     closing clos;
274     int k = Locate(g,v);//将起始点值转换为数组坐标
275 
276     for(int i = 0;i < g.vexNum;i++)
277     {
278         if(i != k)
279         {
280             clos[i].adjvex = v;
281             clos[i].lowcost = g.arc[k][i].adj;
282         }
283     }
284     clos[k].lowcost = 0;
285 
286     for(int j = 1;j < g.vexNum;j++)//总的次数,n个点有n-1条边,所以只需要循环n-1次
287     {
288         k = MinCostLocate(g.vexNum,clos);
289         if(k != -1)
290         {
291 
292             printf("%d %d\n",clos[k].adjvex,g.vexs[k]);
293             clos[k].lowcost = 0;
294             for(int i = 0;i < g.vexNum;i++)
295             {
296                 if(g.arc[k][i].adj < clos[i].lowcost)
297                 {
298                     clos[i].lowcost = g.arc[k][i].adj;
299                     clos[i].adjvex = g.vexs[k];
300                 }
301             }
302         }
303     }
304 }
305 
306 void ShortestPathDIJ(MGraph g,VertexType vp,PathMatrix &p,ShortPathTable &d)//迪杰斯特拉算法求给定点到其他点的最短路径
307 {
308     int v0 = Locate(g,vp);
309     int v;
310     bool *fault = (bool *)malloc(sizeof(bool)*g.vexNum);
311 
312     for(v = 0;v < g.vexNum;v++)
313     {
314         d[v] = g.arc[v0][v].adj;
315         fault[v] = false;
316         for(int w = 0;w < g.vexNum;w++)
317         {
318             p[v][w] = false;
319         }
320         if(d[v] < INFINITY)
321         {
322             p[v][v0] = true;
323             p[v][v] = true;
324         }
325     }
326 
327     d[v0] = 0;
328     fault[v0] = true;
329 
330     for(int count = 1;count < g.vexNum;count++)
331     {
332         int min = INFINITY;//min用于每次循环后更新到各点最短距离
333         for(int w = 0;w < g.vexNum;w++)
334         {
335             if(!fault[w])
336             {
337                 if(d[w] < min)
338                 {
339                     min = d[w];
340                     v = w;
341                 }
342             }
343         }
344     
345         fault[v] = true;
346 
347         for(int w = 0;w < g.vexNum;w++)
348         {
349             if(!fault[w])
350             {
351                 if((min+g.arc[v][w].adj) < d[w])
352                 {
353                     d[w] = min+g.arc[v][w].adj;
354                     for(int i = 0;i < g.vexNum;i++)
355                     {
356                         p[w][i] = p[v][i];
357                     }
358                     p[w][w] = true;
359                 }
360             }
361         }
362     }
363 }
364 
365 void ShortestPathFLOYD(MGraph g,PathMatrix2 &p,ShortPathTable2 &d)//弗洛伊德算法求任意2点间的最短路径
366 {
367     for(int i = 0;i < g.vexNum;i++)
368     {
369         for(int j = 0;j < g.vexNum;j++)
370         {
371             d[i][j] = g.arc[i][j].adj;
372             d[i][i] = 0;//自己到自己的距离是0
373             for(int v = 0;v < g.vexNum;v++)
374             {
375                 p[i][j][v] = false;
376             }
377             if(d[i][j] < INFINITY)
378             {
379                 p[i][j][i] = true;
380                 p[i][j][j] = true;
381             }
382         }
383     }
384 
385     for(int i = 0;i < g.vexNum;i++)
386     {
387         for(int j = 0;j < g.vexNum;j++)
388         {
389             for(int k = 0;k < g.vexNum;k++)
390             {
391                 if(d[j][k] > (d[j][i]+d[i][k]))
392                 {
393                     d[j][k] = d[j][i]+d[i][k];
394                     for(int v = 0;v < g.vexNum;v++)
395                     {
396                         p[j][k][v] = p[j][i][v]||p[i][k][v];
397                     }
398                 }
399             }
400         }
401     }
402 }
403 
404 #endif

main.cpp

 1 #include "prim1.h"
 2 
 3 int main()
 4 {
 5     MGraph g;
 6     CreateMGraph(g);//构造图
 7     PrintMGraph(g);//打印图
 8     MiniSpanTreePrim(g);//用普里姆算法求最小生成树
 9 
10     printf("please input the start point of the tree:\n");
11 
12     VertexType vp;
13     scanf("%d",&vp);
14     PathMatrix p;
15     ShortPathTable d;
16     ShortestPathDIJ(g,vp,p,d);//用迪杰斯特拉算法求最短路径问题
17 
18     printf("DJI :\nthe shortest path form %d to other points is :\n",vp);
19     for(int i = 0;i < g.vexNum;i++)
20     {
21         if(vp != g.vexs[i])
22         {
23             printf("%d to %d : ",vp,g.vexs[i]);
24             for(int t = 0;t < g.vexNum;t++)
25             {
26                 if(p[i][t])
27                 {
28                     printf("%d ",g.vexs[t]);
29                 }
30             }
31             printf("\nthe total length of the path is : %d\n\n",d[i]);
32         }
33     }
34 
35     PathMatrix2 p2;
36     ShortPathTable2 d2;
37     ShortestPathFLOYD(g,p2,d2);
38 
39     printf("FLOYD:\n");
40     for(int w = 0;w < g.vexNum;w++)
41     {
42         printf("the shortest path form %d to other points is :\n",g.vexs[w]);
43 
44         for(int i = 0;i < g.vexNum;i++)
45         {
46             printf("%d to %d :\n",g.vexs[w],g.vexs[i]);
47             for(int j = 0;j < g.vexNum;j++)
48             {
49                 if(p2[w][i][j])
50                 {
51                     printf("%d ",g.vexs[j]);
52                 }
53             }
54             printf("the total length of this path is : %d \n\n",d2[w][i]);
55         }
56     }
57 
58     system("pause");
59     return 0;
60 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值