例如有向图图:
用邻接矩阵存储该有向图:
迪杰斯特拉算法其步骤为:
实现代码如下:
#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; }
运行结果如下: