迪杰斯特拉(Dijkstra)算法

时间:2022-05-13 22:36:43

迪杰斯特拉(Dijkstra)算法

 # include <stdio.h>

 # define MAX_VERTEXES //最大顶点数
# define INFINITY ;//代表∞ typedef struct
{/* 无向图结构体 */
int vexs[MAX_VERTEXES];//顶点下标
int arc[MAX_VERTEXES][MAX_VERTEXES];//矩阵
int numVertexes, numEdges;//顶点数和边数 }MGraph; typedef int PathArc[MAX_VERTEXES];//存储最短路径的下表数组
typedef int ShortPathTable[MAX_VERTEXES];//存储最短路径的权值数组 void CreateMGraph (MGraph *G)
{/* 创建 */
int i, j; //printf ("请输入顶点数和边数");
G->numVertexes = ;//顶点
G->numEdges = ;//边 for (i=; i<G->numVertexes; i++)
G->vexs[i] = i;//初始化顶点下标 for (i=; i<G->numVertexes; i++)//初始化矩阵
for (j=; j<G->numVertexes; j++)
if (i == j)
G->arc[i][j] = ;//本身则0
else
G->arc[i][j] = INFINITY;//否则为∞ //提前手动输入
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=;
G->arc[][]=; G->arc[][]=; for (i=; i<G->numVertexes; i++)//无向图--矩阵上三角对称下三角
for (j=i; j<G->numVertexes; j++)
if (i != j)
G->arc[j][i] = G->arc[i][j]; return ; } //P数组-存放最短路径顶点的下标,D数组-存放最短路径(权值)
void Shorsequence_Path_Dijkstra (MGraph G, int v0, PathArc *P, ShortPathTable *D)
{/* 迪杰斯特拉 算法 - 生成最短路径 */
int v, w, k, min;
int final[MAX_VERTEXES]; //final[w] = 1,表示求得顶点v0→vw的最短路径 for (v=; v<G.numVertexes; v++)
{//初始化
final[v] = ; //全部顶点初始化为未知最短路径状态
(*D)[v] = G.arc[v0][v]; //和v0有连线的点加上权值
(*P)[v] = -; //初始化路径下标数组初始值为-1;
} (*D)[v0] = ; //v0→v0的路径-权值-为0
final[v0] = ; //v0→v0不需要求路径 /* 开始主循环,每次循环求v0到某个v顶点的最短路径 */
for (v=; v<G.numVertexes; v++)
{
min = INFINITY; //初始化-目前所知离v0顶点的最近距离 //注意:这里不要想着w=v;因为程序执行的时候有的顶点不符合是直接跨过去了,然后置0是为了循环访问未访问的顶点
for (w=; w<G.numVertexes; w++)//查找和v0最近的顶点
if (!final[w] && (*D)[w]<min)
{//该顶点未被访问过,并且小于min
k = w; //k存入最近顶点的下标
min = (*D)[w]; //min存入最短路径
} final[k] = ; //将目前找到最近的顶点-做标记 for (w=; w<G.numVertexes; w++)//目前找到与v0最近的顶点下标k,然后继续寻找与k顶点最近的下标
if (!final[w] && (min+G.arc[k][w] < (*D)[w]))
{//若顶点未被访问 并且 (目前最短路径(权值)v0→k + 目前最近的顶点(k)有关联的顶点路径(权值))小于 v0有关联的权路径(权值)
(*D)[w] = min + G.arc[k][w];//则与k顶点相关的权值+min--覆盖D数组
(*P)[w] = k; //则与v0最近的顶点k顶点下标 给 P数组;
}//(*D)[w] = min实际上就是上一个顶点和k顶点最短路径的 + arc[k][w]
} return ;
} int main (void) {
int i, j, v0;
int number = ;
int sequence[MAX_VERTEXES][MAX_VERTEXES];
MGraph G;
PathArc P;
ShortPathTable D; //某点到各点的最短路径
v0 = ; CreateMGraph (&G); //创建 Shorsequence_Path_Dijkstra (G, v0, &P, &D);//迪杰斯特拉 算法 - 生成最短路径 //初始化正序输出的数组
for (i=; i<G.numVertexes; i++)
for (j=; j<G.numVertexes; j++)
sequence[i][j] = ; /* P数组-存放最短路径顶点的下标,D数组-存放最短路径(权值) */ printf ("最短路径倒序如下:\n");
for (i=; i<G.numVertexes; i++)
{
printf ("v%d--v%d\t: ", v0, i);
j = i;
while (P[j] != -)
{//若存在下一个顶点
printf ("%d ", P[j]);//则输出顶点
j = P[j];//按顺序查找
number ++;//记录(辅助正序输出)
} //离上一个顶点最近的顶点的下标-赋值给sequence数组
j = i;
while (<number && P[j] != -)
{
sequence[i][number--] = P[j];
j = P[j];
}
number = ;
printf ("\n");
} //自己修改的
printf ("\n最短路径正序如下:\n");
for (i=; i<G.numVertexes; i++)
{
j = ;
printf ("v%d--v%d\t: ", v0, i);
while (sequence[i][j] != )
printf ("%d ", sequence[i][j++]);
printf ("\n");
} printf ("\n源点到各个点的最短路径为:\n");
for (i=; i<G.numVertexes; i++)
printf ("v%d--v%d : %d\n", G.vexs[], G.vexs[i], D[i]); return ;
}