邻接表:C语言实现

  1 注意InsertVertex(插入点函数)返回的是插入后,该点的指针。所以当你的图是空的时候(即Graph==NULL)时,你应该这样子调用该函数:Graph = InsertVertex(x, Graph).否则只有当图非空时,才可以调用。或者你可以为图添加一个表头,或者将Graph定义为全局变量,做一个小小的修改即可。解决方法有很多,不多列举。
  2 
  3        像求最短路径,只要用到插入边函数, 这样就不需做修改。因为插入边函数返回插入边之后的新的图。这样子调用插入边函数:Graph = InsertEdge(x, y, Graph).
  4 
  5        应用例程,可见算法中的《最短路径:广度优先搜索(C语言实现)》
  6 
  7 [cpp] view plaincopyprint?
  8 邻接表:C语言实现  
  9   
 10 源代码如下:  
 11 #include <stdio.h>   
 12 #include <stdlib.h>   
 13   
 14 typedef struct Ind_Node_tag  
 15 {  
 16     struct Ind_Node_tag *Next ;  
 17     int Number ;  
 18 }*Ind_Node ;  
 19 /*这是入度结点结构。Number记录该入度点的序号。*/  
 20 typedef struct Vertex_tag  
 21 {  
 22     int Number ;  
 23     Ind_Node Indegree ;  
 24     struct Vertex_tag *Next ;  
 25 }*Vertex ;  
 26 /*  Number是指该点的序号。如点1,点2. 
 27 Indegree 是该点的入度数组 
 28 Next 指向下一个点*/  
 29   
 30 /*FindVertex: 
 31 if x in graph 
 32     return x 
 33   else 
 34 return NULL*/  
 35 Vertex FindVertex(int x, Vertex Graph)  
 36 {  
 37     while(Graph != NULL && Graph->Number != x)  
 38         Graph = Graph->Next ;  
 39     return Graph ;  
 40 }  
 41   
 42 /* InsertVertex: 
 43   if x not in graph 
 44         insert x into graph 
 45         return x 
 46     else 
 47         return x 
 48 */  
 49 Vertex InsertVertex(int x, Vertex Graph)  
 50 {  
 51     Vertex G ;  
 52     if(!(G = FindVertex(x, Graph)))         //如果找到了X不做修改,直接返回它,   
 53     {   //否则:   
 54         G = calloc(1, sizeof(struct Vertex_tag)) ;              //分配内存   
 55         if(!G)  {   fprintf(stderr, "Out of memory!\n") ;   exit(1) ;   }   //错误检测   
 56         G->Number = x ;        
 57 /*如果Graph是NULL的,那么就把G返回。     
 58     这就是为什么第一次不能插入点。因为插入点函数返回插入点的指针 
 59     如果Graph是全局的,那么可以使用Graph = G解决。使用表头的不解释*/  
 60         if(Graph == NULL)                 
 61             return G ;  
 62         /* Graph不为空,那么将点插入到邻接图的最后面*/  
 63         while(Graph->Next != NULL)  
 64             Graph = Graph->Next ;  
 65         Graph->Next = G ;  
 66     }  
 67 return G ;  
 68 /*因此每一次调用该函数后,能够保证该点一定存在于表。 
 69     因为如果找到就返回它,不在就插入它               */  
 70 }  
 71 /*  insert x 
 72     insert y 
 73     update indegree of x */  
 74 Vertex InsertEdge(int x, int y, Vertex Graph)  
 75 {  
 76     Vertex V ;  
 77     Ind_Node Ind ;  
 78     //Ind将要插入点x的入度结点   
 79     Ind = calloc(1, sizeof(struct Ind_Node_tag)) ;  
 80     if(!Ind){ fprintf(stderr, "Out of space!\n"); exit(1) ; }  
 81     Ind->Number = y ;  
 82 //首先,保证x在graph中。   
 83 //见InsertVertex注释。调用完插入点函数后,x一定存在于Graph   
 84 V = InsertVertex(x, Graph) ;  
 85 //如果图是空的即Graph == NULL,时,更新Graph.   
 86 //调用这个函数的正确调用方法是Graph = InsertEdge(x, y, Graph)   
 87 //这样子如果图是空的,那么就能够更新Graph了。    
 88     if(Graph == NULL)  
 89         Graph = V ;  
 90     //保证y在图中   
 91     InsertVertex(y, Graph) ;  
 92     //把入度点y插入到x的入度表中。   
 93     Ind->Next = V->Indegree ;  
 94     V->Indegree = Ind ;  
 95     //把Graph返回。   
 96     return Graph ;  
 97 }  
 98 //free memory   
 99 //释放内存   
