最短路径有两种算法:Dijkstra(迪杰斯特拉算法)和Floyd(佛洛伊德)算法
Dijkstra算法:类似于Prim算法,通过在已经遍历到的边中寻找到最小值,不同的是Prim算法寻找的是边权值最小的值,Dijkstra算法找的是权值和最小的值。
Floyd算法:通过遍历整个结点,循环寻找每个
顶点到每个顶点的最小权值。
首选:Dijkstra算法,当需要求每个顶点到每个顶点的最短路径时,Floyd算法可以考虑。
#include <stdio.h>
#include <string.h>
#define MAXVALUE 50
#define INITVALUE 65535
#define INITPOS 0
typedef struct
{
char Vex[MAXVALUE];
int Arch[MAXVALUE][MAXVALUE];
int numVexs, numArch;
}Graph;
void CreatGraph (Graph *G)
{
int i, j, k, weight;
printf("Enter numVexs && numArch:");
scanf("%d%d", &(G->numVexs), &(G->numArch));
for(i = 0; i < G->numVexs; i++) // 邻接矩阵初始化
{
for(j = 0; j < G->numVexs; j++)
{
G->Arch[i][j] = INITVALUE;
}
}
for(k = 0; k < G->numVexs; k++)
{
printf("Enter %d vex:", k);
scanf("%c", &(G->Vex[k]));
getchar();
}
for(k = 0; k < G->numArch; k++)
{
printf("Enter i, j, &weight:");
scanf("%d%d%d", &i, &j, &weight);
G->Arch[i][j] = weight;
G->Arch[j][i] = weight;
}
}
void PrintGraph (Graph G)
{
int i, j;
for(i = 0; i < G.numVexs; i++)
{
for(j = 0; j < G.numVexs; j++)
{
printf("%d ", G.Arch[i][j]);
}
printf("\n");
}
}
void ShortestPath_Dijkstra (Graph G, int *P, int *D) //P中存储着前驱顶点坐标,D总存储着路径长度
{
int i, min, j, k;
int final[MAXVALUE];
P[INITPOS] = 0;
D[INITPOS] = 0;
final[INITPOS] = 1;
for(i = 1; i < G.numVexs; i++)
{
P[i] = INITPOS; //可以根据算法要求到不同起始点的距离变化
D[i] = G.Arch[INITPOS][i];
final[i] = 0;
}
for(i = 0; i < G.numVexs; i++)
{
min = INITVALUE;
j = 1;
while(j < G.numVexs)
{
if(!final[j] && D[j] < min )
{
min = D[j];
k = j;
}
j++;
}
final[k] = 1;
for(j = 0; j < G.numVexs; j++)
{
if(!final[j] && D[j] > min + G.Arch[k][j]) //当遍历到比当前路径小的路径时进行替换
{
D[j] = min+G.Arch[k][j];
P[j] = k;
}
}
}
}
void PrintShortestPath_Dijkstra (Graph G, int *P, int *D) //打印出有Dijkstra算法计算出的最短路径
{
int i, p;
for(i = 0; i < G.numVexs; i++) //打印出路径信息
{
printf("(%d ", i);
p = P[i];
while(p)
{
printf("%d ", p);
p = P[p];
}
printf("%d)%d\n", p, D[i]);
}
}
void ShortestPath_Floyd (Graph G, int P[MAXVALUE][MAXVALUE], int D[MAXVALUE][MAXVALUE])
{
int i, j, k;
for(i = 0; i < G.numVexs; i++)
{
for(j = 0; j < G.numVexs; j++)
{
D[i][j] = G.Arch[i][j];
P[i][j] = j;
}
}
for(i = 0; i < G.numVexs; i++)
{
for(j = 0; j < G.numVexs; j++)
{
for(k = 0; k < G.numVexs; k++)
{
if(G.Arch[j][k] > G.Arch[j][i] + G.Arch[i][k])
{
G.Arch[j][k] = G.Arch[j][i] + G.Arch[i][k];
P[j][k] = P[j][i];
}
}
}
}
}
void PrintShortestPath_Floyd (Graph G, int P[MAXVALUE][MAXVALUE], int D[MAXVALUE][MAXVALUE]) //打印出有Floyd
{
int i, j, p;
for(i = 0; i < G.numVexs; i++)
{
for(j = i+1; j < G.numVexs; j++)
{
printf("(%d ", i);
p = P[i][j];
while(p != j)
{
printf("%d ", p);
p = P[p][j];
}
printf("%d)%d\n", p, D[i][j]);
}
}
}
int main ()
{
Graph G;
int P1[MAXVALUE], D1[MAXVALUE];
int P2[MAXVALUE][MAXVALUE], D2[MAXVALUE][MAXVALUE];
CreatGraph(&G);
PrintGraph(G);
ShortestPath_Dijkstra(G, P1, D1);
PrintShortestPath_Dijkstra(G, P1, D1);
ShortestPath_Floyd(G, P1, D2);
PrintShortestPath_Floyd(G, P1, D2);
return 0;
}