圖的鄰接表表示及遍歷
阿新 • • 發佈:2019-01-22
圖也可以用鄰接表表示。各個結點中存放了結點的資訊,並且由一個指標變數,指向第一條邊,第一條變又指向第二條邊,以此類推。圖的鄰接表的程式碼如下:
/********************************/ /******圖的鄰接表的建立及遍歷****/ #include<stdlib.h> #include<stdio.h> #include<string.h> #define MaxVerNum 100 #define QueueSize 30 typedef enum{FALSE,TRUE} Boolean; typedef struct ArcNode { int adjvex;//該邊所指向的結點的位置 struct ArcNode * nextarc;//指向下一條邊的指標 }ArcNode; typedef struct VNode { char data;//頂點資訊 ArcNode *firstarc;//指向第一條邊的指標 }VNode; typedef struct { VNode adjlist[MaxVerNum]; int n,e; }AGraph; /******************************************/ /**建立有向圖的鄰接表演算法*****************/ Boolean visited[MaxVerNum]; void CreateAGraph(AGraph * G) { int i,j,k; ArcNode * s; printf("請輸入頂點數和邊數(輸入格式為:頂點數,邊數):"); scanf("%d,%d",&(G->n),&(G->e)); printf("請輸入頂點資訊,每個頂點以回車作為結束:\n"); /*建立頂點表,頂點從0開始編號*/ for(i=0;i<G->n;i++) { scanf("\n%c",&(G->adjlist[i].data)); G->adjlist[i].firstarc=NULL; } printf("請輸入邊的資訊(i,j):\n");//回車作為結束 for(k=0;k<G->e;k++) { scanf("%d,%d",&i,&j); s=(ArcNode *)malloc(sizeof(ArcNode)); if(s!=NULL) { s->adjvex=j; s->nextarc=G->adjlist[i].firstarc; G->adjlist[i].firstarc=s; s=NULL; /*對於無向圖在申請一塊記憶體用來存放邊即可 */ //s=(ArcNode * )malloc(sizeof(ArcNode)); if(s!=NULL) { s->adjvex=i; s->nextarc=G->adjlist[j].firstarc; G->adjlist[i].firstarc=s; s=NULL; } } } } /****深度優先遍歷******************************/ void DFS(AGraph *G,int vi)//以vi為出發點對鄰接表表示的圖進行深度優先搜尋 { ArcNode * p=NULL; visited[vi]=TRUE; printf("visited vextex : %c\n",G->adjlist[vi].data); p=G->adjlist[vi].firstarc; while(p!=NULL) { if(visited[p->adjvex]==FALSE) DFS(G,p->adjvex); p=p->nextarc; } } void DFSTraver(AGraph *G) { int i; for(i=0;i<G->n;i++) visited[i]=FALSE; for(i=0;i<G->n;i++) if(!visited[i]) DFS(G,i); } /******************************************************/ /*****廣度優先遍歷*************************************/ typedef struct { int front ; int rear; int count; int data[QueueSize]; }CirQueue; void InitQueue(CirQueue * Q) { Q->front=Q->rear=0; Q->count=0; }; int QueueEmpty(CirQueue *Q) { return Q->count==0; } int QueueFull(CirQueue *Q) { return Q->count==QueueSize; } void EnQueue(CirQueue *Q,int x) { if(QueueFull(Q)) printf("Queue overflow\n"); else { Q->count++; Q->data[Q->rear]=x; Q->rear=(Q->rear+1)%QueueSize; } } int DeQueue(CirQueue * Q) { int temp; if(QueueEmpty(Q)) printf("Queue underflow\n"); else { temp=Q->data[Q->front]; Q->count--; Q->front=(Q->front+1)%QueueSize; return temp; } } void BFS(AGraph *G,int k)//以k為源點進行廣度優先搜尋 { int i; CirQueue Q; ArcNode * p; InitQueue(&Q); visited[k]=TRUE; printf("廣度優先遍歷結點:%c\n",G->adjlist[k].data); EnQueue(&Q,k); while(!QueueEmpty(&Q)) { i=DeQueue(&Q); p=G->adjlist[i].firstarc; while(p) { if(!visited[p->adjvex]) { printf("廣度優先遍歷結點:%c\n",G->adjlist[p->adjvex].data); visited[p->adjvex]=TRUE; EnQueue(&Q,p->adjvex); } p=p->nextarc; } } } void BFSTraver(AGraph *G) { int i; for(i=0;i<G->n;i++) visited[i]=FALSE; for(i=0;i<G->n;i++) { if(!visited[i]) BFS(G,i); } } void main(void) { AGraph G; CreateAGraph(&G); DFSTraver(&G); BFSTraver(&G); }