图的最短路径之Floyd算法C/C++代码实现

柔情只为你懂 2023-02-19 15:23 10阅读 0赞

弗洛伊德Floyd算法:

也称插点法,该算法用来求解每一对顶点之间的最短路径

假设从顶点1到2,顶点3为过度中间顶点则:
如果某个顶点位于从起点到终点的最短路径上:
1->2=(1->3)+(3->2)
如果某个顶点不在从起点到终点的最短路径上:
1->2<(1->3)+(3->2)

总结:从i号顶点到j号顶点只经过前k号点的最短路径
以该图为例:
在这里插入图片描述

辅助数组的变化过程:
在这里插入图片描述

代码如下:

  1. #include<stdio.h>
  2. #define MaxInt 999 //定义无穷大
  3. #define MVNum 100
  4. typedef char VerTexType; //顶点类型
  5. typedef int ArcType; //边权值类型
  6. //邻接矩阵存储结构
  7. typedef struct
  8. {
  9. VerTexType vexs[MVNum]; //顶点表
  10. ArcType arcs[MVNum][MVNum]; //邻接矩阵
  11. int vexnum, arcnum; //图的当前点数和边数
  12. }AMGraph;
  13. void printGraph(AMGraph G);
  14. int LocateVex(AMGraph G, char v);
  15. //创建有向网
  16. void CreateUDN(AMGraph &G)
  17. {
  18. G.vexnum = 4; //输入总顶点数和边数
  19. G.arcnum = 8;
  20. G.vexs[0] = 'v0'; //输入顶点信息
  21. G.vexs[1] = 'v1';
  22. G.vexs[2] = 'v2';
  23. G.vexs[3] = 'v3';
  24. for (int i = 0; i < G.vexnum; i++) //初始化邻接矩阵为极大值
  25. {
  26. for (int j = 0; j < G.vexnum; j++)
  27. {
  28. G.arcs[i][j] = MaxInt;
  29. }
  30. }
  31. //输入权值
  32. int i, j;
  33. i = LocateVex(G, 'v0');
  34. j = LocateVex(G, 'v1');
  35. G.arcs[i][j] = 1;
  36. i = LocateVex(G, 'v0');
  37. j = LocateVex(G, 'v3');
  38. G.arcs[i][j] = 4;
  39. i = LocateVex(G, 'v1');
  40. j = LocateVex(G, 'v3');
  41. G.arcs[i][j] = 2;
  42. i = LocateVex(G, 'v1');
  43. j = LocateVex(G, 'v2');
  44. G.arcs[i][j] = 9;
  45. i = LocateVex(G, 'v2');
  46. j = LocateVex(G, 'v0');
  47. G.arcs[i][j] = 3;
  48. i = LocateVex(G, 'v2');
  49. j = LocateVex(G, 'v1');
  50. G.arcs[i][j] = 5;
  51. i = LocateVex(G, 'v2');
  52. j = LocateVex(G, 'v3');
  53. G.arcs[i][j] = 8;
  54. i = LocateVex(G, 'v3');
  55. j = LocateVex(G, 'v2');
  56. G.arcs[i][j] = 6;
  57. //自己到自己初始化为0
  58. i = LocateVex(G, 'v0');
  59. j = LocateVex(G, 'v0');
  60. G.arcs[i][j] = 0;
  61. i = LocateVex(G, 'v1');
  62. j = LocateVex(G, 'v1');
  63. G.arcs[i][j] = 0;
  64. i = LocateVex(G, 'v2');
  65. j = LocateVex(G, 'v2');
  66. G.arcs[i][j] = 0;
  67. i = LocateVex(G, 'v3');
  68. j = LocateVex(G, 'v3');
  69. G.arcs[i][j] = 0;
  70. printGraph(G);
  71. }
  72. //返回顶点在数组中的下标
  73. int LocateVex(AMGraph G, char v)
  74. {
  75. for (int i = 0; i < G.vexnum; i++)
  76. {
  77. if (G.vexs[i] == v)
  78. {
  79. return i;
  80. }
  81. }
  82. }
  83. //打印输出邻接矩阵
  84. void printGraph(AMGraph G)
  85. {
  86. for (int i = 0; i < G.vexnum; i++)
  87. {
  88. printf("v%d :", i + 1);
  89. for (int j = 0; j < G.vexnum; j++)
  90. {
  91. printf("%5d ", G.arcs[i][j]);
  92. }
  93. printf("\n");
  94. }
  95. }
  96. //邻接矩阵深度优先遍历
  97. bool visited[MVNum];
  98. void DFS_AM(AMGraph G, int v)
  99. {
  100. printf("v%c->", G.vexs[v]);
  101. visited[v] = true;
  102. for (int w = 0; w < G.vexnum; w++)
  103. {
  104. if ((G.arcs[v][w]) != 0 && (!visited[w]))
  105. {
  106. DFS_AM(G, w);
  107. }
  108. }
  109. }
  110. //最短路径弗洛伊德算法
  111. int D[MVNum][MVNum]; //存放v0到vi的最短路径长度值
  112. int Path[MVNum][MVNum]; //存放vi的直接前驱顶点序号
  113. void ShortestPath_Floyd(AMGraph G)
  114. {
  115. //初始化
  116. for (int i = 0; i<G.vexnum; i++)
  117. {
  118. for (int j = 0; j<G.vexnum; j++)
  119. {
  120. D[i][j] = G.arcs[i][j];
  121. if (D[i][j] < MaxInt) //i和j之间有弧
  122. {
  123. Path[i][j] = i;
  124. }
  125. else
  126. {
  127. Path[i][j] =-1;
  128. }
  129. }
  130. }
  131. //算法开始
  132. for (int k = 0; k < G.vexnum; k++) //过度顶点
  133. {
  134. for (int i = 0; i < G.vexnum; i++) //起点
  135. {
  136. for (int j = 0; j < G.vexnum; j++) //终点
  137. {
  138. if (D[i][k] + D[k][j] < D[i][j]) //如小于更新D[i][j]
  139. {
  140. D[i][j] = D[i][k] + D[k][j];
  141. Path[i][j] = Path[k][j];
  142. }
  143. }
  144. }
  145. }
  146. }
  147. //打印输出辅助数组D[i][j]和Path[i][j]
  148. void printArray(AMGraph G)
  149. {
  150. printf("\nD数组:\n");
  151. for (int i = 0; i < G.vexnum; i++)
  152. {
  153. printf("%d:", i);
  154. for (int j = 0; j < G.vexnum; j++)
  155. {
  156. printf("%5d", D[i][j]);
  157. }
  158. printf("\n");
  159. }
  160. printf("\nPath数组:\n");
  161. for (int i = 0; i < G.vexnum; i++)
  162. {
  163. printf("%d:", i);
  164. for (int j = 0; j < G.vexnum; j++)
  165. {
  166. printf("%5d", Path[i][j]);
  167. }
  168. printf("\n");
  169. }
  170. }
  171. int main()
  172. {
  173. AMGraph G;
  174. CreateUDN(G);
  175. int v = 0;
  176. printf("深度优先遍历::");
  177. DFS_AM(G, v);
  178. int v0 = 0;
  179. printf("\n====================================\n");
  180. ShortestPath_Floyd(G);
  181. printArray(G); //输出辅助数组D和Path
  182. }

运行结果:

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,10人围观)

还没有评论,来说两句吧...

相关阅读

    相关 路径Floyd算法

    Floyd算法: 1,从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。 2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w