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 }