问题:
利用Dijkstra算法求从顶点0到其他各顶点间的最短路径,要求写出执行算法过程中辅助数组的每一步变化。
邻接矩阵存图实现的Dijkstra代码:
graph.h:
#include <iostream>
#include <iomanip>
#include <stack>
using namespace std;
#define MAXWEIGHT 100
#define INFINITY 1000
class Graph
{
private:
int numV;
int numE;
int **matrix;
public:
Graph(int numV);
void createGraph(int numE);
~Graph();
void Dijkstra(int vertex);
void Display();
bool check(int tail,int head,int weight);
};
Graph::Graph(int numV)
{
while(numV<=0)
{
cout << "FALSE INPUT!" << endl;
cin >> numV;
}
this->numV = numV;
matrix =new int*[numV];
for(int i =0;i<numV;i++)
matrix[i] = new int[numV];//动态分配空间
for(int i=0;i<numV;i++)//邻接矩阵初始化
for(int j=0;j<numV;j++)
{
if(i==j)
matrix[i][j]=0;
else
matrix[i][j]=INFINITY;
}
}
/*void Graph::createGraph(int numE)
{
while(numE<0 || numE> numV*(numV - 1))
{
cout << "FALSE INPUT!" << endl;
cin >> numE;
}
this->numE = numE;
int tail,head,weight;
int i=0;
cout << "input your tail,head,weight:" << endl;
while(i<numE)
{
cin >> tail >> head >> weight;
while(!check(tail,head,weight))
{
cout << "FALSE INPUT" << endl;
cin >> tail >> head >> weight;
}
matrix[tail][head] = weight;
i++;
}
}*/
void Graph::createGraph(int numE)
{
while(numE<0 || numE> numV*(numV - 1))
{
cout << "FALSE INPUT!" << endl;
cin >> numE;
}
this->numE = numE;
matrix[0][1]=45;
matrix[0][2]=50;
matrix[0][3]=15;
matrix[1][2]=5;
matrix[1][4]=20;
matrix[1][5]=15;
matrix[3][0]=10;
matrix[3][1]=10;
matrix[3][4]=79;
matrix[4][1]=30;
matrix[5][4]=20;
}
Graph::~Graph()
{
int i;
for(i = 0;i<numV;i++)
delete[] matrix[i];
delete[] matrix;
}
void Graph::Display()
{
cout.setf(ios::left);
cout << setw(7) << "";
for(int i = 0;i<numV;i++)
cout << setw(7) << i;
cout << endl;
for(int i = 0;i<numV;i++)
{
cout << setw(7) << i;
for(int j=0;j<numV;j++)
{
cout << setw(7) ;
if(matrix[i][j]==INFINITY)
cout << "--";
else
cout << matrix[i][j];
}
cout << endl;
}
}
bool Graph::check(int tail,int head,int weight)
{
if(tail<0 || tail>=numV || head <0 || head>=numV || weight <=0 || weight >= MAXWEIGHT)
return false;
return true;
}
void Graph::Dijkstra(int vertex)
{
int *path = new int[numV];
for(int i=0;i<numV;i++)
path[i]=vertex;
int *Distance = new int[numV];
for(int i=0;i<numV;i++)
Distance[i] = matrix[vertex][i];
bool *find = new bool[numV];
memset(find,0,numV);
find[vertex] = true;
int d,v,count;
count =1;
v = vertex;
while(count < numV)//遍历n-1次
{
d = INFINITY;
for(int i=0;i<numV;i++)//寻找当前最短的距离
if(!find[i] && Distance[i] < d)
{
d = Distance[i];
v = i;
}
find[v] = true;//将点并入
for(int i=0;i<numV;i++)//更新其他点的距离值
if(!find[i])
{
d = Distance[v]+matrix[v][i];
if( d < Distance[i])
{
Distance[i] = d;;
path[i] = v;
}
}
count++;
}
//利用栈先进后出的特性打印路径
stack<int> s;
for(int i=0;i<numV;i++)
{
if(Distance[i]==0);
else if(Distance[i]==INFINITY)
cout << "No Edge." << endl;
else
{
cout << vertex << " to " << i << "'s Distance:" << Distance[i] << " , way: ";
v = i;
s.push(v);
do{
v = path[v];
s.push(v);
}while(v != vertex);
while(!s.empty())
{
cout << setw(3) << s.top();
s.pop();
}
cout << endl;
}
}
cout << endl;
delete[]find;
delete[]path;
delete[]Distance;
}
main.cpp:
#include "Graph.h"
int main()
{
cout << "Dijkstra" << endl;
int numV,numE;
/*cout << "Input numVex:" << endl;
cin >> numV;
Graph graph(numV);
cout << "Input numEdge:" << endl;
cin >> numE;
graph.createGraph(numE);*/
numV = 6;
numE = 11;
Graph graph(numV);
graph.createGraph(numE);
graph.Display();
cout << endl << "Dijkstra.." << endl;
graph.Dijkstra(0);
return 0;
}
程序执行: