1 图论:最短路径(广度优先搜索、C语言实现) 2 要用到的数据结构有: 3 队列、表、邻接表 4 分为六个文件- 5 |--Main.c 应用文件:main函数所在。读取各边到邻接表,然后调用计算机最小路径函数。求解。 6 |--code.c 最小路径函数:最小路径函数所在。 7 |--Queue.c 数据结构:队列 8 |--Table.c 数据结构:表 9 |--AdjList.c数据结构:邻接表 10 |--Graph.h 将所有数据结构文件包含进来 11 12 邻接表和队列的源泉代码可以从文章列表中找到。 13 算法为广度优先搜索。将路径和点记录在一张表中。最后用打印函数递归的打印出路径。思路可见《数据结构与算法分析》。 14 各文件源代码如下: 15 图论:最短路径(广度优先搜索、C语言实现) 16 要用到的数据结构有: 17 队列、表、邻接表 18 分为六个文件- 19 |--Main.c 应用文件:main函数所在。读取各边到邻接表,然后调用计算机最小路径函数。求解。 20 |--code.c 最小路径函数:最小路径函数所在。 21 |--Queue.c 数据结构:队列 22 |--Table.c 数据结构:表 23 |--AdjList.c数据结构:邻接表 24 |--Graph.h 将所有数据结构文件包含进来 25 26 邻接表和队列的源泉代码可以从文章列表中找到。 27 算法为广度优先搜索。将路径和点记录在一张表中。最后用打印函数递归的打印出路径。思路可见《数据结构与算法分析》。 28 各文件源代码如下: 29 [cpp] view plaincopyprint? 30 Graph.h:#ifndef _Graph_h 31 #include "Queue.c" 32 #include "Table.c" 33 #endif 34 Graph.h:#ifndef _Graph_h 35 #include "Queue.c" 36 #include "Table.c" 37 #endif [cpp] view plaincopyprint? 38 Main.c: 39 #include "code.c" 40 int main() 41 { 42 Vertex Graph = NULL ; Table T ; 43 int x, y, s, a ; 44 /*读取各边并插入*/ 45 for(scanf("%d %d", &x, &y); x != -1 ; scanf("%d %d", &x, &y)) 46 Graph = InsertEdge(x, y, Graph) ; 47 /*创建用于簿记的表,并初化始表:将图中各点格式化入表中*/ 48 T = CreatTable(SizeOfGraph(Graph)) ; 49 TableInit(T, Graph) ; 50 /*获取起点*/ 51 printf("Input the start vertex: ") ; 52 scanf("%d", &s) ; 53 /*计算各点的最短路径,并记录表中*/ 54 ShortestPath(s, Graph, T) ; 55 /*得到终点*/ 56 printf("Input the aim vertex: ") ; 57 scanf("%d", &a) ; 58 /*打印出该路径,未尾会*/ 59 TablePrint(s, a, T) ; 60 printf("\n") ; 61 /*释放内存*/ 62 GraphDestory(Graph) ; 63 TableDestory(T) ; 64 65 return 0; 66 } 67 Main.c: 68 #include "code.c" 69 int main() 70 { 71 Vertex Graph = NULL ; Table T ; 72 int x, y, s, a ; 73 /*读取各边并插入*/ 74 for(scanf("%d %d", &x, &y); x != -1 ; scanf("%d %d", &x, &y)) 75 Graph = InsertEdge(x, y, Graph) ; 76 /*创建用于簿记的表,并初化始表:将图中各点格式化入表中*/ 77 T = CreatTable(SizeOfGraph(Graph)) ; 78 TableInit(T, Graph) ; 79 /*获取起点*/ 80 printf("Input the start vertex: ") ; 81 scanf("%d", &s) ; 82 /*计算各点的最短路径,并记录表中*/ 83 ShortestPath(s, Graph, T) ; 84 /*得到终点*/ 85 printf("Input the aim vertex: ") ; 86 scanf("%d", &a) ; 87 /*打印出该路径,未尾会*/ 88 TablePrint(s, a, T) ; 89 printf("\n") ; 90 /*释放内存*/ 91 GraphDestory(Graph) ; 92 TableDestory(T) ; 93 94 return 0; 95 }[cpp] view plaincopyprint? 96 code.c: 97 #include "Graph.h" 98 99 void ShortestPath(int S, Vertex Graph, Table T) 100 { 101 Queue Q ; int NumVertex ; 102 int tmp ; int V, W ; 103 Ind_Node Ind ; int DistCount = 0; 104 //init what should be init 105 /*计算图中的点数*/ 106 NumVertex = SizeOfGraph(Graph) ; 107 /*创建队列*/ 108 Q = CreatQueue(NumVertex) ; 109 //enter the start vertex into queue 110 /*找到起点*/ 111 tmp = TableFind(S, T) ; 112 /*初始化起点*/ 113 T->Array[tmp].Know = True ; 114 T->Array[tmp].Path = 0 ; 115 T->Array[tmp].Dist = 0 ; 116 /*将起点推入队列之中,以驱动下面的代码*/ 117 Enqueue(tmp, Q) ; 118 /*第一次运行至此,队列不为空,因为插入起点*/ 119 while(!QueueIsEmpty(Q)) 120 { 121 /*读取一点*/ 122 V = Dequeue(Q) ; 123 /*读取V的各个入度*/ 124 Ind = (T->Array[V].prototype)->Indegree ; 125 while(Ind != NULL) 126 { 127 /*W为当前读取到的入度点*/ 128 W = TableFind(Ind->Number, T) ; 129 if(T->Array[W].Dist == Infinity) 130 { 131 /*如果W以前没有处理过,那么进行处理*/ 132 T->Array[W].Dist = T->Array[V].Dist +1 ; 133 T->Array[W].Path = (T->Array[V].prototype)->Number ; 134 /*然后推入队列之中*/ 135 Enqueue(W, Q) ; 136 } 137 /*处理下一入度点*/ 138 Ind = Ind->Next ; 139 } 140 } 141 / 142 QueueDestory(Q) ; 143 } 144 code.c: 145 #include "Graph.h" 146 147 void ShortestPath(int S, Vertex Graph, Table T) 148 { 149 Queue Q ; int NumVertex ; 150 int tmp ; int V, W ; 151 Ind_Node Ind ; int DistCount = 0; 152 //init what should be init 153 /*计算图中的点数*/ 154 NumVertex = SizeOfGraph(Graph) ; 155 /*创建队列*/ 156 Q = CreatQueue(NumVertex) ; 157 //enter the start vertex into queue 158 /*找到起点*/ 159 tmp = TableFind(S, T) ; 160 /*初始化起点*/ 161 T->Array[tmp].Know = True ; 162 T->Array[tmp].Path = 0 ; 163 T->Array[tmp].Dist = 0 ; 164 /*将起点推入队列之中,以驱动下面的代码*/ 165 Enqueue(tmp, Q) ; 166 /*第一次运行至此,队列不为空,因为插入起点*/ 167 while(!QueueIsEmpty(Q)) 168 { 169 /*读取一点*/ 170 V = Dequeue(Q) ; 171 /*读取V的各个入度*/ 172 Ind = (T->Array[V].prototype)->Indegree ; 173 while(Ind != NULL) 174 { 175 /*W为当前读取到的入度点*/ 176 W = TableFind(Ind->Number, T) ; 177 if(T->Array[W].Dist == Infinity) 178 { 179 /*如果W以前没有处理过,那么进行处理*/ 180 T->Array[W].Dist = T->Array[V].Dist +1 ; 181 T->Array[W].Path = (T->Array[V].prototype)->Number ; 182 /*然后推入队列之中*/ 183 Enqueue(W, Q) ; 184 } 185 /*处理下一入度点*/ 186 Ind = Ind->Next ; 187 } 188 } 189 / 190 QueueDestory(Q) ; 191 }[cpp] view plaincopyprint? 192 193 [cpp] view plaincopyprint? 194 Table.c: 195 #include <stdio.h> 196 #include <stdlib.h> 197 #include "AdjList.c" 198 #include "limits.h" 199 #define Infinity INT_MAX 200 #define True 1 201 #define False 0 202 typedef struct table_element_tag 203 { 204 /*将向邻接表中的点*/ 205 Vertex prototype ; 206 /*路径长度*/ 207 int Dist ; 208 /*记录该点在最短路径中的上一个点。*/ 209 int Path ; 210 }*TableElement ; 211 typedef struct table_tag 212 { 213 /*这里是表头,第一个是记录表大小,第二个是数组(数组实现表)*/ 214 int Size ; 215 TableElement Array ; 216 }*Table ; 217 218 Table CreatTable(int Max) 219 { 220 /*分配好内存,返回*/ 221 Table T ; 222 T = calloc(1, sizeof(struct table_tag)) ; 223 if(!T) { fprintf(stderr, "Out of space!\n"); exit(1) ;} 224 T->Array = calloc(Max, sizeof(struct table_element_tag)) ; 225 if(!T->Array){ fprintf(stderr, "Out of space!") ; exit(1) ;} 226 T->Size = Max ; 227 return T ; 228 } 229 void TableInit(Table T, Vertex Graph) 230 { 231 /*将表中各点记录表中*/ 232 int i = 0; 233 while(Graph != NULL && i < T->Size) 234 { 235 //calloc will init Know 236 T->Array[i].prototype = Graph ; 237 /*记录为无穷大,表示该点未知*/ 238 T->Array[i].Dist = Infinity ; 239 T->Array[i].Path = Infinity ; 240 i++ ; 241 Graph = Graph->Next ; 242 } 243 } 244 int TableFind(int f, Table T) 245 { 246 TableElement te ; int size ; int i ; 247 if(!T){ fprintf(stderr, "Graph was empty or miss!\n") ; exit(1) ;} 248 te = T->Array ; size = T->Size ; 249 for( i = 0; i < size; i++) 250 if( (te[i].prototype)->Number == f) 251 break ; 252 if(i < size) 253 return i ; 254 else /*如果没有找到就返回无穷大*/ 255 return Infinity ; 256 } 257 void TablePrint(int s, int a, Table T) 258 { 259 int tmp ; 260 if(a != s) 261 { 262 tmp = TableFind(a, T) ; 263 if(tmp == Infinity){ fprintf(stderr, "No Found the vertex: %d\n", a) ; exit(1) ;} 264 TablePrint(s, T->Array[tmp].Path, T) ; 265 printf(" to ") ; 266 } 267 printf("%d", (T->Array[TableFind(a, T)].prototype)->Number) ; 268 } 269 void TableDestory(Table T) 270 { 271 /*释放内存*/ 272 if(T) 273 { 274 if(T->Array) 275 free(T->Array) ; 276 free(T) ; 277 } 278 }