zoukankan      html  css  js  c++  java
  • 图论:最短路径:广度优先搜索(C语言实现)

      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 }  
  • 相关阅读:
    实例讲解如何在Delphi中动态创建dxBarManager内容
    SqlServer中创建Oracle连接服务器
    Delphi中的四舍五入函数
    Delphi中的四舍五入函数
    垃圾回收内存管理
    列表生成式
    列表函数&方法
    python切片
    python函数def
    Python 控制流、列表生成式
  • 原文地址:https://www.cnblogs.com/XLCYun/p/2477721.html
Copyright © 2011-2022 走看看