图之Dijkstra算法

Dijkstra算法是一种求单源最短路算法,即从一个点开始到所有其他点的最短路。其步骤如下:

图之Dijkstra算法_第1张图片


图之Dijkstra算法_第2张图片


图之Dijkstra算法_第3张图片


图之Dijkstra算法_第4张图片


图之Dijkstra算法_第5张图片


图之Dijkstra算法_第6张图片


C语言实现如下:(使用邻接矩阵存储)

[cpp]  view plain  copy
  1. #include     
  2. #include     
  3. #define VERTEXNUM 6    
  4.   
  5. //存放最短路径的边元素  
  6. typedef struct edge{  
  7.         int vertex;  
  8.         int value;  
  9.         struct edge* next;  
  10. }st_edge;  
  11.   
  12. void createGraph(int (*edge)[VERTEXNUM], int start, int end, int value);    
  13. void displayGraph(int (*edge)[VERTEXNUM]);   
  14. void displayPath(st_edge** path, int startVertex,int* shortestPath);  
  15. void dijkstra(int (*edge)[VERTEXNUM], st_edge*** path, int** shortestPath, int startVertex, int* vertexStatusArr);  
  16. int getDistance(int value, int startVertex, int start, int* shortestPath);  
  17. void createPath(st_edge **path, int startVertex, int start, int end, int edgeValue);  
  18.   
  19. int main(void){    
  20.         //动态创建存放边的二维数组   
  21.         int (*edge)[VERTEXNUM] = (int (*)[VERTEXNUM])malloc(sizeof(int)*VERTEXNUM*VERTEXNUM);    
  22.         int i,j;    
  23.         for(i=0;i
  24.                 for(j=0;j
  25.                         edge[i][j] = 0;    
  26.                 }    
  27.         }    
  28.         //存放顶点的遍历状态,0:未遍历,1:已遍历  
  29.         int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);    
  30.         for(i=0;i
  31.                 vertexStatusArr[i] = 0;    
  32.         }    
  33.     
  34.         printf("after init:\n");    
  35.         displayGraph(edge);    
  36.         //创建图   
  37.         createGraph(edge,0,1,6);    
  38.         createGraph(edge,0,3,5);    
  39.         createGraph(edge,0,2,1);    
  40.         createGraph(edge,1,2,5);    
  41.         createGraph(edge,1,4,3);    
  42.         createGraph(edge,2,4,6);    
  43.         createGraph(edge,2,3,5);    
  44.         createGraph(edge,2,5,4);    
  45.         createGraph(edge,3,5,2);    
  46.         createGraph(edge,4,5,6);    
  47.     
  48.         printf("after create:\n");    
  49.         displayGraph(edge);  
  50.     //最短路径  
  51.         /*存储的结构如下: 
  52.             path[0]:edge0->NULL 
  53.             path[1]:edge1->NULL 
  54.             path[2]:edge1->edge2->NULL 
  55.             path[3]:edge1->edge2->edge3->NULL 
  56.             path[4]:edge4->NULL 
  57.             从顶点0到0的最短路径:从0出发直接到0 
  58.             从顶点0到1的最短路径:从0出发直接到1 
  59.             从顶点0到2的最短路径:从0出发到1,从1出发到2 
  60.             ...... 
  61.         */  
  62.     st_edge** path = NULL;  
  63.     //存储最短路径的权值  
  64.         /* 
  65.         shortestPath[0] = 0; 
  66.         shortestPath[1] = 8; 
  67.         shortestPath[2] = 12; 
  68.         从顶点0到0的路径是0 
  69.         从顶点0到1的路径是8 
  70.         从顶点0到2的路径是12 
  71.         */  
  72.     int* shortestPath = NULL;  
  73.     //从顶点0开始寻找最短路径  
  74.     int startVertex = 0;  
  75.     //最短路径  
  76.     dijkstra(edge, &path, &shortestPath, startVertex, vertexStatusArr);  
  77.     printf("the path is:\n");  
  78.     displayPath(path,startVertex,shortestPath);  
  79.     
  80.         free(edge);    
  81.         free(path);    
  82.         return 0;    
  83. }    
  84. //创建图   
  85. void createGraph(int (*edge)[VERTEXNUM], int start, int end, int value){    
  86.         edge[start][end] = value;    
  87.         edge[end][start] = value;    
  88. }    
  89. //打印存储的图  
  90. void displayGraph(int (*edge)[VERTEXNUM]){    
  91.         int i,j;    
  92.         for(i=0;i
  93.                 for(j=0;j
  94.                         printf("%d ",edge[i][j]);    
  95.                 }    
  96.                 printf("\n");    
  97.         }    
  98. }  
  99. //打印最短路径  
  100. void displayPath(st_edge** path, int startVertex,int* shortestPath){  
  101.         int i;  
  102.         st_edge* p;  
  103.         for(i=0;i
  104.                 printf("Path from %d to %d:",startVertex,i);  
  105.                 p = *(path+i);  
  106.                 while(p != NULL){  
  107.                         printf("%d(%d) ",p->vertex,p->value);  
  108.                         p = p->next;  
  109.                 }  
  110.                 printf("\n");  
  111.         printf("the count is:%d\n",shortestPath[i]);  
  112.         }  
  113. }  
  114. //最短路径  
  115. void dijkstra(int (*edge)[VERTEXNUM], st_edge*** path, int** shortestPath, int startVertex, int* vertexStatusArr){  
  116.     //初始化最短路径  
  117.     *path = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);  
  118.         int i,j;  
  119.     for(i=0;i
  120.         if(i == startVertex){  
  121.             st_edge* e = (st_edge*)malloc(sizeof(st_edge));  
  122.             e->vertex = startVertex;  
  123.             e->value = 0;  
  124.             e->next = NULL;  
  125.             (*path)[i] = e;  
  126.         }else{  
  127.             (*path)[i] = NULL;  
  128.         }  
  129.     }  
  130.     //初始化最短路径的权值  
  131.     *shortestPath = (int *)malloc(sizeof(int)*VERTEXNUM);  
  132.     for(i=0;i
  133.         if(i == startVertex){  
  134.             (*shortestPath)[i] = 0;  
  135.         }else{  
  136.             (*shortestPath)[i] = -1;  
  137.         }  
  138.     }  
  139.     //从顶点0开始,则顶点0就是已访问的   
  140.     vertexStatusArr[startVertex] = 1;    
  141.    
  142.     int shortest, distance,start, end, edgeValue, vNum = 1;  
  143.         //如果还顶点还没有访问完  
  144.         while(vNum < VERTEXNUM){  
  145.                 shortest = 9999;    
  146.                 for(i=0;i
  147.                         //选择已经访问过的点  
  148.                         if(vertexStatusArr[i] == 1){    
  149.                                 for(j=0;j
  150.                                         //选择一个没有访问过的点    
  151.                                         if(vertexStatusArr[j] == 0){    
  152.                                                 //选出一条value最小的边  
  153.                                                 if(edge[i][j] != 0 && (distance = getDistance(edge[i][j], startVertex, i,  *shortestPath)) < shortest){    
  154.                                                         shortest = distance;    
  155.                                                         edgeValue = edge[i][j];  
  156. "white-space:pre">                          start = i;    
  157.                                                         end = j;    
  158.                                                 }    
  159.                                         }    
  160.                                 }    
  161.                         }    
  162.                 }    
  163.                 vNum++;    
  164.             //将点设置为访问过   
  165.             vertexStatusArr[end] = 1;     
  166.             //保存最短路径权值  
  167.             (*shortestPath)[end] = shortest;  
  168.             //保存最短路径  
  169.             createPath(*path, startVertex, start, end, edgeValue);   
  170.         }    
  171. }  
  172.   
  173. //返回从startVertex到新的顶点的距离  
  174. int getDistance(int value, int startVertex, int start, int* shortestPath){  
  175.     if(start == startVertex){  
  176.         return value;  
  177.     }else{  
  178.         return shortestPath[start] + value;  
  179.     }  
  180. }  
  181.   
  182. //保存最短路径  
  183. void createPath(st_edge **path, int startVertex, int start, int end, int edgeValue){  
  184.     if(start == startVertex){  
  185.         st_edge* newEdge = (st_edge*)malloc(sizeof(st_edge));  
  186.         newEdge->vertex = end;  
  187.         newEdge->value = edgeValue;  
  188.         newEdge->next = NULL;  
  189.           
  190.         st_edge** p = path + end;  
  191.         while((*p) != NULL){  
  192.             p = &((*p)->next);  
  193.         }  
  194.         *p = newEdge;  
  195.     }else{  
  196.         st_edge** pCopySrc = path + start;  
  197.         st_edge** pCopyDes = path + end;  
  198.         st_edge* newEdge = NULL;  
  199.         while((*pCopySrc) != NULL){  
  200.             newEdge = (st_edge*)malloc(sizeof(st_edge));  
  201.             *newEdge = **pCopySrc;  
  202.             newEdge->next = NULL;  
  203.             *pCopyDes = newEdge;  
  204.             pCopySrc = &((*pCopySrc)->next);  
  205.             pCopyDes = &((*pCopyDes)->next);  
  206.         }  
  207.         newEdge = (st_edge*)malloc(sizeof(st_edge));  
  208.         newEdge->vertex = end;  
  209.         newEdge->value = edgeValue;  
  210.         newEdge->next = NULL;  
  211.         *pCopyDes = newEdge;  
  212.     }  
  213. }  


