c++实现Dijkstra算法(最短路径)

#include<iostream>
#include<string>
using namespace std;

const int MAX = 10; //限定最大的顶点数
const int _INFINITY = 65535; //定义一个不可能输入的数字
class Graph
{
private:
	int vertex_num; //顶点数
	int edge_num; //边数
	int weight; //权值
	string vertex[MAX]; //顶点数组
	int edge[MAX][MAX]; //邻接矩阵
	int locate(string ch); //定位
	int *final; //标识是否已纳入最短路径,置为1表示纳入
	int *distance; //存放最短路径的权值和
	string *path;  //存放最短路径字符串

public:
	Graph(int v_n, int e_n); //构造函数
	void print_graph(); //打印邻接矩阵
	void Dijkstra(int v); //Dijkstra算法
	int Min(int *_distance, int num); //最小值
};

//定位(找到字母的下标)
int Graph::locate(string ch)
{
	int index;
	for (index = 0; index < this->vertex_num; index++)
	{
		if (this->vertex[index] == ch)
		{
			break;
		}
	}
	return index;
}

//构造函数
Graph::Graph(int v_n, int e_n) : vertex_num(v_n), edge_num(e_n)
{
	int i, j, k;
	cout << "现在请输入这" << this->vertex_num << "个顶点:" << endl;
	for (i = 0; i < this->vertex_num; i++)
	{
		cin >> this->vertex[i];
	}

	//初始化邻接矩阵
	for (i = 0; i < this->vertex_num; i++)
	{
		for (j = 0; j < this->vertex_num; j++)
		{
			if (i == j)
			{
				this->edge[i][j] = 0;
			}
			else
			{
				this->edge[i][j] = _INFINITY;
			}

		}
	}

	cout << "请依次输入边相邻的两个顶点及边的权值:" << endl;
	for (k = 0; k < this->edge_num; k++)
	{
		string first, second;
		cin >> first >> second >> this->weight;
		i = this->locate(first);
		j = this->locate(second);

		edge[i][j] = this->weight;
		//无向图
		edge[j][i] = this->weight;
	}
}

//打印
void Graph::print_graph()
{
	cout << "邻接矩阵为:" << endl;
	for (int i = 0; i < this->vertex_num; i++)
	{
		for (int j = 0; j < this->vertex_num; j++)
		{
			cout << this->edge[i][j] << "\t";
		}
		cout << endl;
	}
}

//返回最小值下标
int Graph::Min(int *_distance, int num)
{
	int index = 0, min = _INFINITY;
	for (int i = 0; i < num; i++)
	{
		if (!this->final[i] && _distance[i] < min)
		{
			min = _distance[i];
			index = i;
		}
	}
	return index;
}

//Dijkstra算法
void Graph::Dijkstra(int v)  //从源点v出发
{
	int i, j, min;
	this->path = new string[MAX];
	this->final = new int[MAX];
	this->distance = new int[MAX];
	//初始化上列数组
	for (i = 0; i < this->vertex_num; i++)
	{
		this->final[i] = 0;
		this->distance[i] = this->edge[v][i]; //初始化为源点到各t'hi点的权值大小
		if (this->distance[i] != _INFINITY)
		{
			this->path[i] = this->vertex[v] + this->vertex[i]; //当直接路径存在时,同样初始化为源点到各点的路径
		}
		else
		{
			this->path[i] = "";
		}
	}
	//初始化源点
	this->distance[v] = 0;
	this->final[v] = 1;

	//开始主循环,每次求得v到一个顶点的最短路径,所以循环次数比顶点数少一次
	for (i = 1; i < this->vertex_num; i++)
	{
		min = this->Min(distance, this->vertex_num); //求当前最小值下标
		cout << "最短路径:" << this->path[min] << "\t权值:" << this->distance[min] << endl; //输出当前最短路径
		this->final[min] = 1;
		//再次循环,修正当前最短路径及其权值和
		for (j = 0; j < this->vertex_num; j++)
		{
			//如果经过的顶点的路径比现在这条路径还短的话
			if (!this->final[j] && this->distance[j] > this->edge[min][j] + this->distance[min])
			{
				this->distance[j] = this->edge[min][j] + this->distance[min];
				this->path[j] = this->path[min] + this->vertex[j];
			}
		}
	}
	delete[]path;
	delete[]distance;
	delete[]final;
}



int main()
{
	int v = 0, e = 0;
	cout << "请依次输入图的顶点数和边数:" << endl;
	cin >> v >> e;

	Graph g(v, e);
	g.print_graph();
	g.Dijkstra(0);

	system("pause");
	return 0;
}

输出结果:
在这里插入图片描述
在这里插入图片描述

  • 12
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值