Dijkstra[狄克斯特拉] 算法 C语言实现
Dijkstra 求最短路径算法,从一堆点{0,1,2,3,4,5}里选择一点0,然后求从0到{1,2,3,4,5}的最短距离,因为只有一个起点,所以也称为单源最短路径算法。
下面是图示例:
步骤如下:
1.取距离起点最近的点且未处理过。若没有,则结束
2.分别逐个计算以该点为起点的所有点的距离+起点到该点的距离 是否小于 起点到该相邻点的距离, 若小于则更新该相邻到到起点的距离
3.将该点置为已处理状态
4.重复1.2.3
下面是C语言 利用数组简单实现
1 #include2 #include 3 #include 4 #if linux 5 #include 6 #endif 7 8 #define INT_MAX 0x80000000 // 代表无穷大 9 #define POINT_NUM 6 //点数量 10 #define SIDE_NUM 9 //边数量 11 12 typedef struct __graph 13 { 14 unsigned v_to_other[POINT_NUM]; // 记录从0顶点到各个顶点间的最小权重 15 unsigned sides[POINT_NUM][POINT_NUM]; // 边权重集合 16 unsigned char processed[POINT_NUM]; // 处理过的顶点 处理过为1 否则为0 17 }GRAPH, *PGRAPH; 18 19 void InitGraph(PGRAPH pgraph) 20 { 21 // 初始化 0 到 各个顶点的最短距离 22 for (size_t i = 0; i < POINT_NUM; i++) 23 { 24 pgraph->v_to_other[i] = INT_MAX; 25 } 26 27 // 已知 0->0 距离为0 28 pgraph->v_to_other[0] = 0; 29 pgraph->v_to_other[1] = 1; 30 pgraph->v_to_other[2] = 2; 31 pgraph->v_to_other[3] = 3; 32 33 // 初始化各个边的距离 34 for (size_t i = 0; i < POINT_NUM; i++) 35 { 36 for (size_t j = 0; j < POINT_NUM; j++) 37 { 38 if(i == j) 39 { 40 pgraph->sides[i][j] = 0; 41 } else { 42 pgraph->sides[i][j] = INT_MAX; 43 } 44 } 45 } 46 // 已知各个边的距离 47 pgraph->sides[0][1] = 1; 48 pgraph->sides[0][2] = 2; 49 pgraph->sides[0][3] = 3; 50 pgraph->sides[1][3] = 1; 51 pgraph->sides[1][4] = 4; 52 pgraph->sides[2][3] = 4; 53 pgraph->sides[3][4] = 2; 54 pgraph->sides[3][5] = 4; 55 pgraph->sides[4][5] = 1; 56 57 memset(pgraph->processed, 0, POINT_NUM); 58 pgraph->processed[0] = 1; 59 } 60 61 // 获取距离起点最短的点的索引 62 bool GetMinVToOther(PGRAPH pgraph, size_t *vindex) 63 { 64 unsigned min_v_to_other = INT_MAX; 65 for (size_t i = 0; i < POINT_NUM; i++) 66 { 67 if(!pgraph->processed[i] && pgraph->v_to_other[i] < min_v_to_other) 68 { 69 min_v_to_other = pgraph->v_to_other[i]; 70 *vindex = i; 71 } 72 } 73 return min_v_to_other != INT_MAX; 74 } 75 76 void Dijkstra(PGRAPH pgraph) 77 { 78 size_t vindex = 0; 79 while (GetMinVToOther(pgraph, &vindex)) 80 { 81 for (size_t i = 0; i < POINT_NUM; i++) 82 { 83 if(pgraph->sides[vindex][i] != INT_MAX) 84 { 85 // 距离0的 j点最短距离 = i点最短距离 + i->j距离 86 unsigned distance = pgraph->v_to_other[vindex] + pgraph->sides[vindex][i]; 87 // 如果从0->i->j的这条线段距离 比已知 0->j 的距离短的话,则更新0->j最短距离 88 if(distance < pgraph->v_to_other[i]) 89 { 90 pgraph->v_to_other[i] = distance; 91 } 92 } 93 } 94 pgraph->processed[vindex] = 1; 95 } 96 97 } 98 99 int main(int argc, char *argv[]) 100 { 101 GRAPH graph; 102 InitGraph(&graph); 103 104 Dijkstra(&graph); 105 106 for (size_t i = 0; i < POINT_NUM; i++) 107 { 108 printf("0->%lu : %u\n", i, graph.v_to_other[i]); 109 } 110 111 return 0; 112 }