求解最短路径的迪杰斯特拉算法基本思想:

(1) 设置辅助数组Dist,其中每个分量Dist[k] 表示当前所求得的从源点到其余各顶点 k的最短路径。

(2) 一般情况下,Dist[k] = Min{<源点到顶点 k 的弧上的权值>,<源点到其它顶点的最短路径长度> + <其它顶点到顶点 k 的弧上的权值>};

(3) 首先清除所有点的标号;

(4) 设d[0]=0,其他d[i]=inf;

(5) 循环n次,在所有未标号结点中,选出d值最小的结点x,给结点x标记,对于从x出发的所有边(x,y),更新d[y]= min{d[y], d[x]+w(x,y)}。

算法实现

  1. 建立地图

DijkStra算法实现校园地图导航 - 图1

  1. 在控制台中,将地图抽象为

DijkStra算法实现校园地图导航 - 图2

  1. 根据设计要求和实际需要定义的宏如下
  1. #define M 8//地点数
  2. #define N 12//路径数
  3. #define mapRowNum 10//地图行数
  4. #define mapColNum 10//地图列数
  1. 定义地图二维数组
  1. //地图二维数组
  2. static char map[mapRowNum][mapRowNum] = {
  3. {' ', ' ', ' ', ' ', '0', '*', ' ', ' ', ' ', ' '},
  4. {' ', ' ', ' ', '*', '*', ' ', '1', ' ', ' ', ' '},
  5. {' ', ' ', '*', ' ', '2', '*', ' ', '*', ' ', ' '},
  6. {' ', '*', ' ', ' ', '*', ' ', ' ', ' ', '*', ' '},
  7. {'*', ' ', ' ', '*', '3', '*', ' ', ' ', ' ', '*'},
  8. {'*', ' ', '*', ' ', '*', ' ', '*', ' ', ' ', '*'},
  9. {'4', '*', ' ', ' ', '*', ' ', ' ', '*', '*', '6'},
  10. {' ', ' ', '*', '*', '5', '*', '*', ' ', ' ', ' '},
  11. {' ', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', ' '},
  12. {' ', ' ', ' ', ' ', '7', ' ', ' ', ' ', ' ', ' '},
  13. };
  1. 定义相邻两点间的距离数组
  1. //相邻两点间的距离数组
  2. static int dist[3][12] = {
  3. {0, 0, 0, 1, 1, 2, 3, 3, 3, 4, 5, 5},
  4. {1, 2, 4, 2, 6, 3, 4, 5, 6, 5, 6, 7},
  5. {3, 2, 12, 3, 10, 2, 9, 4, 11, 7, 9, 2}
  6. };
  1. 定义地点名数组
  1. //地点名
  2. static char loca[8][8] = {"图书馆", "行远楼", "信南", "四区", "东操", "餐厅", "北操", "宿舍区"};
  1. 定义其他数组
  1. int edge[N][N], weight[N], disp[N];
  2. bool visited[N] = {false};
  3. const int inf = 999999;
  1. 打印地图和图例的函数
  1. //打印地图和图例
  2. void printMap() {
  3. printf(" ");
  4. for(int i = 0; i < mapRowNum; i++) {
  5. for(int j = 0; j < mapColNum; j++) {
  6. printf("%c ", map[i][j]);
  7. }
  8. printf("\n ");
  9. }
  10. printf("\n");
  11. printf("图例:(共8个地点)\n 0-图书馆 1-行远楼 2-信南 3-四区");
  12. printf(" 4-东操 5-餐厅 6-北操 7-宿舍区\n\n");
  13. printf("各地点间距离:(任意两点间共12条路径)\n ");
  14. printf("0-1:3; 0-2:2; 0-4:12; 1-2:3; 1-6:10; 2-3:2; ");
  15. printf("3-4:9; 3-5:4; 3-6:11; 4-5:7; 5-6:9; 5-7:2 ");
  16. }
  1. 求解最短路径的函数
  1. //求解最短路径
  2. void calculatePath(){
  3. int prev[N];//用来标注当前结点的上一个结点,以便输出两点间最短路线
  4. fill(edge[0], edge[0] + N * N, inf);//注意这里要是N*N,要不然不是全部
  5. fill(disp, disp + N, inf);
  6. int start_point;
  7. cout<<"\n\n请输入起点:";
  8. cin>>start_point;
  9. //建立二维距离矩阵
  10. for(int i=0; i < N; i++) {
  11. edge[dist[0][i]][dist[1][i]] = edge[dist[1][i]][dist[0][i]] = dist[2][i];
  12. }
  13. for(int i = 0; i < N; i++) {
  14. prev[i] = i;//初始状态设每个点的前驱为自身
  15. edge[i][i] = 0;
  16. }
  17. //DijkStra算法求解最短路径
  18. disp[start_point] = 0;
  19. for(int i = 0; i < M; i++) {
  20. int u = -1, min = inf;
  21. for(int j = 0; j < M; j++) {
  22. if(visited[j] == false && disp[j] <= min) {
  23. u = j;
  24. min = disp[j];
  25. }
  26. }
  27. if(u == -1) break;
  28. visited[u] = true;
  29. for(int v = 0; v < M; v++) {
  30. if(visited[v] == false && edge[u][v] != inf) {
  31. if(disp[u] + edge[u][v] < disp[v]) {
  32. disp[v] = disp[u] + edge[u][v];
  33. prev[v] = u;//prev保存当前结点的上一个节点,以便输出最短路线
  34. }
  35. }
  36. }
  37. }
  38. int end_point;//终点
  39. cout<<"请输入终点:";
  40. cin>>end_point;
  41. stack<int> myStack;//最短路径栈
  42. //构建最短路径栈
  43. int temp = end_point;
  44. myStack.push(end_point);//先加终点
  45. while(start_point != temp) {
  46. temp = prev[temp];
  47. myStack.push(temp);//注意这里是把当前点的上一个结点放进去,此时换成了temp
  48. }
  49. cout<<"\n"<<loca[start_point]<<"("<<start_point<<")"<<" -> "<<loca[end_point];
  50. cout<<"("<<end_point<<")"<<"的最短距离为: "<<disp[end_point]<< "\n对应的路径为: ";
  51. //输出最短路径
  52. while(!myStack.empty()) {
  53. cout<<loca[myStack.top()]<<"("<<myStack.top()<<")";
  54. myStack.pop();
  55. if(!myStack.empty())
  56. cout<<"->";
  57. }
  58. }
  1. 主函数
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <stack>
  4. using namespace std;
  5. int main() {
  6. printMap();
  7. calculatePath();
  8. return 0;
  9. }

运行结果

DijkStra算法实现校园地图导航 - 图3