/* * shortpath.h */ #ifndef _SHORTPATH_H #define _SHORTPATH_H /* #define INFINITY ((1UL << 32) - 1) */ #define INFINITY 1000 #define VERTEX_NUM 6 /* 图的邻接矩阵 */ typedef struct _graph { char vexs[VERTEX_NUM]; /*顶点*/ int arcs[VERTEX_NUM][VERTEX_NUM]; /*邻接矩阵*/ int vexnum; /*顶点数*/ int arcnum; /*弧数*/ }graph; extern void sp_dijkstra(graph g, int v0, int p[VERTEX_NUM][VERTEX_NUM], int *d); extern void sp_dijstra_print(graph g, int v0, int p[VERTEX_NUM][VERTEX_NUM], int *d); extern void sp_floyd(graph g, int d[VERTEX_NUM][VERTEX_NUM]); extern void sp_floyd_print(graph g, int d[VERTEX_NUM][VERTEX_NUM]); #endif /* * dijkstra.c */ #include <stdio.h> #include "shortpath.h" /* * @g: 图的邻接矩阵 * @v0: 起始起点 * @p: p[v][w] 记录 v0 到 v 经过的第 w 个顶点 * @d: d[i]表示从 v0 到 i 的最短距离 */ void sp_dijstra_print(graph g, int v0, int p[VERTEX_NUM][VERTEX_NUM], int *d) { int v, j; for(v = 0; v < g.vexnum; ++v) { printf("%c -> %c 路径: ", g.vexs[v0], g.vexs[v]); for(j = 0; j < g.vexnum; ++j) { if(p[v][j] > -1) { if(j == 0) { printf("%c", g.vexs[p[v][j]]); } else { printf(" -> %c", g.vexs[p[v][j]]); } } else { break; } } printf("/t距离: %5d/n", d[v]); } } /* * func: 用迪杰斯特拉算法求解v0到其余个点的最短路径 * @g: 图的邻接矩阵 * @v0: 起始起点 * @p: p[v][w] 记录 v0 到 v 经过的第 w 个顶点 * @d: d[i]表示从 v0 到 i 的最短距离 */ void sp_dijkstra(graph g, int v0, int p[VERTEX_NUM][VERTEX_NUM], int *d) { int i, j; int v, w; int final[VERTEX_NUM]; /* final[v]=1 代表已经求出 v0 到 vi 的最短路径 */ int min; /* 初始化 p 和 d */ for(v = 0; v < g.vexnum; ++v) { final[v] = 0; d[v] = g.arcs[v0][v]; for(w = 0; w < g.vexnum; ++w) { p[v][w] = -1; } if(d[v] < INFINITY) { p[v][0] = v0; p[v][1] = v; } } final[v0] = 1; d[v0] = 0; v = v0; /* * 计算 v0 到其余各点的最短路径, 循环 vexnum-1 次 */ for(i = 1; i < g.vexnum; ++i) { min = INFINITY; for(w = 0; w < g.vexnum; ++w) { /* 寻找离 v0 最近的点 */ if(!final[w]) { if(d[w] < min) { min = d[w]; v = w; } } } if(v != v0) { /* 找到离 v0 最近的点 */ final[v] = 1; /* 更新 v0 到 final[w]=0 的各点的最短路径 */ for(w = 0; w < g.vexnum; ++w) { if(!final[w] && (min + g.arcs[v][w]) < d[w]) { d[w] = min + g.arcs[v][w]; for(j = 0; j < g.vexnum; ++j) { if(p[v][j] > -1) { p[w][j] = p[v][j]; /* 借助最短路径到达w点 */ } else { break; } } p[w][j] = w; /* 经过w点 */ } } } else { /* 路径不可达 */ break; } } } /* * floyd.c */ #include <stdio.h> #include "shortpath.h" void sp_floyd_print(graph g, int d[VERTEX_NUM][VERTEX_NUM]) { int v, w; for(v = 0; v < g.vexnum; ++v) { for(w = 0; w < g.vexnum; ++w) { printf("%c -> %c 距离: ", g.vexs[v], g.vexs[w]); if(d[v][w] != INFINITY) { printf("%d/n", d[v][w]); } else { printf("INFINITY/n"); } } } } /* 最短路径的floyd算法实现 */ void sp_floyd(graph g, int d[VERTEX_NUM][VERTEX_NUM]) { int u, v, w; for(v = 0; v < g.vexnum; ++v) { for(w = 0; w < g.vexnum; ++w) { d[v][w] = g.arcs[v][w]; } } for(u = 0; u < g.vexnum; ++u) { for(v = 0; v < g.vexnum; ++v) { for(w = 0; w < g.vexnum; ++w) { if(d[v][u] + d[u][w] < d[v][w]) { d[v][w] = d[v][u] + d[u][w]; } } } } } #include <stdio.h> #include <stdlib.h> #include "shortpath.h" int main(int argc, char *argv[]) { int i, j; graph g; /* for dijstra */ int v0; int path[VERTEX_NUM][VERTEX_NUM]; int d[VERTEX_NUM]; /* for floyd */ int ddd[VERTEX_NUM][VERTEX_NUM]; /* dijstra 算法 */ /* 初始化图g */ g.vexs[0]='A',g.vexs[1]='B',g.vexs[2]='C',g.vexs[3]='D',g.vexs[4]='E',g.vexs[5]='F'; for(i = 0; i < VERTEX_NUM; ++i) { for(j = 0; j < VERTEX_NUM; ++j) { g.arcs[i][j] = INFINITY; } } g.arcs[0][2]=10,g.arcs[0][4]=30,g.arcs[0][5]=100,g.arcs[1][2]=5, g.arcs[2][3]=50,g.arcs[3][5]=10,g.arcs[4][3]=20,g.arcs[4][5]=60; g.vexnum = VERTEX_NUM; g.arcnum = VERTEX_NUM; /* 输出图的有关信息 */ for(i=0;i<VERTEX_NUM;i++) { printf("%c/t",g.vexs[i]); for(j=0;j<VERTEX_NUM;j++) { printf("%5d ",g.arcs[i][j]); } printf("/n"); } printf("/n"); /* 求最短路径 */ v0 = 0; sp_dijkstra(g, v0 , path, d); /* 输出 v0 到各点的最短路径 */ sp_dijstra_print(g, v0 , path, d); printf("/n"); /* floyd 算法 */ /* 初始化图g */ g.vexs[0]='A',g.vexs[1]='B',g.vexs[2]='C',g.vexs[3]='D',g.vexs[4]='E',g.vexs[5]='F'; for(i = 0; i < VERTEX_NUM; ++i) { for(j = 0; j < VERTEX_NUM; ++j) { g.arcs[i][j] = INFINITY; } } g.arcs[0][2]=10,g.arcs[0][4]=30,g.arcs[0][5]=100,g.arcs[1][2]=5, g.arcs[2][3]=50,g.arcs[3][5]=10,g.arcs[4][3]=20,g.arcs[4][5]=60; g.vexnum = VERTEX_NUM; g.arcnum = VERTEX_NUM; /* 输出图的有关信息 */ for(i=0;i<VERTEX_NUM;i++) { printf("%c/t",g.vexs[i]); for(j=0;j<VERTEX_NUM;j++) { printf("%5d ",g.arcs[i][j]); } printf("/n"); } printf("/n"); /* 求最短路径 */ sp_floyd(g, ddd); /* 输出任意两点最短路径 */ sp_floyd_print(g, ddd); system("pause"); return 0; }