c语言实现如下:(使用邻接表存储)

[cpp]  view plain  copy
  1. #include   
  2. #include   
  3. #define VERTEXNUM 6  
  4.   
  5. //存放顶点的邻接表元素  
  6. //存放最短路径的边元素  
  7. typedef struct edge{  
  8.         int vertex;  
  9.         int value;  
  10.         struct edge* next;  
  11. }st_edge;  
  12.   
  13. void createGraph(st_edge** edge, int start, int end, int value);  
  14. void displayGraph(st_edge** edge);  
  15. void delGraph(st_edge** edge);  
  16. void dijkstra(st_edge** edge, st_edge*** path, int** shortestPath, int startVertex, int* vertexStatusArr);  
  17. void displayPath(st_edge** path, int startVertex,int* shortestPath);  
  18. int getDistance(int value, int startVertex, int start, int* shortestPath);  
  19. void createPath(st_edge **path, int startVertex, int start, int end, int edgeValue);  
  20.   
  21. int main(void){  
  22.     //动态创建存放边的指针数组    
  23.     st_edge** edge = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);  
  24.     int i;  
  25.     for(i=0;i
  26.             edge[i] = NULL;  
  27.     }  
  28.     //存放顶点的遍历状态,0:未遍历,1:已遍历  
  29.     int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);  
  30.     for(i=0;i
  31.             vertexStatusArr[i] = 0;  
  32.     }  
  33.   
  34.     printf("after init:\n");  
  35.     displayGraph(edge);  
  36.     //创建图  
  37.     createGraph(edge,0,1,6);  
  38.     createGraph(edge,0,3,5);  
  39.     createGraph(edge,0,2,1);  
  40.     createGraph(edge,1,2,5);  
  41.     createGraph(edge,1,4,3);  
  42.     createGraph(edge,2,4,6);  
  43.     createGraph(edge,2,3,5);  
  44.     createGraph(edge,2,5,4);  
  45.     createGraph(edge,3,5,2);  
  46.     createGraph(edge,4,5,6);  
  47.   
  48.     printf("after create:\n");  
  49.     displayGraph(edge);  
  50.   
  51.     //最短路径  
  52.     /*存储的结构如下: 
  53.         path[0]:edge0->NULL 
  54.         path[1]:edge1->NULL 
  55.         path[2]:edge1->edge2->NULL 
  56.         path[3]:edge1->edge2->edge3->NULL 
  57.         path[4]:edge4->NULL 
  58.         从顶点0到0的最短路径:从0出发直接到0 
  59.         从顶点0到1的最短路径:从0出发直接到1 
  60.         从顶点0到2的最短路径:从0出发到1,从1出发到2 
  61.         ...... 
  62.     */  
  63.     st_edge** path = NULL;  
  64.     //存储最短路径的权值  
  65.     /* 
  66.     shortestPath[0] = 0; 
  67.     shortestPath[1] = 8; 
  68.     shortestPath[2] = 12; 
  69.     从顶点0到0的路径是0 
  70.     从顶点0到1的路径是8 
  71.     从顶点0到2的路径是12 
  72.     */  
  73.     int* shortestPath = NULL;  
  74.     int startVertex = 0;  
  75.     //最短路径  
  76.     dijkstra(edge, &path, &shortestPath, startVertex, vertexStatusArr);  
  77.     printf("the path is:\n");  
  78.     displayPath(path,startVertex,shortestPath);  
  79.   
  80.     delGraph(edge);  
  81.     edge = NULL;  
  82.   
  83.     delGraph(path);   
  84.     path = NULL;  
  85.       
  86.     if(vertexStatusArr != NULL){  
  87.             free(vertexStatusArr);  
  88.             vertexStatusArr = NULL;  
  89.     }  
  90.   
  91.     if(shortestPath != NULL){  
  92.         free(shortestPath);  
  93.         shortestPath = NULL;  
  94.     }  
  95.         return 0;  
  96. }  
  97. //创建图  
  98. void createGraph(st_edge** edge, int start, int end, int value){  
  99.         st_edge* newedge1 = (st_edge*)malloc(sizeof(st_edge));  
  100.         newedge1->vertex = end;  
  101.     newedge1->value = value;  
  102.         newedge1->next = NULL;  
  103.         st_edge** edge1 = edge + start;  
  104.         while(*edge1 != NULL){  
  105.                 edge1 = &((*edge1)->next);  
  106.         }  
  107.         *edge1 = newedge1;  
  108.   
  109.     st_edge* newedge2 = (st_edge*)malloc(sizeof(st_edge));  
  110.         newedge2->vertex = start;  
  111.         newedge2->value = value;  
  112.         newedge2->next = NULL;  
  113.         st_edge** edge2 = edge + end;  
  114.         while(*edge2 != NULL){  
  115.                 edge2 = &((*edge2)->next);  
  116.         }  
  117.         *edge2 = newedge2;  
  118. }  
  119. //打印存储的图    
  120. void displayGraph(st_edge** edge){  
  121.         int i;  
  122.         st_edge* p;  
  123.         for(i=0;i
  124.                 printf("%d:",i);  
  125.                 p = *(edge+i);  
  126.                 while(p != NULL){  
  127.                         printf("%d(%d) ",p->vertex,p->value);  
  128.                         p = p->next;  
  129.                 }  
  130.                 printf("\n");  
  131.         }  
  132. }  
  133. //打印最短路径  
  134. void displayPath(st_edge** path, int startVertex,int* shortestPath){  
  135.         int i;  
  136.         st_edge* p;  
  137.         for(i=0;i
  138.                 printf("Path from %d to %d:",startVertex,i);  
  139.                 p = *(path+i);  
  140.                 while(p != NULL){  
  141.                         printf("%d(%d) ",p->vertex,p->value);  
  142.                         p = p->next;  
  143.                 }  
  144.                 printf("\n");  
  145.         printf("the count is:%d\n",shortestPath[i]);  
  146.         }  
  147. }  
  148. //释放邻接表占用的内存  
  149. void delGraph(st_edge** edge){  
  150.         int i;  
  151.         st_edge* p;  
  152.         st_edge* del;  
  153.         for(i=0;i
  154.                 p = *(edge+i);  
  155.                 while(p != NULL){  
  156.                         del = p;  
  157.                         p = p->next;  
  158.                         free(del);  
  159.                 }  
  160.                 edge[i] = NULL;  
  161.         }  
  162.         free(edge);  
  163. }  
  164. //dijkstra求最短路径  
  165. void dijkstra(st_edge** edge, st_edge*** path, int** shortestPath, int startVertex, int* vertexStatusArr){  
  166.     //初始化最短路径  
  167.     *path = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);  
  168.         int i,j;  
  169.         for(i=0;i
  170.         if(i == startVertex){  
  171.             st_edge* e = (st_edge*)malloc(sizeof(st_edge));  
  172.             e->vertex = startVertex;  
  173.             e->value = 0;  
  174.             e->next = NULL;  
  175.             (*path)[i] = e;  
  176.         }else{  
  177.             (*path)[i] = NULL;  
  178.         }  
  179.         }  
  180.     //初始化最短路径的权值  
  181.     *shortestPath = (int *)malloc(sizeof(int)*VERTEXNUM);  
  182.     for(i=0;i
  183.         if(i == startVertex){  
  184.             (*shortestPath)[i] = 0;  
  185.         }else{  
  186.             (*shortestPath)[i] = -1;  
  187.         }  
  188.     }  
  189.   
  190.     vertexStatusArr[startVertex] = 1;  
  191.   
  192.     st_edge* p;  
  193.     int shortest, distance, edgeValue, start, end, vNum = 1;  
  194.     //如果还顶点还没有访问完  
  195.     while(vNum < VERTEXNUM){  
  196.         shortest = 9999;  
  197.         for(i=0;i
  198.             //选择已经访问过的点  
  199.             if(vertexStatusArr[i] == 1){  
  200.                 for(j=0;j
  201.                     //选择一个没有访问过的点   
  202.                     if(vertexStatusArr[j] == 0){  
  203.                         p = *(edge+i);  
  204.                         while(p != NULL){  
  205.                             //如果从startVertex到j的距离小于shortest  
  206.                             if((distance = getDistance(p->value, startVertex, i, *shortestPath)) < shortest && p->vertex == j){  
  207.                                 shortest = distance;  
  208.                                 edgeValue = p->value;  
  209.                                 start = i;  
  210.                                 end = j;  
  211.                             }  
  212.                             p = p->next;  
  213.                         }                         
  214.                     }  
  215.                 }  
  216.             }  
  217.         }  
  218.         vNum++;  
  219.         vertexStatusArr[end] = 1;  
  220.         //保存最短路径的权值  
  221.         (*shortestPath)[end] = shortest;  
  222.         //保存最短路径  
  223.         createPath(*path, startVertex, start, end, edgeValue);  
  224.     }  
  225. }  
  226. //返回从startVertex到新的顶点的距离  
  227. int getDistance(int value, int startVertex, int start, int* shortestPath){  
  228.     if(start == startVertex){  
  229.         return value;  
  230.     }else{  
  231.         return value + shortestPath[start];  
  232.     }  
  233. }  
  234. //保存最短路径  
  235. void createPath(st_edge **path, int startVertex, int start, int end, int edgeValue){  
  236.     if(start == startVertex){  
  237.         st_edge* newEdge = (st_edge*)malloc(sizeof(st_edge));  
  238.         newEdge->vertex = end;  
  239.         newEdge->value = edgeValue;  
  240.         newEdge->next = NULL;  
  241.           
  242.         st_edge** p = path + end;  
  243.         while((*p) != NULL){  
  244.             p = &((*p)->next);  
  245.         }  
  246.         *p = newEdge;  
  247.     }else{  
  248.         st_edge** pCopySrc = path + start;  
  249.         st_edge** pCopyDes = path + end;  
  250.         st_edge* newEdge = NULL;  
  251.         while((*pCopySrc) != NULL){  
  252.             newEdge = (st_edge*)malloc(sizeof(st_edge));  
  253.             *newEdge = **pCopySrc;  
  254.             newEdge->next = NULL;  
  255.             *pCopyDes = newEdge;  
  256.             pCopySrc = &((*pCopySrc)->next);  
  257.             pCopyDes = &((*pCopyDes)->next);  
  258.         }  
  259.         newEdge = (st_edge*)malloc(sizeof(st_edge));  
  260.         newEdge->vertex = end;  
  261.         newEdge->value = edgeValue;  
  262.         newEdge->next = NULL;  
  263.         *pCopyDes = newEdge;  
  264.     }  
  265. }  

      博客地址:http://blog.csdn.net/todd911/article/details/9347053

你可能感兴趣的:(数据结构)