データ構造の最短パスとは、ネットワークグラフの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]の意味を理解する必要があります。
前者の最終結果は、配列の添え字とソースポイントの間の距離です。ポイントとポイントの間の距離は、ソースポイントを含む距離
後者は
手のアニメーションに似ています理解を深めることができます