例如有向图图:
用邻接矩阵存储该有向图:
迪杰斯特拉算法其步骤为:
实现代码如下:
#include<stdio.h>
#include<stdbool.h>
#define MNUM 10
typedef struct
{
int vexs[MNUM]; //这里把数字作为顶点的代表 如果是字母可以为char vexs[MNUM];
int arcs[MNUM][MNUM];
int vexnum, arcnum;
}Graph;
void Creat_graph(Graph * G)
{
int i, j, m, n, q;
scanf("%d %d", &G->vexnum, &G->arcnum);
for(i = 0; i < G->vexnum; i++){
G->vexs[i] = i;
}
for(i = 0; i < G->vexnum; i++){
for(j = 0; j < G->vexnum; j++){
if(i == j)
G->arcs[i][j] = 0;
else
G->arcs[i][j] = 99;
}
}
for(i = 0; i < G->arcnum; i++){
scanf("%d %d %d", &m, &n, &q);
G->arcs[m][n] = q;
//G->arcs[n][m] = q; //建立无向图
}
}
void ShortestPath_Dijkstra(Graph G, int v0)
{
int n, v, j, i, min;
n = G.vexnum; //让n为G中顶点的个数
bool Mark[n];
int Lowcost[n], Front[n]; //Path存前驱 D存权值
for(v = 0; v < n; v++){ //n个顶点依次初始话
Mark[v] = false;
Lowcost[v] = G.arcs[v0][v]; //将v0到各个中终点的最短路径长度设置为 v 与 v0上的权值
if(Lowcost[v] < 99)
Front[v] = v0; //如果说v与v0之间有弧,则把v的前驱设置为v0
else
Front[v] = -1; //如果v与v0之间没有弧相连,则把v的前驱用-1标注下来。
}
Mark[v0] = true;
printf("%d ", v0);
/*初始化结束,开始主循环,每次求得V0到某个顶点的最短路径,将v加到s*/
for(i = 1; i < n; i++){
min = 99;
for(j = 0; j < n; j++){
if(!Mark[j] && Lowcost[j] < min){
min = Lowcost[j];
v = j; //选择当前一个最短路径用v标记下来
}
}
Mark[v] = true;
printf("%d ", v);
for(j = 0; j < n; j++){ //更新从v0出发到集合V-S上所有顶点的最短路径长度
if(!Mark[j] && (Lowcost[v] + G.arcs[v][j] < Lowcost[j])){
Lowcost[j] = Lowcost[v] + G.arcs[v][j]; //更新D[j],保证目前最短
Front[j] = v; //更新前驱
}
}
}
}
int main()
{
Graph G;
Creat_graph(&G);
int i, j;
for(i = 0; i < G.vexnum; i++){
for(j = 0; j < G.vexnum; j++){
if(G.arcs[i][j] < 10)
printf("%d ", G.arcs[i][j]);
else
printf("%d ", G.arcs[i][j]);
}
putchar('\n');
} //输出
//MiniSpanTree_Kruskal(G);
ShortestPath_Dijkstra(G, 0);
return 0;
}
运行结果如下: