最短路径Dijkstra算法

素颜马尾好姑娘i 2022-08-21 03:27 413阅读 0赞

最短路径Dijkstra算法

本文取自《数据结构与算法》(C语言版)(第三版),出版社是清华大学出版社。

本博文作为学习资料整理。附书的截图:

Center

最短路径的Dijkstra算法的基本思想是:设S为最短路径已确定的顶点集,V-S是最短距离尚未确定的顶点集。初始时,将源点V0添加到顶点集S中,即S={V0}。在当前顶点集V-S中选择一个最短路径最小的顶点来扩充顶点集S,以保证算法按路径长度递增的次序产生各顶点的最短路径。

Dijkstra算法的步骤示意图如下:

SouthEast
其程序如下:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #define MaxVertexNum 100
  5. const int INF=25500000;
  6. typedef struct node
  7. {
  8. int adjvex;
  9. int hostvex;
  10. struct node *nextrarc;
  11. int info;
  12. }EdgeNode;
  13. typedef struct vnode
  14. {
  15. char vexdate;
  16. int pos;
  17. EdgeNode *firstarc;
  18. }VertexNode;
  19. typedef VertexNode AdjList[MaxVertexNum];
  20. typedef struct
  21. {
  22. AdjList adjlist;
  23. int n,e;
  24. }ALGraph;
  25. int initGraph(ALGraph* aGraph);
  26. int mFind(char aChar, ALGraph* aGraph);
  27. int createHead(char aChar, ALGraph* aGraph);
  28. void addBody(char aChar, int aPos, ALGraph* aGraph, int weight);
  29. void showGraph(ALGraph* aGraph);
  30. EdgeNode* isEdge(VertexNode* start, VertexNode* end);
  31. void Dijkstra(ALGraph* aGraph, int v);
  32. void Dispath(int dist[], int path[], int s[], ALGraph* aGraph, int v);
  33. void privatePrintPath(ALGraph* aGraph, int path[], int curr, int v);
  34. int main(void)
  35. {
  36. char a;
  37. int isFinish=0;
  38. int headPos=-1;
  39. char a1='@', a2='@', a3='@', a4='@', a5='@', a6='@', a7='@';
  40. ALGraph g_graph;
  41. initGraph(&g_graph);
  42. printf("Input arcs like this '(start,end:weight)',end with $\n");
  43. while(isFinish==0)
  44. {
  45. while(1)
  46. {
  47. a=getchar();
  48. if(a=='$'||a=='#')
  49. {
  50. if(a=='#')
  51. isFinish=1;
  52. break;
  53. }
  54. if(a==' '||a=='\n')
  55. continue;
  56. a1=a2;
  57. a2=a3;
  58. a3=a4;
  59. a4=a5;
  60. a5=a6;
  61. a6=a7;
  62. a7=a;
  63. if(a1=='('&&a3==','&&a5==':'&&a7==')')
  64. {
  65. if((headPos=mFind(a2,&g_graph))==-1)
  66. headPos=createHead(a2,&g_graph);
  67. addBody(a4,headPos,&g_graph,a6-48);
  68. }
  69. }
  70. }
  71. Dijkstra(&g_graph,2);
  72. return 0;
  73. }
  74. EdgeNode* isEdge(VertexNode* start, VertexNode* end)
  75. {
  76. EdgeNode* temEdge=start->firstarc;
  77. while(temEdge!=NULL)
  78. {
  79. if(temEdge->adjvex==end->pos)
  80. return temEdge;
  81. temEdge=temEdge->nextrarc;
  82. }
  83. return NULL;
  84. }
  85. void Dijkstra(ALGraph* aGraph, int v)
  86. {
  87. int dist[MaxVertexNum], path[MaxVertexNum];
  88. int s[MaxVertexNum];
  89. int mindis,i,j,u;
  90. EdgeNode* temEdge;
  91. for(i=0; i<aGraph->n; i++)
  92. {
  93. dist[i]=INF;
  94. s[i]=0;
  95. path[i]=-1;
  96. }
  97. temEdge=aGraph->adjlist[v].firstarc;
  98. while(temEdge!=NULL)
  99. {
  100. dist[temEdge->adjvex]=temEdge->info;
  101. path[temEdge->adjvex]=v;
  102. temEdge=temEdge->nextrarc;
  103. }
  104. s[v]=1;path[v]=v;dist[v]=0;
  105. for(i=0; i<aGraph->n; i++)
  106. {
  107. mindis=INF;
  108. for(j=0; j<aGraph->n; j++)
  109. {
  110. if(s[j]==0&&dist[j]<mindis)
  111. {
  112. u=j;
  113. mindis=dist[j];
  114. }
  115. }
  116. s[u]=1;
  117. for(j=0; j<aGraph->n; j++)
  118. {
  119. if(s[j]==0)
  120. {
  121. EdgeNode* temEdge=isEdge(&(aGraph->adjlist[u]), &(aGraph->adjlist[j]));
  122. if(temEdge!=NULL)
  123. {
  124. if((dist[u]+temEdge->info)<dist[j])
  125. {
  126. dist[j]=dist[u]+temEdge->info;
  127. path[j]=u;
  128. }
  129. }
  130. }
  131. }
  132. }
  133. Dispath(dist,path,s,aGraph,v);
  134. }
  135. void Dispath(int dist[], int path[], int s[], ALGraph* aGraph, int v)
  136. {
  137. int i;
  138. for(i=0; i<aGraph->n; i++)
  139. {
  140. printf("%c->%c(distance is %d) \n%c", aGraph->adjlist[v].vexdate,
  141. aGraph->adjlist[i].vexdate,dist[i],aGraph->adjlist[v].vexdate);
  142. privatePrintPath(aGraph,path,i,v);
  143. printf("\n");
  144. }
  145. }
  146. void privatePrintPath(ALGraph* aGraph, int path[], int curr, int v)
  147. {
  148. char temChar=aGraph->adjlist[curr].vexdate;
  149. int temPos=curr;
  150. if(curr!=v)
  151. {
  152. privatePrintPath(aGraph,path,path[temPos],v);
  153. printf(" ->%c",temChar);
  154. }
  155. }
  156. void showGraph(ALGraph* aGraph)
  157. {
  158. int i=0;
  159. for(i=0; i<aGraph->n; i++)
  160. {
  161. EdgeNode* pos;
  162. printf(" %c->",aGraph->adjlist[i]);
  163. pos=aGraph->adjlist[i].firstarc;
  164. while(pos!=NULL)
  165. {
  166. printf(" %d ",pos->adjvex);
  167. pos=pos->nextrarc;
  168. }
  169. printf("\n ");
  170. }
  171. }
  172. void addBody(char aChar, int aPos, ALGraph* aGraph, int weight)
  173. {
  174. int inversePos;
  175. EdgeNode* node=(EdgeNode*) malloc(sizeof(EdgeNode));
  176. node->info=weight;
  177. if((node->adjvex=mFind(aChar,aGraph))==-1)
  178. node->adjvex=createHead(aChar,aGraph);
  179. node->hostvex=aPos;
  180. node->nextrarc=NULL;
  181. if(aGraph->adjlist[aPos].firstarc==NULL)
  182. aGraph->adjlist[aPos].firstarc=node;
  183. else
  184. {
  185. EdgeNode* tail=aGraph->adjlist[aPos].firstarc;
  186. while(tail->nextrarc!=NULL)
  187. tail=tail->nextrarc;
  188. tail->nextrarc=node;
  189. }
  190. aGraph->e++;
  191. inversePos=node->adjvex;
  192. node=(EdgeNode*) malloc(sizeof(EdgeNode));
  193. node->info=weight;
  194. node->hostvex=inversePos;
  195. node->adjvex=aPos;
  196. node->nextrarc=NULL;
  197. if(aGraph->adjlist[inversePos].firstarc==NULL)
  198. aGraph->adjlist[inversePos].firstarc=node;
  199. else
  200. {
  201. EdgeNode* tail=aGraph->adjlist[inversePos].firstarc;
  202. while(tail->nextrarc!=NULL)
  203. tail=tail->nextrarc;
  204. tail->nextrarc=node;
  205. }
  206. aGraph->e++;
  207. }
  208. int createHead(char aChar, ALGraph* aGraph)
  209. {
  210. int currPos=aGraph->n;
  211. aGraph->adjlist[currPos].vexdate=aChar;
  212. aGraph->adjlist[currPos].pos=currPos;
  213. aGraph->n++;
  214. return currPos;
  215. }
  216. int mFind(char aChar, ALGraph* aGraph)
  217. {
  218. int i=0;
  219. for(i=0; i<aGraph->n; i++)
  220. {
  221. if(aChar==aGraph->adjlist[i].vexdate)
  222. return i;
  223. }
  224. return -1;
  225. }
  226. int initGraph(ALGraph* aGraph)
  227. {
  228. int i=0;
  229. aGraph->e=0;
  230. aGraph->n=0;
  231. for(i=0; i<MaxVertexNum; i++)
  232. {
  233. aGraph->adjlist[i].firstarc=NULL;
  234. }
  235. return 0;
  236. }

在VC2010中 C++控制台程序运行的结果:如下图所示:

Center 1

发表评论

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

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

相关阅读

    相关 路径Dijkstra算法

    最短路径之Dijkstra算法(看到i,j,k三个变量可以理解为需要三个for循环,方便记忆) 本节来学习指定一个点(源点)到其余各个顶点的最短路径,也称为”单源最短路径”。

    相关 路径Dijkstra算法 java

    思路:设置一个基点集合 S ,并不断地作贪心选择来扩充这个集合。一个顶点属于集合 S 当且仅当从源到该顶点的最短路径长度已知。初始时,S中仅含有源。设 u 是 G 的某一个顶点