图的邻接表存储方式及遍历
Posted accomplishment
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的邻接表存储方式及遍历相关的知识,希望对你有一定的参考价值。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<time.h> 4 #include<stdarg.h> 5 #define OK 1 6 #define NO 0 7 #define TRUE 1 8 #define FALSE 0 9 #define ERROR -1 10 #define MAX_VERTEX_NUM 20 //最大顶点个数 11 12 typedef int Status; 13 14 typedef int QElemType_L; 15 16 typedef struct QNode 17 { 18 QElemType_L data; 19 struct QNode *next; 20 }QNode; 21 typedef QNode *QueuePtr; 22 23 typedef struct 24 { 25 QueuePtr front; 26 QueuePtr rear; 27 28 }LinkQueue; 29 30 typedef enum{DG,UDG}GraphKind; 31 32 typedef struct ArcNode 33 { 34 int adjvex;//该弧指向的顶点的位置 35 struct ArcNode *nextarc;//指向下一个弧结点的指针 36 }ArcNode; 37 38 typedef char VertexType_AL; 39 typedef struct VNode //头结点 40 { 41 VertexType_AL data; 42 ArcNode *firstarc; 43 }VNode; 44 typedef VNode AdjList[MAX_VERTEX_NUM+1]; 45 46 /*图的存储方式*/ 47 typedef struct 48 { 49 AdjList vertices;//邻接表 50 int vexnum,arcnum;//图当前顶点数和弧数 51 GraphKind kind; 52 }ALGraph; 53 54 Status visited[MAX_VERTEX_NUM+1]; 55 56 void (*VisitFunc)(VertexType_AL e);//函数指针变量 57 58 Status CreateGraph_AL(ALGraph *G,int r); 59 60 Status CreateDG_AL(ALGraph *G); 61 62 Status CreateUDG_AL(ALGraph *G); 63 64 int LocateVex_AL(ALGraph G,VertexType_AL u); 65 66 Status FitstAdjVex_AL(ALGraph G,VertexType_AL u); 67 68 Status NextAdjVex_AL(ALGraph G,VertexType_AL v,VertexType_AL w); 69 70 Status PutVex_AL(ALGraph *G,VertexType_AL v,VertexType_AL value); 71 72 Status InsertVex_AL(ALGraph *G,VertexType_AL v); 73 74 Status InsertArc_AL(ALGraph *G,VertexType_AL v,VertexType_AL w); 75 76 Status DeleteArc_AL(ALGraph *G,VertexType_AL v,VertexType_AL w); 77 78 Status DeleteVex_AL(ALGraph *G,VertexType_AL v); 79 80 void OutputALGraph(ALGraph G); 81 82 VertexType_AL GetVex_AL(ALGraph G,int order); 83 84 void DFSTraverse_AL(ALGraph G); 85 86 void DFS_AL(ALGraph G,int v); 87 88 void BFSTraverse_AL(ALGraph G); 89 90 91 Status InitQueue_L(LinkQueue *Q); 92 93 Status QueueEmpyt(LinkQueue Q); 94 95 Status EnQueue_L(LinkQueue *Q,QElemType_L e); 96 97 Status DeQueue_L(LinkQueue *Q,QElemType_L *e); 98 99 Status ClearGraph_AL(ALGraph *G); 100 101 102 int main(int argc,char**argv) 103 { 104 ALGraph G; 105 printf("1、2、3\\n函数CreateGraph_AL等测试..\\n"); 106 { 107 int r; 108 srand((unsigned)time(NULL));//用系统的时间做随机数的种子 109 r=rand()%2;//对4取余只能产生0,1这几个数 110 switch(r) 111 { 112 case DG: 113 printf("初始化有向图 G..\\n"); 114 break; 115 case UDG: 116 printf("初始化无向图 G..\\n"); 117 break; 118 } 119 CreateGraph_AL(&G,r); 120 printf("\\n"); 121 } 122 123 124 printf("17\\n函数OutputALGraph 测试..\\n"); 125 { 126 printf("输出图的邻接表 G = \\n"); 127 OutputALGraph(G); 128 printf("\\n"); 129 130 131 } 132 printf("6\\n函数 GetVex_AL 测试..\\n"); 133 { 134 printf("第%d个顶点的值为\'%c\'\\n",3,GetVex_AL(G,3)); 135 136 } 137 printf("8\\n函数 FitstAdjVex_AL 测试..\\n"); 138 { 139 printf("\'%c\'的第一个邻接顶点的序号为 %d \\n",\'B\',FitstAdjVex_AL(G,\'B\')); 140 printf("\\n"); 141 } 142 143 printf("9\\n函数 NextAdjVex_AL 测试..\\n"); 144 { 145 printf("\'%c\'相对与\'%c\'的下一个邻接顶点的序号为 %d \\n",\'A\',\'B\',NextAdjVex_AL(G,\'A\',\'B\')); 146 printf("\\n"); 147 } 148 149 printf("7\\n函数PutVex_AL 测试..\\n"); 150 { 151 printf("对顶点\'%c\'赋值\'%c\'后,G=\\n",\'A\',\'X\'); 152 PutVex_AL(&G,\'A\',\'X\'); 153 OutputALGraph(G); 154 printf("\\n"); 155 156 } 157 printf("10\\n函数 InsertVex_AL 测试..\\n"); 158 { 159 printf("插入顶点\'%c\'后,G = \\n",\'H\'); 160 InsertVex_AL(&G,\'H\'); 161 OutputALGraph(G); 162 printf("\\n"); 163 } 164 printf("12\\n函数 InsertArc_AL 测试..\\n"); 165 { 166 printf("按顺序插入弧<%c,%c>、",\'H\',\'X\'); 167 printf("<%c,%c>、",\'H\',\'C\'); 168 printf("<%c,%c>后,G = \\n",\'D\',\'H\'); 169 InsertArc_AL(&G,\'H\',\'X\'); 170 InsertArc_AL(&G,\'H\',\'C\'); 171 InsertArc_AL(&G,\'D\',\'H\'); 172 OutputALGraph(G); 173 printf("\\n"); 174 175 } 176 177 printf("13\\n函数DeleteArc_AL 测试..\\n"); 178 { 179 printf("删除弧<%c,%c>后,G = \\n",\'H\',\'X\'); 180 DeleteArc_AL(&G,\'H\',\'X\'); 181 OutputALGraph(G); 182 printf("\\n"); 183 184 } 185 186 printf("13\\n函数DeleteArc_AL 测试..\\n"); 187 { 188 printf("删除顶点\'%c\'后,G = \\n",\'H\'); 189 DeleteVex_AL(&G,\'H\'); 190 OutputALGraph(G); 191 printf("\\n"); 192 193 } 194 195 196 printf("14、15\\n函数DFSTraverse_AL 等测试..\\n"); 197 { 198 printf("深度优先遍历图 G= "); 199 DFSTraverse_AL(G); 200 printf("\\n"); 201 202 } 203 204 205 printf("16\\n函数BFSTraverse_AL 等测试..\\n"); 206 { 207 printf("广度优先遍历图 G= "); 208 BFSTraverse_AL(G); 209 printf("\\n"); 210 211 } 212 213 printf("4\\n函数ClearGraph_AL 测试..\\n"); 214 { 215 printf("清空图\\n"); 216 ClearGraph_AL(&G); 217 OutputALGraph(G); 218 printf("\\n"); 219 220 221 } 222 223 return 0; 224 } 225 226 Status InitQueue_L(LinkQueue *Q){ 227 Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode)); 228 if(!Q->front) 229 exit(ERROR); 230 Q->front->next=NULL; 231 return OK; 232 } 233 234 Status QueueEmpyt(LinkQueue Q){ 235 if(Q.front==Q.rear) 236 return TRUE; 237 else 238 return FALSE; 239 } 240 241 Status EnQueue_L(LinkQueue *Q,QElemType_L e){ 242 QueuePtr p; 243 p=(QueuePtr)malloc(sizeof(QNode)); 244 if(!p) 245 exit(ERROR); 246 p->data=e; 247 p->next=NULL; 248 Q->rear->next=p; 249 Q->rear=p; 250 return OK; 251 252 } 253 254 255 Status DeQueue_L(LinkQueue *Q,QElemType_L *e){ //从头部删除 256 QueuePtr p; 257 if(Q->front==Q->rear) 258 return ERROR; 259 p=Q->front->next; 260 *e=p->data; 261 Q->front->next=p->next; 262 if(Q->rear==p) //如果删除的是队列的最后一个元素,此时对队尾指针进行重新赋值 263 Q->rear=Q->front; 264 } 265 266 267 268 Status CreateGraph_AL(ALGraph *G,int r){ 269 270 switch(r) 271 { 272 case DG: 273 G->kind=DG; 274 return CreateDG_AL(G); 275 case UDG: 276 G->kind=UDG; 277 return CreateUDG_AL(G); 278 default: 279 return ERROR; 280 281 } 282 283 return OK; 284 285 286 287 } 288 289 int LocateVex_AL(ALGraph G,VertexType_AL u) 290 { 291 int i; 292 for(i=1;i<=G.vexnum;i++) 293 { 294 if(G.vertices[i].data==u) 295 return i; 296 } 297 return 0; 298 299 } 300 Status CreateDG_AL(ALGraph *G){ 301 int i,j,k; 302 VertexType_AL v1,v2; 303 ArcNode *p; 304 ArcNode *r[MAX_VERTEX_NUM+1]; 305 printf("输入顶点数 "); 306 scanf("%d",&(G->vexnum)); 307 printf("输入弧数 "); 308 scanf("%d",&(G->arcnum)); 309 printf("输入各个顶点值 "); 310 getchar(); 311 for(i=1;i<=G->vexnum;i++) 312 { 313 scanf("%c",&(G->vertices[i].data)); 314 G->vertices[i].firstarc=NULL; 315 r[i]=NULL; 316 } 317 318 printf("读取各边,制作邻接表\\n"); 319 for(k=1;k<=G->arcnum;k++) 320 { 321 getchar(); 322 printf("输入相邻结点(添加弧的信息)"); 323 scanf("%c%c",&v1,&v2); 324 i=LocateVex_AL(*G,v1); //第i个结点的链表相连 325 j=LocateVex_AL(*G,v2); 326 p=(ArcNode*)malloc(sizeof(ArcNode)); 327 if(!p) 328 exit(ERROR); 329 p->adjvex=j; 330 p->nextarc=NULL; 331 if(r[i]==NULL) 332 G->vertices[i].firstarc=p; 333 else 334 r[i]->nextarc=p; 335 r[i]=p;//r[i]用来标记链表的最后一个结点指针,起到延长链表添加新的结点的作用 336 337 } 338 339 return OK; 340 } 341 Status CreateUDG_AL(ALGraph *G){ 342 int i,j,k; 343 VertexType_AL v1,v2; 344 ArcNode *p,*q; 345 ArcNode *r[MAX_VERTEX_NUM+1]; 346 printf("输入顶点数 "); 347 scanf("%d",&(G->vexnum)); 348 printf("输入弧数 "); 349 scanf("%d",&(G->arcnum)); 350 printf("输入各个顶点值 "); 351 getchar(); 352 for(i=1;i<=G->vexnum;i++) 353 { 354 scanf("%c",&(G->vertices[i].data)); 355 G->vertices[i].firstarc=NULL; 356 r[i]=NULL; 357 } 358 359 printf("读取各边,制作邻接表\\n"); 360 for(k=1;k<=G->arcnum;k++) 361 { 362 getchar(); 363 printf("输入相邻结点(添加弧的信息)"); 364 scanf("%c%c",&v1,&v2); 365 i=LocateVex_AL(*G,v1); //第i个结点的链表相连 366 j=LocateVex_AL(*G,v2); 367 p=(ArcNode*)malloc(sizeof(ArcNode)); 368 if(!p) 369 exit(ERROR); 370 p->adjvex=j; 371 p->nextarc=NULL; 372 if(r[i]==NULL) 373 G->vertices[i].firstarc=p; 374 else 375 r[i]->nextarc=p; 376 r[i]=p;//r[i]用来标记链表的最后一个结点指针,起到延长链表添加新的结点的作用 377 q=(ArcNode*)malloc(sizeof(ArcNode)); 378 if(!q) 379 exit(ERROR); 380 q->adjvex=i; 381 q->nextarc=NULL; 382 if(r[j]==NULL) 383 G->vertices[j].firstarc=q; 384 else 385 r[j]->nextarc=q; 386 r[j]=q; //i和j轮换对称,上面的方法可以给i添加邻接表,下面的也可以给j按同样的方法添加,只是也就是输入两个结点的时候会同时进行两次操作 387 388 389 } 390 391 392 return OK; 393 } 394 395 void OutputALGraph(ALGraph G){ 396 int i,j; 397 ArcNode *p; 398 if(!G.vexnum&&!G.arcnum) 399 printf("空图!\\n"); 400 else 401 { 402 for(i=1;i<=G.vexnum;i++) 403 { 404 printf("%c->",G.vertices[i].data); 405 p=G.vertices[i].firstarc; 406 while(p) 407 { 408 printf(" %c",G.vertices[p->adjvex].data); 409 p=p->nextarc; 410 411 } 412 printf("\\n"); 413 } 414 } 415 } 416 Status ClearGraph_AL(ALGraph *G){ 417 int i; 418 ArcNode *p,*q; 419以上是关于图的邻接表存储方式及遍历的主要内容,如果未能解决你的问题,请参考以下文章