图的邻接表存储方式及遍历

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以上是关于图的邻接表存储方式及遍历的主要内容,如果未能解决你的问题,请参考以下文章

图的存储代码实现

c语言图的遍历,邻接表存储,深度,广度优先遍历

C++如何处理图的存储方式

邻接矩阵和邻接表存储的图的基本操作及完整代码

图的存储表示及示例

浅谈数据结构之图的邻接表深度和广度优先遍历