100 void GraphDestory(Vertex Graph)  
101 {  
102     Ind_Node Ind, ITmp ;  
103     Vertex Tmp ;  
104     while(Graph != NULL)  
105     {  
106         Ind = Graph->Indegree ;  
107         while(Ind != NULL)  
108         {  
109             ITmp = Ind ;  
110             Ind = Ind->Next ;  
111             free(ITmp) ;  
112         }  
113         Tmp = Graph ;  
114         Graph = Graph->Next ;  
115         free(Tmp ) ;  
116     }  
117 }  
118 //return how many vertex of graph   
119 //计算图中有多少个点   
120 int SizeOfGraph(Vertex Graph)  
121 {  
122     int Result = 0 ;  
123     while(Graph != NULL)  
124     {  
125         Result ++ ;  
126         Graph = Graph->Next ;  
127     }  
128     return Result ;  
129 }  
130 邻接表:C语言实现
131 
132 源代码如下:
133 #include <stdio.h>
134 #include <stdlib.h>
135 
136 typedef struct Ind_Node_tag
137 {
138     struct Ind_Node_tag *Next ;
139     int Number ;
140 }*Ind_Node ;
141 /*这是入度结点结构。Number记录该入度点的序号。*/
142 typedef struct Vertex_tag
143 {
144     int Number ;
145     Ind_Node Indegree ;
146     struct Vertex_tag *Next ;
147 }*Vertex ;
148 /*    Number是指该点的序号。如点1,点2.
149 Indegree 是该点的入度数组
150 Next 指向下一个点*/
151 
152 /*FindVertex:
153 if x in graph
154     return x
155   else
156 return NULL*/
157 Vertex FindVertex(int x, Vertex Graph)
158 {
159     while(Graph != NULL && Graph->Number != x)
160         Graph = Graph->Next ;
161     return Graph ;
162 }
163 
164 /* InsertVertex:
165   if x not in graph
166         insert x into graph
167         return x
168     else
169         return x
170 */
171 Vertex InsertVertex(int x, Vertex Graph)
172 {
173     Vertex G ;
174     if(!(G = FindVertex(x, Graph)))         //如果找到了X不做修改,直接返回它,
175     {    //否则:
176         G = calloc(1, sizeof(struct Vertex_tag)) ;                //分配内存
177         if(!G)  {   fprintf(stderr, "Out of memory!\n") ;   exit(1) ;   }    //错误检测
178         G->Number = x ;        
179 /*如果Graph是NULL的,那么就把G返回。    
180     这就是为什么第一次不能插入点。因为插入点函数返回插入点的指针
181     如果Graph是全局的,那么可以使用Graph = G解决。使用表头的不解释*/
182         if(Graph == NULL)                
183             return G ;
184         /* Graph不为空,那么将点插入到邻接图的最后面*/
185         while(Graph->Next != NULL)
186             Graph = Graph->Next ;
187         Graph->Next = G ;
188     }
189 return G ;
190 /*因此每一次调用该函数后,能够保证该点一定存在于表。
191     因为如果找到就返回它,不在就插入它                */
192 }
193 /*  insert x
194     insert y
195     update indegree of x */
196 Vertex InsertEdge(int x, int y, Vertex Graph)
197 {
198     Vertex V ;
199     Ind_Node Ind ;
200     //Ind将要插入点x的入度结点
201     Ind = calloc(1, sizeof(struct Ind_Node_tag)) ;
202     if(!Ind){ fprintf(stderr, "Out of space!\n"); exit(1) ; }
203     Ind->Number = y ;
204 //首先,保证x在graph中。
205 //见InsertVertex注释。调用完插入点函数后,x一定存在于Graph
206 V = InsertVertex(x, Graph) ;
207 //如果图是空的即Graph == NULL,时,更新Graph.
208 //调用这个函数的正确调用方法是Graph = InsertEdge(x, y, Graph)
209 //这样子如果图是空的,那么就能够更新Graph了。 
210     if(Graph == NULL)
211         Graph = V ;
212     //保证y在图中
213     InsertVertex(y, Graph) ;
214     //把入度点y插入到x的入度表中。
215     Ind->Next = V->Indegree ;
216     V->Indegree = Ind ;
217     //把Graph返回。
218     return Graph ;
219 }
220 //free memory
221 //释放内存
222 void GraphDestory(Vertex Graph)
223 {
224     Ind_Node Ind, ITmp ;
225     Vertex Tmp ;
226     while(Graph != NULL)
227     {
228         Ind = Graph->Indegree ;
229         while(Ind != NULL)
230         {
231             ITmp = Ind ;
232             Ind = Ind->Next ;
233             free(ITmp) ;
234         }
235         Tmp = Graph ;
236         Graph = Graph->Next ;
237         free(Tmp ) ;
238     }
239 }
240 //return how many vertex of graph
241 //计算图中有多少个点
242 int SizeOfGraph(Vertex Graph)
243 {
244     int Result = 0 ;
245     while(Graph != NULL)
246     {
247         Result ++ ;
248         Graph = Graph->Next ;
249     }
250     return Result ;
251 }
原文地址:https://www.cnblogs.com/XLCYun/p/2477720.html