1. 程式人生 > >圖的遍歷(DFS、BFS)使用鄰接矩陣(陣列)作為儲存結構--C語言

圖的遍歷(DFS、BFS)使用鄰接矩陣(陣列)作為儲存結構--C語言

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_VERTEX_NUM 20    //最大頂點個數 
#define INFINITY INT_MAX  //最大值∞ 

typedef char VertexType;   //頂點向量型別 
typedef int VRType;       
typedef int InfoType;
typedef int QElemType;

//圖的陣列儲存表示 
 typedef
struct{ VertexType vexs[MAX_VERTEX_NUM]; //頂點向量 VRType arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];; //鄰接矩陣,於無權圖1、0表示兩個頂點是否相鄰,對於有權圖為權值 int vexnum,arcnum; //圖的頂點數和弧數 }MGraph; bool visited[MAX_VERTEX_NUM]; //標記頂點是否被訪問,訪問為true,否則為false //查詢頂點在頂點向量中的位置 int locateVertex(MGraph umg, VertexType v) { int
i; for(i=0;i<umg.vexnum;i++) { if(v == umg.vexs[i]) return i; } return -1; } //建立無向(有向)無權圖 createUMGraph(MGraph *umg) { int i,j,v; char v1,v2; printf("輸入無權圖的頂點數和邊數\n"); scanf("%d %d",&(*umg).vexnum,&(*umg).arcnum); for(v=0;v<(*umg).vexnum;v++) visited[v] = false
; getchar(); printf("輸入頂點名稱\n"); for(v=0;v<(*umg).vexnum;v++) { printf("輸入第%d個頂點名稱:",v); scanf("%c",&(*umg).vexs[v]); getchar(); } //初始化鄰接矩陣 for(i=0;i<(*umg).vexnum;i++) for(j=0;j<(*umg).vexnum;j++) (*umg).arcs[i][j] = 0; //將圖中相鄰的頂點的鄰接矩陣值設為1,不相鄰仍為0 printf("輸入邊的資訊,輸入邊的兩個頂點名稱v1 v2\n"); for(v=0;v<(*umg).arcnum;v++) { printf("輸入第%d條邊兩個頂點:",v); scanf("%c %c",&v1,&v2); getchar(); printf("\n"); i = locateVertex(*umg,v1); j = locateVertex(*umg,v2); // (*umg).arcs[i][j] = (*umg).arcs[j][i] = 1; //由於是無向圖,因此一條邊關聯兩個頂點 (*umg).arcs[i][j] = 1; //有向圖,邊為單向 } } //建立無向(有向)有權圖 createMGraph(MGraph *mg) { int i,j,v,w; char v1,v2; printf("輸入有權圖的頂點數和邊數\n"); scanf("%d %d",&(*mg).vexnum,&(*mg).arcnum); for(v=0;v<(*mg).vexnum;v++) visited[v] = false; getchar(); printf("輸入頂點名稱\n"); for(v=0;v<(*mg).vexnum;v++) { printf("輸入第%d個頂點名稱:",v); scanf("%c",&(*mg).vexs[v]); getchar(); } //初始化鄰接矩陣 for(i=0;i<(*mg).vexnum;i++) for(j=0;j<(*mg).vexnum;j++) (*mg).arcs[i][j] = INFINITY; //將圖中相鄰的頂點的鄰接矩陣值設為邊的權值 printf("輸入邊的資訊,輸入邊的兩個頂點名稱和權值v1 v2 w\n"); for(v=0;v<(*mg).arcnum;v++) { printf("輸入第%d條邊兩個頂點和權值:",v); scanf("%c %c %d",&v1,&v2,&w); getchar(); i = locateVertex(*mg,v1); j = locateVertex(*mg,v2); // (*mg).arcs[i][j] = (*mg).arcs[j][i] = w; //由於是無向圖,因此一條邊關聯兩個頂點 (*mg).arcs[i][j] = w; //有向圖,邊為單向 } } //列印圖的臨界矩陣 void print(MGraph G) { int i,j; printf("圖的鄰接矩陣\n"); for(i=0;i<G.vexnum;i++) { for(j=0;j<G.vexnum;j++) { if(G.arcs[i][j]!=INFINITY) printf("%d ",G.arcs[i][j]); else printf("∞ "); } printf("\n"); } printf("\n"); } //深度優先遍歷圖 int FirstAdjVex(MGraph G,int v) { //獲取與頂點v相鄰的第一個頂點下標 int i; for(i=0;i<G.vexnum;i++) { if(G.arcs[v][i]!=0 && G.arcs[v][i]!=INFINITY && !visited[i]) return i; } return -1; } int NextAdjVex(MGraph G,int v,int w) { //得到v的下一個未被訪問的相鄰頂點下標 int i; for(i=w;i<G.vexnum;i++) { if(G.arcs[v][i]!=0 && G.arcs[v][i]!=INFINITY && !visited[i]) return i; } return -1; } void DFS(MGraph G,int v) { int w; visited[v] = true; printf("%c ",G.vexs[v]); //訪問第v個頂點 for(w = FirstAdjVex(G,v); w >= 0;w = NextAdjVex(G,v,w)) if(!visited[w]) DFS(G,w); //對v的尚未訪問的鄰接頂點w遞迴呼叫DFS } void DFSTraverse(MGraph G) { printf("深度優先遍歷序列:"); int v; for(v = 0; v<G.vexnum;v++) visited[v] = false; for(v=0;v<G.vexnum;v++) if(!visited[v]) DFS(G,v); printf("\n"); } //廣度優先遍歷 //建立用於廣度優先遍歷的佇列 typedef struct QNode { QElemType data; struct QNode *qnext; }QNode,*PQNode; typedef struct Queue { PQNode front; PQNode rear; }Queue,*PQueue; //初始化一個空佇列 PQueue initQueue() { PQueue pqueue = (PQueue)malloc(sizeof(Queue)); PQNode pqnode = (PQNode)malloc(sizeof(QNode)); if(pqnode==NULL) { printf("佇列頭空間申請失敗!\n"); exit(-1); } pqueue->front = pqueue->rear = pqnode; pqnode->qnext = NULL; return pqueue; } //隊尾入隊 void enQueue(PQueue pqueue,QElemType data) { PQNode pqnode = (PQNode)malloc(sizeof(QNode)); if(pqnode==NULL) { printf("佇列結點申請失敗!\n"); exit(-1); } pqnode->data = data; pqnode->qnext = NULL; pqueue->rear->qnext = pqnode; pqueue->rear = pqnode; } //判斷佇列是否為空 bool isEmpty(PQueue pqueue) { if(pqueue->front == pqueue->rear) return true; return false; } //隊頭出隊 QElemType deQueue(PQueue pqueue) { if(isEmpty(pqueue)) { printf("佇列為空\n"); exit(-1); } PQNode pqnode = pqueue->front->qnext; pqueue->front->qnext = pqnode->qnext; if(pqnode == pqueue->rear) pqueue->rear = pqueue->front; QElemType data = pqnode->data; free(pqnode); return data; } void BFSTraverse(MGraph G) { printf("廣度優先遍歷序列:"); int i,v,w; for(i=0;i<G.vexnum;i++) visited[i] = false; PQueue pqueue = initQueue(); //初始化輔助佇列 for(i=0;i<G.vexnum;i++) { if(!visited[i]) //i未被訪問 { visited[i] = true; printf("%c ",G.vexs[i]); enQueue(pqueue,i); while(!isEmpty(pqueue)) { v = deQueue(pqueue); //隊頭元素出隊 for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)) if(!visited[w]) //w為v的尚未訪問的鄰接頂點 { visited[w] = true; printf("%c ",G.vexs[w]); enQueue(pqueue,w); } } } } printf("\n"); } int main() { // MGraph umg; //無權圖 // createUMGraph(&umg); //建立無權圖 // print(umg); MGraph mg; createMGraph(&mg); print(mg); DFSTraverse(mg); BFSTraverse(mg); return 0; }

這裡寫圖片描述