当前位置:   article > 正文

数据结构实验任务六 :基于 Dijsktra 算法的最短路径求解_基于dijsktra算法的最短路径求解

基于dijsktra算法的最短路径求解

本次代码为实验六:基于 Dijsktra 算法的最短路径求解实现。本实验的重点在于对于Dijsktra算法的理解。有关Dijsktra的资料可以参考有关博文:

图论:Dijkstra算法——最详细的分析,图文并茂,一次看懂!-CSDN博客

以下附上实现代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define MaxE 5
  5. #define MVNum 100
  6. #define MaxInt 32767
  7. typedef struct{
  8. char vex[MVNum]; //顶点表
  9. int arcs[MVNum][MVNum];//邻接矩阵,权重为整数
  10. int Vexnum;//顶点数
  11. int arcnum; //边数
  12. }AMGraph;
  13. //全局变量部分
  14. int cunt=0; //为存储矩阵计数
  15. int store[MaxE][MVNum]; //存储结果矩阵 ,每个结果数组的第一位位存最短路径值,后面为路径节点
  16. int ismin[MVNum]; //记录该几点是否已为最小值
  17. //函数定义部分
  18. void Dijsktra(AMGraph *a,char s,char e);
  19. void Init(AMGraph *a);
  20. int Read(AMGraph *a);
  21. void Cal(AMGraph *a);
  22. void show(int a[]);
  23. int getIndex(AMGraph *a,char c);
  24. //函数部分
  25. void Init(AMGraph *a){ //初始化图和存储数组
  26. a->arcnum=0;
  27. a->Vexnum=0;
  28. for(int i=0;i<MVNum;i++){
  29. for(int j=0;j<MVNum;j++){
  30. a->arcs[i][j]=MaxInt;
  31. }
  32. }
  33. for(int i=0;i<MVNum;i++){
  34. a->vex[i] = 0;
  35. store[cunt][i] = 0;
  36. ismin[i] = 0;
  37. }
  38. }
  39. int getIndex(AMGraph *a,char c){ //获取节点在图中的位置
  40. int rs;
  41. for(int i=0;i<a->Vexnum;i++){
  42. if(c==a->vex[i])return i;
  43. }
  44. }
  45. void show(int a[]){ //输出数据
  46. printf("\n[RES]:\n");
  47. printf("最短距离:%d\n",a[0]); //第一位为数字,直接输出
  48. printf("最短路径:%c",a[1]);
  49. for(int i=2;i<MVNum;i++){ //后面皆为字符;
  50. if(a[i] == 0){
  51. break;
  52. }
  53. printf("->%c",a[i]);
  54. }
  55. }
  56. void Dijsktra(AMGraph *a,char s,char e){
  57. int min=0;//记录每一趟的最小值以及该节点
  58. char minv;
  59. int *lgti = (int*)malloc(sizeof(int)*a->Vexnum); //该数组用于更新节点节点的最短路径
  60. char ** lgtc = (char**)malloc(sizeof(char*)*a->Vexnum); //该数组用于保存每个节点当前最短路径
  61. for(int i=0;i<a->Vexnum;i++){ //初始化
  62. lgtc[i]=(char*)malloc(sizeof(char)*a->Vexnum);
  63. lgtc[i][0] = s;
  64. for(int j=1;j<a->Vexnum;j++)lgtc[i][j]=0;
  65. lgti[i] = MaxInt;
  66. }
  67. minv=s;
  68. for(int i=0;i<a->Vexnum-1;i++){ //每次确定一个最小路径,最多共需v-1趟完成
  69. for(int j=0;j<a->Vexnum;j++){ //每趟对v个节点路径进行更新
  70. //printf("\n%c:new =%d,old =%d\n",a->vex[j],min+a->arcs[getIndex(a,minv)][j],lgti[j]);
  71. if(min+a->arcs[getIndex(a,minv)][j]<lgti[j]){ //若更新节点值小于现有最小值,则更新为改值
  72. lgti[j] = min+a->arcs[getIndex(a,minv)][j];
  73. strcpy(lgtc[j],lgtc[getIndex(a,minv)]);
  74. lgtc[j][strlen(lgtc[j])] = a->vex[j];
  75. }
  76. }
  77. min = MaxInt;
  78. printf("[TRV %d]:",cunt+1);
  79. for(int j=0;j<a->Vexnum;j++){
  80. if(lgti[j]<min&&ismin[j]==0){ //若小于min且未定为最小值,则记录
  81. min = lgti[j];
  82. minv = a->vex[j];
  83. }
  84. }
  85. printf("新增最小路径: %c\n",minv);
  86. if(minv==e){
  87. printf("Success!\n");
  88. store[cunt][0] = min;
  89. for(int i=0;i<strlen(lgtc[getIndex(a,e)]);i++){
  90. store[cunt][i+1]=(int)lgtc[getIndex(a,e)][i];
  91. }
  92. cunt++;
  93. break;
  94. }
  95. ismin[getIndex(a,minv)]=1;
  96. }
  97. }
  98. void Cal(AMGraph *a){ //计算结果,Dijsktra
  99. char start,end;
  100. getchar(); //结果存储
  101. printf("请输入起始节点: ");
  102. scanf(" %c %c",&start,&end);
  103. Dijsktra(a,start,end);
  104. }
  105. int Read(AMGraph *a){ //读取数据
  106. int n,m,lgt;
  107. char ca,cb;
  108. printf("请输入n,m:");
  109. scanf("%d%d",&n,&m);
  110. if(n==0&&m==0)return 1;
  111. a->Vexnum = n;
  112. a->arcnum =m;
  113. printf("请输入顶点:");
  114. for(int i=0;i<n;i++){
  115. scanf(" %c",&a->vex[i]); //储存节点
  116. }
  117. getchar();
  118. printf("请输入边: \n");
  119. for(int i=0;i<m;i++){ //存储边
  120. scanf(" %c %c %d",&ca,&cb,&lgt);
  121. a->arcs[getIndex(a,ca)][getIndex(a,cb)]=lgt;
  122. }
  123. return 0;
  124. }
  125. int main(){
  126. int flag=0; //记录是否输入停止
  127. AMGraph *a = (AMGraph*)malloc(sizeof(AMGraph));
  128. printf("多组数据,每组数据有 m+3 行。\n第一行为两个整数 n 和 m,分别代表城市个数 n 和路径条数 m。\n第二行有 n 个字符,代表每个城市的名字。\n第三行到第m+2 行每行有两个字符 a 和 b 和一个整数 d,代表从城市 a 到城市 b 有一条距离为 d 的路。\n最后一行为两个字符,代表待求最短路径的城市起点和终点。\n当 n 和m 都等于 0 时,输入结束");
  129. while(1){
  130. Init(a); //初始化图
  131. printf("\n =================| -FZC- |=============== \n\n");
  132. flag = Read(a); //读取信息
  133. if(flag==1){
  134. printf("\n =================| -FZC- |=============== \n\n");
  135. printf("\nFOLLOWING OUTPUI:\n");
  136. printf("共寻径[%d]次\n",cunt);
  137. for(int i=0;i<cunt;i++)show(store[i]);
  138. break;
  139. }
  140. Cal(a); //计算距离并存储结果
  141. }
  142. return 0;
  143. }

以上代码仅供参考,欢迎交流。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/711000
推荐阅读
相关标签
  

闽ICP备14008679号