實驗項目六 圖結構基本操作的實現
課程名稱:數據結構
實驗項目名稱:圖結構基本操作的實現
實驗目的:
1.掌握圖的基本操作—遍歷。
實驗要求:
1、 分別用DFS和BFS的方法實現一個無向圖的遍歷。
實驗過程:
1、 創建一個圖(可用鄰接矩陣或鄰接表的方式進行存儲);
2、 輸入選項:0或1,0為DFS,1為BFS。
3、 分別輸出DFS和BFS兩種遍歷序列;
實驗報告中給出DFS和BFS兩種遍歷的算法代碼。
實驗結果:
1、輸入頂點集:1 2 3 4 5 6 7 8
2、輸入邊的集合: 1 2
1 3
2 4
2 5
4 8
5 8
3 6
3 7
6 7
輸入:0(DFS)
輸出:DFS遍歷序列為:12485367
輸入:1(BFS)
輸出:BFS遍歷序列為:12345678
實驗分析:
1.簡單分析DFS與BFS實現時用到的方法(DFS通過遞歸函數實現,用到棧的數據結構,BFS用到隊列的數據結構);
2.列舉調試運行過程中出現的錯誤並分析原因。
要求:
(1) 程序要添加適當的注釋,程序的書寫要采用縮進格式。
(2) 程序要具在一定的健壯性,即當輸入數據非法時,程序也能適當地做出反應。
(3) 程序要做到界面友好,在程序運行時用戶可以根據相應的提示信息進行操作。
(4) 上傳源程序到課堂派。順序表的源程序保存為TraversalGraph.cpp。
#include<stdio.h> #include<iostream> using namespace std; #define MaxInt 32767 //表示極大值 #define MVNum 100 //最大定點數 #define OK 1 #define MAXQSIZE 100 typedef char VerTexType; //假設頂點的數據類型為字符型 typedef int ArcType; //假設邊的權值類型為整型 typedef struct { VerTexType vexs[MVNum]; //定點表 ArcType arcs[MVNum][MVNum]; //鄰接矩陣 int vexnum,arcnum; //圖的當前點和邊數 }AMGraph; AMGraph G; typedef struct { int *base; int front,rear; }SqQueue; int InitQueue(SqQueue &Q) {//構造一個空隊列Q Q.base=new int[MAXQSIZE]; //為隊列分配一個最大容量為MAXQSIZE的數組空間 if(!Q.base) exit(0); //存儲分配失敗 Q.front=Q.rear=0; //頭指針和尾指針為零,隊列為空 return OK; } int EnQueue(SqQueue &Q,int e) {//插入元素e為Q的新的隊尾元素 if((Q.rear+1)%MAXQSIZE==Q.front) //尾指針在循環意義上加1后等於頭指針,表明隊滿 return 0; Q.base[Q.rear]=e; //新元素插入隊尾 Q.rear=(Q.rear+1)%MAXQSIZE; //隊尾指針加1 return OK; } int DeQueue(SqQueue &Q,int &e) {//刪除Q的隊頭元素,用e返回其值 if(Q.front==Q.rear) return 0; //隊空 e=Q.base[Q.front]; //保存隊頭元素 Q.front=(Q.front+1)%MAXQSIZE; //隊頭指針加1 return OK; } int QueueEmpty(SqQueue &Q) { if (Q.front==Q.rear) return OK; else return 0; } int LocateVex(AMGraph G,int b) { int a; for(a=0;a<G.vexnum;a++) //判斷頂點在第幾個位置 { if(G.vexs[a]==b) return a; } } int CreateUDN(AMGraph &G) {//采用鄰接矩陣表示法,創建無向網G cout<<"請輸入頂點的個數:\n"; cin>>G.vexnum; //輸入總頂點數 cout<<"請輸入邊的條數:\n"; cin>>G.arcnum; //輸入總邊數 int i,j,k,v1,v2,w; cout<<"依次輸入頂點的信息:\n"; for(i=0;i<G.vexnum;i++) //依次輸入點的信息 cin>>G.vexs[i]; for(i=0;i<G.vexnum;i++) //初始化鄰接矩陣,邊的權值位置為極大值MaxInt for(j=0;j<G.vexnum;j++) G.arcs[i][j]=0; for(k=0;k<G.arcnum;k++) //構造鄰接矩陣 { cout<<"輸入一條邊依附的頂點: "; cin>>v1>>v2; //輸入一條邊依附的頂點及權值 // i=LocateVex(G,v1); // j=LocateVex(G,v2); //確定v1和v2在G中的位置,及頂點數組的下標 // G.arcs[i][j]=w; //變<v1,v2>的初值置為w // G.arcs[j][i]=G.arcs[i][j]; //置<v1,v2>的對稱邊<v2,v1>的權值為w G.arcs[v1][v2]=1; G.arcs[v2][v1]=1; } return OK; } bool visited[MVNum]; //訪問標志數組,其初值為“false” void DFS_AM(AMGraph G,int v) {//從第V個定點出發遞歸的深度優先遍歷圖G cout<<v; int w; visited[v]=1; //訪問第v個頂點,並置訪問標志數組相應分量值為true for(w=1;w<=G.vexnum;w++) if((G.arcs[v][w]!=0)&&(!visited[w])) DFS_AM(G,w); } void DFSTraverse(AMGraph G) {//對非連接圖G做深度優先遍歷 int v; for(v=0;v<G.vexnum;++v) visited[v]=0; for(v=1;v<=G.vexnum;++v) if(!visited[v]) DFS_AM(G,v); //對尚未訪問的頂點調用DFS } void BFS(AMGraph G,int v) {//按廣度優先非遞歸遍歷連接圖 cout<<v; int u,w; SqQueue Q; // for(w=0;w<G.vexnum;w++) // { // visited[w]=0; // } visited[v]=1; InitQueue(Q); EnQueue(Q,v); while(!QueueEmpty(Q)) { DeQueue(Q,u); for(w=1;w<=G.vexnum;w++) if((G.arcs[u][w]!=0)&&(!visited[w])) { cout<<w; visited[w]=1; EnQueue(Q,w); } } } main() { CreateUDN(G); int choose,v; while(1) { cout<<"請輸入功能0(DFS)或1(BFS):\n"; cin>>choose; if(choose==0) { DFS_AM(G,1); break; } else if(choose==1) { BFS(G,1); break; } else { cout<<"輸入錯誤,請重新輸入:\n"; } } }