单源最短路径Dijkstra算法

Dijkstra算法中设置了一顶点集合S,从源点s到集合中的顶点的最终最短路径的权值均已确定。算法反复选择具有最短

路径估计的顶点u∈V - S,并将u加入S中,对u的所有出边进行松弛,在下列算法实现中,用到了顶点的最小优先队列

Q,排序关键字为顶点的d值。d为实时权值。



代码如下:

 

  1. #include<iostream>  
  2. #include<list>  
  3. using namespace std;  
  4.   
  5. #define MAXVALUE 10000          //定义一个最长路径   
  6.   
  7. //此处Dijkstra算法的图为有向图  
  8.   
  9. struct Edge  
  10. {  
  11.     int verno;          //邻接数组中节点编号  
  12.     int weight;         //权值  
  13.     Edge* next;         //指向下一条边  
  14. };  
  15.   
  16. struct Vertex  
  17. {  
  18.     Edge *adj;          //所指向的节点所在边  
  19.     int verno;          //邻接数组中节点编号  
  20.     char key;           //关键字  
  21. };  
  22.   
  23. struct Graph  
  24. {  
  25.     Vertex *vertexs;    //节点数组  
  26.     int vertexnum;      //节点个数  
  27.     int adjnum;         //边数  
  28. };  
  29.   
  30. class MSWDijkstra  
  31. {  
  32. public:  
  33.     MSWDijkstra(char *vertex,int vernum,char adj[][2],int *weight,int adjnum);  
  34.     void DijkstraInsert(int source,int dest,int weight);  
  35.     int DijkstraFindKey(char key);  
  36.     int DijkstraExtraMin(bool *visited,int length);  
  37.     void DijkstraInitSingleSource();  
  38.     void DijkstraMSW(char sourceKey);  
  39.     void DijkstraOutput();  
  40. private:  
  41.     int *shortway;  
  42.     int *parent;  
  43.     Graph *dijkstraGraph;  
  44. };  
  45.   
  46. MSWDijkstra::MSWDijkstra(char *vertex,int vernum,char adj[][2],int *weight,int adjnum)  
  47. {  
  48.     int i,source,dest;  
  49.   
  50.     shortway = new int[vernum];  
  51.     parent = new int[vernum];  
  52.     dijkstraGraph = new Graph;  
  53.   
  54.     dijkstraGraph->vertexs = new Vertex[vernum];  
  55.     dijkstraGraph->adjnum = adjnum;  
  56.     dijkstraGraph->vertexnum = vernum;  
  57.     for(i = 0;i < vernum;i++)  
  58.     {  
  59.         dijkstraGraph->vertexs[i].key = vertex[i];  
  60.         dijkstraGraph->vertexs[i].verno = i;  
  61.         dijkstraGraph->vertexs[i].adj = NULL;  
  62.     }  
  63.   
  64.     for(i = 0;i < adjnum;i++)  
  65.     {  
  66.         source = DijkstraFindKey(adj[i][0]);  
  67.         dest = DijkstraFindKey(adj[i][1]);  
  68.         DijkstraInsert(source,dest,weight[i]);  
  69.         //DijkstraInsert(dest,source,weight[i]);            //无向图与有向图的区别在此  
  70.     }  
  71. }  
  72.   
  73. void MSWDijkstra::DijkstraInsert(int source,int dest,int weight)  
  74. {  
  75.     if(dijkstraGraph->vertexs[source].adj == NULL || dijkstraGraph->vertexs[source].adj->weight > weight)  
  76.     {  
  77.         Edge* newnode = new Edge;  
  78.         newnode->verno = dest;  
  79.         newnode->weight = weight;  
  80.         newnode->next = dijkstraGraph->vertexs[source].adj;  
  81.         dijkstraGraph->vertexs[source].adj = newnode;  
  82.     }  
  83.     else  
  84.     {  
  85.         Edge* temp = dijkstraGraph->vertexs[source].adj;  
  86.         while(temp->next != NULL)                        //插入新边的时候,把权值从低到高进行排序  
  87.         {  
  88.             if(temp->next->weight > weight)  
  89.                 break;  
  90.             temp = temp->next;  
  91.         }  
  92.         Edge* newnode = new Edge;  
  93.         newnode->verno = dest;  
  94.         newnode->weight = weight;  
  95.         newnode->next = temp->next;  
  96.         temp->next = newnode;  
  97.     }  
  98. }  
  99.   
  100. int MSWDijkstra::DijkstraFindKey(char key)  
  101. {  
  102.     int i;  
  103.     for(i = 0;i < dijkstraGraph->vertexnum;i++)  
  104.     {  
  105.         if(dijkstraGraph->vertexs[i].key == key)  
  106.             break;  
  107.     }  
  108.     return i;  
  109. }  
  110.   
  111. int MSWDijkstra::DijkstraExtraMin(bool *visited,int length)  
  112. {  
  113.     int min = MAXVALUE;  
  114.     for(int i = 0;i < length; i++)  
  115.     {  
  116.         if(!visited[i])  
  117.         {  
  118.             if(min != MAXVALUE && shortway[i] < shortway[min] || min == MAXVALUE)  
  119.                 min = i;  
  120.         }  
  121.     }  
  122.     return min;  
  123. }  
  124.   
  125. void MSWDijkstra::DijkstraInitSingleSource()  
  126. {  
  127.     int vernum = dijkstraGraph->vertexnum;  
  128.     for(int i = 0;i < vernum;i++)  
  129.     {  
  130.         shortway[i] = MAXVALUE;  
  131.         parent[i] = i;  
  132.     }  
  133. }  
  134.   
  135. void MSWDijkstra::DijkstraMSW(char sourceKey)  
  136. {  
  137.     int i;  
  138.     int count = 1;  
  139.     Edge* sourceEdge;  
  140.     int vernum = dijkstraGraph->vertexnum;  
  141.     int source = DijkstraFindKey(sourceKey);  
  142.     bool *visited = new bool[vernum];  
  143.     for(i = 0;i < vernum;i++)  
  144.     {  
  145.         visited[i] = false;  
  146.     }  
  147.     DijkstraInitSingleSource();  
  148.     shortway[source] = 0;  
  149.     while(count <= vernum)  
  150.     {  
  151.         i = DijkstraExtraMin(visited,vernum);  
  152.         visited[i] = true;  
  153.         count++;  
  154.         sourceEdge = dijkstraGraph->vertexs[i].adj;  
  155.         while(sourceEdge != NULL)  
  156.         {  
  157.             if((shortway[i] + sourceEdge->weight) < shortway[sourceEdge->verno])  
  158.             {  
  159.                 parent[sourceEdge->verno] = i;  
  160.                 shortway[sourceEdge->verno] = shortway[i] + sourceEdge->weight;  
  161.             }  
  162.             sourceEdge = sourceEdge->next;  
  163.         }  
  164.     }  
  165.     delete []visited;  
  166. }  
  167.   
  168. void MSWDijkstra::DijkstraOutput()  
  169. {  
  170.     int i,j,weight;  
  171.     list<int> route;  
  172.     cout<<"All the most shortest route from source : "<<endl;  
  173.     for(i = 0;i < dijkstraGraph->vertexnum;i++)  
  174.     {  
  175.         j = i;  
  176.         weight = shortway[j];  
  177.         do  
  178.         {  
  179.             route.push_front(j);  
  180.             j = parent[j];  
  181.   
  182.         }while(parent[j] != j);  
  183.   
  184.         cout<<dijkstraGraph->vertexs[j].key;  
  185.         cout<<"---"<<dijkstraGraph->vertexs[route.front()].key;  
  186.         route.pop_front();  
  187.         while(!route.empty())  
  188.         {  
  189.             if(route.front() != j)  
  190.                 cout<<"---"<<dijkstraGraph->vertexs[route.front()].key;  
  191.             route.pop_front();  
  192.         }  
  193.         cout<<"    "<<weight<<endl;  
  194.     }  
  195.   
  196. }  
  197.   
  198. int main()  
  199. {  
  200.     char vertex[] = {'S','T','X','Y','Z'};  
  201.     int vernum = 5;  
  202.     char adj[][2] = {{'S','T'},{'S','Y'},{'T','X'},{'T','Y'},{'X','Z'},{'Y','T'},{'Y','X'},{'Y','Z'},{'Z','S'},{'Z','X'}};  
  203.     int weight[] = {10,5,1,2,4,3,9,2,7,6};  
  204.     int adjnum = 10;  
  205.     MSWDijkstra *dijkstra = new MSWDijkstra(vertex,vernum,adj,weight,adjnum);  
  206.     dijkstra->DijkstraMSW('S');  
  207.     dijkstra->DijkstraOutput();  
  208.   
  209.     return 0;  
  210. }  

结果如下:

 

 

    1. All the most shortest route from source :  
    2. S---S    0  
    3. S---Y---T    8  
    4. S---Y---T---X    9  
    5. S---Y    5  
    6. S---Y---Z    7  
    7. 请按任意键继续. . .  
posted @ 2013-04-09 13:14  季相相  阅读(175)  评论(0编辑  收藏  举报