Floyd 算法实现

x33g5p2x  于2022-07-10 转载在 其他  
字(2.8k)|赞(0)|评价(0)|浏览(271)

一 问题描述

求节点0到节点2的最短路径。

二 代码

  1. package graph.floyd;
  2. import java.util.Scanner;
  3. public class Floyd {
  4. static final int MaxVnum = 100; // 顶点数最大值
  5. static final int INF = 0x3f3f3f3f; //无穷大
  6. static final int dist[][] = new int[MaxVnum][MaxVnum]; // 最短距离
  7. static final int p[][] = new int[MaxVnum][MaxVnum]; // 前驱数组
  8. static final boolean flag[] = new boolean[MaxVnum]; // 如果 s[i] 等于 true,说明顶点 i 已经加入到集合 S ;否则顶点 i 属于集合 V-S
  9. static int locatevex(AMGraph G, char x) {
  10. for (int i = 0; i < G.vexnum; i++) // 查找顶点信息的下标
  11. if (x == G.Vex[i])
  12. return i;
  13. return -1; // 没找到
  14. }
  15. static void CreateAMGraph(AMGraph G) {
  16. Scanner scanner = new Scanner(System.in);
  17. int i, j;
  18. char u, v;
  19. int w;
  20. System.out.println("请输入顶点数:");
  21. G.vexnum = scanner.nextInt();
  22. System.out.println("请输入边数:");
  23. G.edgenum = scanner.nextInt();
  24. System.out.println("请输入顶点信息:");
  25. // 输入顶点信息,存入顶点信息数组
  26. for (int k = 0; k < G.vexnum; k++) {
  27. G.Vex[k] = scanner.next().charAt(0);
  28. }
  29. //初始化邻接矩阵所有值为0,如果是网,则初始化邻接矩阵为无穷大
  30. for (int m = 0; m < G.vexnum; m++)
  31. for (int n = 0; n < G.vexnum; n++)
  32. if (m != n)
  33. G.Edge[m][n] = INF;
  34. else
  35. G.Edge[m][n] = 0; // 注意m==n时,设置为 0
  36. System.out.println("请输入每条边依附的两个顶点及权值:");
  37. while (G.edgenum-- > 0) {
  38. u = scanner.next().charAt(0);
  39. v = scanner.next().charAt(0);
  40. w = scanner.nextInt();
  41. i = locatevex(G, u);// 查找顶点 u 的存储下标
  42. j = locatevex(G, v);// 查找顶点 v 的存储下标
  43. if (i != -1 && j != -1)
  44. G.Edge[i][j] = w; //有向图邻接矩阵
  45. else {
  46. System.out.println("输入顶点信息错!请重新输入!");
  47. G.edgenum++; // 本次输入不算
  48. }
  49. }
  50. }
  51. static void Floyd(AMGraph G) { // 用 Floyd 算法求有向网 G 中各对顶点 i 和 j 之间的最短路径
  52. int i, j, k;
  53. for (i = 0; i < G.vexnum; i++) // 各对结点之间初始已知路径及距离
  54. for (j = 0; j < G.vexnum; j++) {
  55. dist[i][j] = G.Edge[i][j];
  56. if (dist[i][j] < INF && i != j)
  57. p[i][j] = i; // 如果 i 和 j 之间有弧,则将 j 的前驱置为 i
  58. else p[i][j] = -1; // 如果 i 和 j 之间无弧,则将 j 的前驱置为 -1
  59. }
  60. for (k = 0; k < G.vexnum; k++)
  61. for (i = 0; i < G.vexnum; i++)
  62. for (j = 0; j < G.vexnum; j++)
  63. if (dist[i][k] + dist[k][j] < dist[i][j]) { // 从 i 经 k 到 j 的一条路径更短
  64. dist[i][j] = dist[i][k] + dist[k][j]; // 更新dist[i][j]
  65. p[i][j] = p[k][j]; // 更改 j 的前驱
  66. }
  67. }
  68. static void print(AMGraph G) { // 输出邻接矩阵
  69. int i, j;
  70. for (i = 0; i < G.vexnum; i++) {//输出最短距离数组
  71. for (j = 0; j < G.vexnum; j++)
  72. System.out.print(dist[i][j] + "\t");
  73. System.out.println();
  74. }
  75. System.out.println();
  76. for (i = 0; i < G.vexnum; i++) {//输出前驱数组
  77. for (j = 0; j < G.vexnum; j++)
  78. System.out.print(p[i][j] + "\t");
  79. System.out.println();
  80. }
  81. }
  82. static void DisplayPath(AMGraph G, int s, int t) { // 显示最短路径
  83. if (p[s][t] != -1) {
  84. DisplayPath(G, s, p[s][t]);
  85. System.out.print(G.Vex[p[s][t]] + "-->");
  86. }
  87. }
  88. public static void main(String[] args) {
  89. char start, destination;
  90. int u, v;
  91. AMGraph G = new AMGraph();
  92. CreateAMGraph(G);
  93. Floyd(G);
  94. print(G);
  95. System.out.print("请依次输入路径的起点与终点的名称:");
  96. Scanner scanner = new Scanner(System.in);
  97. start = scanner.next().charAt(0);
  98. destination = scanner.next().charAt(0);
  99. u = locatevex(G, start);
  100. v = locatevex(G, destination);
  101. DisplayPath(G, u, v);
  102. System.out.println(G.Vex[v]);
  103. System.out.println("最短路径的长度为:" + dist[u][v]);
  104. System.out.println();
  105. }
  106. }
  107. class AMGraph {
  108. char Vex[] = new char[Floyd.MaxVnum];
  109. int Edge[][] = new int[Floyd.MaxVnum][Floyd.MaxVnum];
  110. int vexnum; // 顶点数
  111. int edgenum; // 边数
  112. }

三 实现

白色为输出,绿色为输入。

相关文章