C++版Dijkstra最短路径算法
/
//file:ShortestPath.h
#ifndef _SHORTESTPATH_H_
#define _SHORTESTPATH_H_
#define MAX_NODES 100
#define INFINITY 100
#include <iostream>
using namespace std;
class Vertex { //顶点类
public:
Vertex(int i = -1) {
id = i; //顶点标号 初始化为-1
known = false; //打圈的标记 初始化为false
dist = INFINITY; //距离 初始化为正无穷
pred = -1; //顶点的前一个点 初始化为-1
}
int id;
bool known;
int dist;
int pred;
};
class Path { //路径类
public:
Path() {
_start = MAX_NODES; //开始下标 初始化为MAX_NODES
for(int i = 0; i < MAX_NODES; i++)
_path[i] = -1; //初始路径初始化为-1
}
int in_path(int item) { //写入一个路径顶点
_start--;
_path[_start] = item;
return 0;
}
int de_path(int& item) { //输出一个路径顶点
item = _path[_start];
_start++;
return 0;
}
bool is_empty() const{
if(_start == MAX_NODES) return true;
else return false;
}
private:
int _start;
int _path[MAX_NODES];
};
class Graph { //图类
public:
Graph() {
_num_nodes = 0; //初始化顶点数为0 权值矩阵均为正无穷
for(int i = 0; i < MAX_NODES; i ++)
for(int j = 0; j < MAX_NODES; j ++)
_weight[i][j] = INFINITY;
}
int build(string ifile); //从文件中读取数据建立图
Path shortest_path(int S, int T); //计算从S到T的最短路径
private:
int _num_nodes; //顶点总数
Vertex Vex[MAX_NODES]; //顶点的集合
int _weight[MAX_NODES][MAX_NODES]; //权值矩阵
};
#endif
//
//file:ShortestPath.cpp
#include "ShortestPath.h"
#include <fstream>
int Graph::build(string ifile) { //从文件数据中创建图
int i = 0;
int j = 0;
ifstream infile(ifile.c_str());
if(!infile) {
cout << "Error: Unable to open the input file!" << ifile.c_str() << endl;
exit(-1);
}
infile >> _num_nodes; //读取节点总数
while(infile >> i) {
if(i >= _num_nodes) {
cout << "The node does not exist!" << endl;
exit(-1);
}
infile >> j;
if(j >= _num_nodes) {
cout << "The node does not exist!" << endl;
exit(-1);
}
infile >> _weight[i][j]; //读取权值
}
infile.close();
for(int i = 0; i < _num_nodes; i++) { //建立顶点
Vex[i] = Vertex(i);
}
return 0;
}
Path Graph::shortest_path(int S, int T) { //求从S到T的最短路径
Path path;
int next = -1;
if(_num_nodes == 0) { //判空
cout << "The graph is empty!" << endl;
exit(-1);
}
if(S < 0 || T < 0 || S >= _num_nodes || T >= _num_nodes) { //检查节点是否存在
cout << "Node S or T does not exist!" << endl;
exit(-1);
}
int current = S;
Vex[S].dist = 0;
while(Vex[T].known == false) {
int smallest_d = INFINITY;
for(int i = 0; i < _num_nodes; i++) {
if(Vex[i].known == false) {
if(Vex[current].dist + _weight[current][i] < Vex[i].dist) {
Vex[i].dist = Vex[current].dist + _weight[current][i];
Vex[i].pred = current;
}
if(Vex[i].dist < smallest_d) {
smallest_d = Vex[i].dist;
next = i;
}
}
}
current = next;
Vex[current].known =true;
}
path.in_path(T); //将路径存入path
current = T;
while(current != S) {
path.in_path(Vex[current].pred);
current = Vex[current].pred;
}
return path;
}
//
//file:main.cpp
#include "ShortestPath.h"
ostream& operator<<(ostream& out, Path& path) { //重载输出运算符
int item = -1;
while(!path.is_empty()) {
path.de_path(item);
out << "-->" << item;
}
return out;
}
int main() {
int S = 0;
int T = 6;
string file_name = "data.txt";
Graph G;
G.build(file_name);
Path path;
path = G.shortest_path(S, T);
cout << path;
return 0;
}