圖的基本操作和實現
阿新 • • 發佈:2019-02-07
圖的基本操作與實現
(1)自選儲存結構,輸入含n個頂點(用字元表示頂點)和e條邊的圖G;
(2)求每個頂點的度,輸出結果;
(3) 指定任意頂點x為初始頂點,對圖G作DFS遍歷,輸出DFS頂點序列(提示:使用一個棧實現DFS);
(4) 指定任意頂點x為初始頂點,對圖G作BFS遍歷,輸出BFS頂點序列(提示:使用一個佇列實現BFS);
(5) 輸入頂點x,查詢圖G:若存在含x的頂點,則刪除該結點及與之相關連的邊,並作DFS遍歷(執行操作3);否則輸出資訊“無x”;
(6) 判斷圖G是否是連通圖,輸出資訊“YES”/“NO”;
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #define maxSize 100 using namespace std; int Count=0; const int Max=50; typedef char type; bool visited[100] = { false }; typedef struct ///定義資料結構:棧 { int *top; int *base; int Size; }Stack; typedef struct ///定義資料結構:佇列 { int *Front; int *Rear; int Size; } Queue; typedef struct ///定義資料結構:圖 { type vexs[Max]; bool arcs[Max][Max]; int vexnum,arcnum; } graph; void InitStack(Stack &s) ///對棧進行初始化 { if(!(s.top=s.base=(int *)malloc(maxSize*sizeof(int)))) return ; s.Size=maxSize; } void push(Stack &s,int e) ///入棧:將元素e壓入棧 { *s.top=e; s.top++; } void pop(Stack &s) ///出棧:棧頂指標減一 { if(s.base==s.top) return ; s.top--; } int top(Stack s) ///返回棧頂元素 { s.top--; return *s.top; } void InitQueue(Queue &q) ///初始化佇列 { if(!(q.Front=q.Rear=(int *)malloc(maxSize*sizeof(int)))) return ; q.Size=maxSize; } void Q_push(Queue &q,int e) ///入佇列:將元素e入佇列 { *q.Rear=e; q.Rear++; } int Q_pop(Queue &q) ///出佇列:返回隊頭元素,隊頭指標加一 { int e; if(q.Front==q.Rear) return 0; e=*q.Front; q.Front++; return e; } void Create(graph *g) ///建立鄰接矩陣並輸出 { int i,j; memset(g->arcs,0,sizeof(g->arcs)); for(i=0; i<g->arcnum; ++i) { int x,y; cin>>x>>y; g->arcs[x][y]=1; g->arcs[y][x]=1; } cout<<"無向鄰接表矩陣為:"<<endl; for(i=0; i<g->vexnum; i++) { for(j=0; j<g->vexnum; j++) cout<<g->arcs[i][j]<<" "; cout<<endl; } } void Du(graph *g) ///統計每個頂點的度 { int i,j; for(i=0; i<g->vexnum; i++) { int amount=0; for(j=0; j<g->vexnum; ++j) if(g->arcs[i][j]) ++amount; cout<<"頂點"<<g->vexs[i]<<"的度為"<<amount<<endl; } } void DFS(graph *g,int k) ///DFS深度優先搜尋 { int t,i; Stack s; InitStack(s); cout<<g->vexs[k]<<" "; visited[k]=true; push(s,k); while(s.base!=s.top) { t=top(s); if(i==g->vexnum) ///如果內層迴圈未找到沒被訪問的元素,則出棧 pop(s); for(i=0; i<g->vexnum; i++) { if(g->arcs[t][i]==1&&visited[i]==false) ///找出鄰接矩陣第t+1行中第一個未被訪問的元素 { visited[i]=true; ///找到後標誌為1,並輸出,入棧 cout<<g->vexs[i]<<" "; push(s,i); break; ///找到之後跳出內層迴圈,返回外層迴圈起始處,重複之前操作 } } } } void BFS(graph *g, int k) ///BFS廣度優先搜尋 { Queue q; InitQueue(q); visited[k]=true; cout<<g->vexs[k]<<" "; Q_push(q,k); while(q.Front!=q.Rear) { int t=Q_pop(q); for(int w=0; w<g->vexnum; w++) { if (g->arcs[t][w]!=0&&visited[w]==false) ///找出鄰接矩陣中t+1行所有未被訪問的元素 { visited[w]=true; ///每找到一個標誌為1併入佇列 cout<<g->vexs[w]<<" "; Q_push(q,w); } } } } void Is_in_graph(graph *g,char ch) ///查詢圖中是否存在頂點ch { int i,j,k; for(i=0; i<g->vexnum; i++) ///遍歷頂點陣列 if(ch==g->vexs[i]) break; if(i==g->vexnum) ///如果迴圈正常結束則i=g->vexnum,此時說明不存在該頂點 { printf("無%c",ch); return ; } else { for(j=0; j<g->vexnum; j++) ///如果存在,則將與頂點相關的邊覆蓋 for(k=0; k<g->vexnum; k++) { if(j>=i&&k>=i) g->arcs[j][k]=g->arcs[j+1][k+1]; if(j>=i&&k<i) g->arcs[j][k]=g->arcs[j+1][k]; if(j<i&&k>=i) g->arcs[j][k]=g->arcs[j][k+1]; } } for(j=0; j<g->vexnum; j++) ///覆蓋該頂點 if(j>=i) g->vexs[j]=g->vexs[j+1]; g->vexnum--; cout<<"刪除該頂點後剩餘頂點為:\n"; for(j=0; j<g->vexnum; j++) cout<<g->vexs[j]<<" "; cout<<endl; cout<<"刪除後鄰接矩陣為:\n"; for(j=0; j<g->vexnum; j++) { for(k=0; k<g->vexnum; k++) cout<<g->arcs[j][k]<<" "; cout<<endl; } cout<<"從第一個頂點開始的DFS遍歷為:\n"; DFS(g,0); } void Is_connect(graph *g,int k) ///利用DFS搜尋的思想遍歷圖,每遍歷一個頂點計數加一 { visited[k]=true; Count++; for(int i=0; i<g->vexnum; i++) if(g->arcs[k][i]==1&&visited[i]==false) { Is_connect(g,i); } } void main_menu() ///主選單 { cout<<"-----------------------------------\n"; cout<<"---------程式主選單----------------\n"; cout<<"-----------------------------------\n"; cout<<"---------1圖的創立及鄰接矩陣-------\n"; cout<<"---------2查詢圖中各頂點的度-------\n"; cout<<"---------3DFS遍歷圖----------------\n"; cout<<"---------4BFS遍歷圖----------------\n"; cout<<"---------5查詢頂點是否在圖中-------\n"; cout<<"---------6判斷是否為連通圖---------\n"; cout<<"---------7退出---------------------\n"; cout<<"---------回車鍵返回選單------------\n"; cout<<"-----------------------------------\n"; cout<<"---------請選擇:(1-7)--------------\n"; } int main() { int i,num; char ch; graph g; while(1) { system("cls"); main_menu(); scanf("%d",&num); system("cls"); switch(num) ///通過輸入1-7呼叫不同的功能 { case 1: printf("1圖的創立及鄰接矩陣\n\n"); printf("請輸入頂點的個數:"); cin>>g.vexnum; cout<<endl; printf("請輸入邊的條數:"); cin>>g.arcnum; printf("請輸入各頂點:"); for(i=0; i<g.vexnum; ++i) cin>>g.vexs[i]; cout<<endl; printf("請輸入各條邊i-j:\n"); Create(&g); printf("輸入任意鍵返回主選單:"); system("pause"); break; case 2: printf("2查詢圖中各頂點的度\n\n"); Du(&g); printf("輸入任意鍵返回主選單:"); system("pause"); break; case 3: printf("3DFS遍歷圖\n\n"); printf("請輸入開始的頂點:"); cin>>ch; cout<<endl; for(i=0;i<g.vexnum;i++) if(ch==g.vexs[i]) break; if(i>=g.vexnum) { printf("輸入數字有誤!"); printf("輸入任意鍵返回主選單:"); system("pause"); break; } printf("從該點開始DFS搜尋為:"); DFS(&g,i); cout<<endl; memset(visited,0,sizeof(visited)); ///將訪問標誌陣列初始化為0 printf("輸入任意鍵返回主選單:"); system("pause"); break; case 4: printf("4BFS遍歷圖\n\n"); printf("請輸入開始的頂點:"); cin>>ch; cout<<endl; for(i=0;i<g.vexnum;i++) if(ch==g.vexs[i]) break; if(i>=g.vexnum) { printf("輸入數字有誤!"); printf("輸入任意鍵返回主選單:"); system("pause"); break; } printf("從該點開始BFS搜尋為:"); BFS(&g,i); cout<<endl; memset(visited,0,sizeof(visited)); ///將訪問標誌陣列初始化為0 printf("輸入任意鍵返回主選單:"); system("pause"); break; case 5: printf("5查詢頂點是否在圖中\n\n"); printf("請輸入要查詢的頂點:"); cin>>ch; cout<<endl; Is_in_graph(&g,ch); cout<<endl; memset(visited,0,sizeof(visited)); ///將訪問標誌陣列初始化為0 printf("輸入任意鍵返回主選單:"); system("pause"); break; case 6: printf("6判斷是否為連通圖\n\n"); Is_connect(&g,0); if(Count==g.vexnum) printf("YES!"); else printf("NO!"); cout<<endl; Count=0; memset(visited,0,sizeof(visited)); ///將訪問標誌陣列初始化為0 printf("輸入任意鍵返回主選單:"); system("pause"); break; case 7: printf("退出成功"); return 0; } } }