Dijkstra算法中设置了一顶点集合S,从源点s到集合中的顶点的最终最短路径的权值均已确定。算法反复选择具有最短
路径估计的顶点u∈V - S,并将u加入S中,对u的所有出边进行松弛,在下列算法实现中,用到了顶点的最小优先队列
Q,排序关键字为顶点的d值。d为实时权值。
代码如下:
#include<iostream>
#include<list>
using namespace std;
#define MAXVALUE 10000 //定义一个最长路径
//此处Dijkstra算法的图为有向图
struct Edge
{
int verno; //邻接数组中节点编号
int weight; //权值
Edge* next; //指向下一条边
};
struct Vertex
{
Edge *adj; //所指向的节点所在边
int verno; //邻接数组中节点编号
char key; //关键字
};
struct Graph
{
Vertex *vertexs; //节点数组
int vertexnum; //节点个数
int adjnum; //边数
};
class MSWDijkstra
{
public:
MSWDijkstra(char *vertex,int vernum,char adj[][2],int *weight,int adjnum);
void DijkstraInsert(int source,int dest,int weight);
int DijkstraFindKey(char key);
int DijkstraExtraMin(bool *visited,int length);
void DijkstraInitSingleSource();
void DijkstraMSW(char sourceKey);
void DijkstraOutput();
private:
int *shortway;
int *parent;
Graph *dijkstraGraph;
};
MSWDijkstra::MSWDijkstra(char *vertex,int vernum,char adj[][2],int *weight,int adjnum)
{
int i,source,dest;
shortway = new int[vernum];
parent = new int[vernum];
dijkstraGraph = new Graph;
dijkstraGraph->vertexs = new Vertex[vernum];
dijkstraGraph->adjnum = adjnum;
dijkstraGraph->vertexnum = vernum;
for(i = 0;i < vernum;i++)
{
dijkstraGraph->vertexs[i].key = vertex[i];
dijkstraGraph->vertexs[i].verno = i;
dijkstraGraph->vertexs[i].adj = NULL;
}
for(i = 0;i < adjnum;i++)
{
source = DijkstraFindKey(adj[i][0]);
dest = DijkstraFindKey(adj[i][1]);
DijkstraInsert(source,dest,weight[i]);
//DijkstraInsert(dest,source,weight[i]); //无向图与有向图的区别在此
}
}
void MSWDijkstra::DijkstraInsert(int source,int dest,int weight)
{
if(dijkstraGraph->vertexs[source].adj == NULL || dijkstraGraph->vertexs[source].adj->weight > weight)
{
Edge* newnode = new Edge;
newnode->verno = dest;
newnode->weight = weight;
newnode->next = dijkstraGraph->vertexs[source].adj;
dijkstraGraph->vertexs[source].adj = newnode;
}
else
{
Edge* temp = dijkstraGraph->vertexs[source].adj;
while(temp->next != NULL) //插入新边的时候,把权值从低到高进行排序
{
if(temp->next->weight > weight)
break;
temp = temp->next;
}
Edge* newnode = new Edge;
newnode->verno = dest;
newnode->weight = weight;
newnode->next = temp->next;
temp->next = newnode;
}
}
int MSWDijkstra::DijkstraFindKey(char key)
{
int i;
for(i = 0;i < dijkstraGraph->vertexnum;i++)
{
if(dijkstraGraph->vertexs[i].key == key)
break;
}
return i;
}
int MSWDijkstra::DijkstraExtraMin(bool *visited,int length)
{
int min = MAXVALUE;
for(int i = 0;i < length; i++)
{
if(!visited[i])
{
if(min != MAXVALUE && shortway[i] < shortway[min] || min == MAXVALUE)
min = i;
}
}
return min;
}
void MSWDijkstra::DijkstraInitSingleSource()
{
int vernum = dijkstraGraph->vertexnum;
for(int i = 0;i < vernum;i++)
{
shortway[i] = MAXVALUE;
parent[i] = i;
}
}
void MSWDijkstra::DijkstraMSW(char sourceKey)
{
int i;
int count = 1;
Edge* sourceEdge;
int vernum = dijkstraGraph->vertexnum;
int source = DijkstraFindKey(sourceKey);
bool *visited = new bool[vernum];
for(i = 0;i < vernum;i++)
{
visited[i] = false;
}
DijkstraInitSingleSource();
shortway[source] = 0;
while(count <= vernum)
{
i = DijkstraExtraMin(visited,vernum);
visited[i] = true;
count++;
sourceEdge = dijkstraGraph->vertexs[i].adj;
while(sourceEdge != NULL)
{
if((shortway[i] + sourceEdge->weight) < shortway[sourceEdge->verno])
{
parent[sourceEdge->verno] = i;
shortway[sourceEdge->verno] = shortway[i] + sourceEdge->weight;
}
sourceEdge = sourceEdge->next;
}
}
delete []visited;
}
void MSWDijkstra::DijkstraOutput()
{
int i,j,weight;
list<int> route;
cout<<"All the most shortest route from source : "<<endl;
for(i = 0;i < dijkstraGraph->vertexnum;i++)
{
j = i;
weight = shortway[j];
do
{
route.push_front(j);
j = parent[j];
}while(parent[j] != j);
cout<<dijkstraGraph->vertexs[j].key;
cout<<"---"<<dijkstraGraph->vertexs[route.front()].key;
route.pop_front();
while(!route.empty())
{
if(route.front() != j)
cout<<"---"<<dijkstraGraph->vertexs[route.front()].key;
route.pop_front();
}
cout<<" "<<weight<<endl;
}
}
int main()
{
char vertex[] = {'S','T','X','Y','Z'};
int vernum = 5;
char adj[][2] = {{'S','T'},{'S','Y'},{'T','X'},{'T','Y'},{'X','Z'},{'Y','T'},{'Y','X'},{'Y','Z'},{'Z','S'},{'Z','X'}};
int weight[] = {10,5,1,2,4,3,9,2,7,6};
int adjnum = 10;
MSWDijkstra *dijkstra = new MSWDijkstra(vertex,vernum,adj,weight,adjnum);
dijkstra->DijkstraMSW('S');
dijkstra->DijkstraOutput();
return 0;
}
结果如下:
All the most shortest route from source :
S---S 0
S---Y---T 8
S---Y---T---X 9
S---Y 5
S---Y---Z 7
请按任意键继续. . .