データ構造-グラフの最短経路のダイクストラアルゴリズムの理解と実装

データ構造の最短パスとは、ネットワークグラフの2つのノード間のエッジの重みの合計が最小のパスを指します。

ダイクストラのアルゴリズムの理解

以前の最小全域木と類似点があります。
原点から終点まで、
ソースポイントV0から開始し、
3つの配列
final [MAX]定義します。判断のために0に初期化されます。

ShortPathTable [MAX]:重みの合計を格納するために使用されます(配列の添え字に従って)。
ループされるたびに更新されます。これは、現在のノードの位置と次のノードの重み、および最小パスに基づいています。前回見つかりました。値の合計の
更新された部分minは次のとおりです:たとえば、V0からV8ノードに移動します。間にV5ノードがあり、minはV0からV5への最小パスです。その後、SPT配列の要素は、V5 + minに関連するエッジの重みに更新されます。

Patharc [MAX]:配列の添え字位置の前のノードレコードの最短パスを格納します

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

typedef char Vertextype;//顶点类型
typedef int Edgetype;//边缘权值
typedef int Status;
#define MAXVER 9//最大顶点数
#define INF 65535//代表无穷
#define NULL 0


//定义Dijktre算法的相关数组
typedef int Patharc[MAXVER];//存储最短路径数组下标
typedef int ShortPathTable[MAXVER];//用于存储路径之间的权值最小和

//定义图——邻接矩阵
typedef struct Graph
{
    
    
	Vertextype Ver[MAXVER];
	Edgetype Arc[MAXVER][MAXVER];
	int NumVer, NumEdg;
}MGraph;

//生成图——邻接矩阵
Status CreatGraph(MGraph &G)
{
    
    
	int i, j, w;
	cout << "Please enter the number of verticesof the graph : " << endl;
	cin >> G.NumVer;
	cout << "Please enter the number of edges the graph : " << endl;
	cin >> G.NumEdg;
	cout << "Please enter the name of vex : " << endl;
	for (i = 0; i < G.NumVer; i++){
    
    
		//cout << "Please enter the NO." << i + 1 << "%d name of vex : " << endl;
		cin >> G.Ver[i];
	}

	cout << "Diagonal infinity ..." << endl;
	for (i = 0; i < G.NumVer; i++)
		for (j = 0; j < G.NumVer; j++)
		{
    
    
		G.Arc[i][j] = INF;//简单图  不循环
		//cout << G.arc[i][j] << endl;//不理解为啥是1
		}
	cout << "...Diagonal infinity" << endl;

	for (int k = 0; k < G.NumEdg; k++){
    
    //因为具体哪条边存在不一定 所以选择性输入边
		cout << "Enter the subscripts and weights from vertex vi to vertex vj : " << endl;
		cin >> i >> j >> w;
		/*cout << "Please enter the subscript j of the edge : " << endl;
		cin >> j;
		cout << "Please enter the weight from vertex "<<i<<" to vertex "<<j<<" : " << endl;
		cin >> w;*/

		G.Arc[i][j] = w;
		G.Arc[j][i] = G.Arc[i][j];//无向图  边的信息  是对称的  //有向图的话 无需设置

	}
	return 0;
}

Status Shortpath_Dijkstra(MGraph &G, int V0, Patharc &P, ShortPathTable &D)
{
    
    
	int v, w, k, min;
	int final[MAXVER];

	//初始化过程
	//final数组为判决数组 初始化为0  若走过 则改 1    原始位置为1
	//Patharc数组记录最小路径的位置 (下标对应 该位置的上一结点)
	//ShortPathTable数组 记录两个结点之间最小路径的权值之和   会根据结点所在位置不断更新
	for (v = 0; v < G.NumVer; v++)
	{
    
    
		final[v] = 0;
		(D)[v] = G.Arc[V0][v];
		(P)[v] = 0;
	}
	(D)[V0] = 0;
	final[V0] = 1;

	//一个一个的开始找
	for (v = 1; v < G.NumVer; v++)
	{
    
    
		min = INF;//找出某结点边的最小权值   初始化为一个最大值

		//寻找出某结点边权值的最小个   且包括源点到它的总权值
		for (w = 0; w < G.NumVer; w++)
		{
    
    
			if (!final[w] && (D)[w] < min)
			{
    
    
				k = w;
				min = (D)[w];
			}
		}

		//当找出了某结点的最小权值之和
		final[k] = 1;//标记此结点

		for (w = 0; w < G.NumVer; w++)
		{
    
    
			if (!final[w] && min + G.Arc[k][w] < D[w])//判断结点是否走过  和  选择相关边
			{
    
    
				//从某点  找到  该点 最小权值对应结点K   然后将D  P 更新  分别保存D为对应w位置值为前min+对应点边值p记录位置
				(D)[w] = min + G.Arc[k][w];
				(P)[w] = k;
			}
		}

	}
	return 0;
}

Status DispPath(Patharc &P, ShortPathTable &D)
{
    
    
	for (int i = 0; i < MAXVER; i++)
	{
    
    
		cout << P[i] << endl;
	}

	for (int i = 0; i < MAXVER; i++)
	{
    
    
		cout << D[i] << endl;
	}
	return 0;
}

int main()
{
    
    
	MGraph G;
	Patharc P;
	ShortPathTable D;
	
	CreatGraph(G);
	int V = 0;
	Shortpath_Dijkstra(G, V, P, D);
	DispPath(P,D);
	system("pause");
	return 0;

}

ここで、Patharc [MAXVER]とShortPathTable [MAXVER]の意味を理解する必要があります。
前者最終結果は、配列の添え字とソースポイントの間の距離です。ポイントとポイントの間の距離は、ソースポイントを含む距離
後者は
手のアニメーションに似ています理解を深めることができます

おすすめ

転載: blog.csdn.net/weixin_46096297/article/details/113697887