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 }