資料結構--圖--圖的陣列儲存表示,深度優先搜尋遍歷和廣度優先搜尋遍歷
阿新 • • 發佈:2019-02-12
圖有四種儲存結構:陣列,鄰接表,十字連結串列,鄰接多重表。下面以陣列為儲存結構來實現圖的深度優先搜尋遍歷和廣度優先搜尋遍歷。其中廣度優先搜尋遍歷中有用到STL中的queue,注意標頭檔案的包含。具體程式碼如下:
//圖的陣列(鄰接矩陣)儲存表示和深度優先遍歷 const int MAX_VERTEX_NUM=20; //最大頂點數 typedef enum {DG,DN,UDG,UDN} GraphKind ;//(有向圖,有向網,無向圖,無向網) typedef int VRType; typedef char InfoType; typedef char VertexType; typedef struct ArcCell{ VRType adj; //VRType是頂點關係型別,對於無權圖,用1或者0表示頂點相鄰與否,對於有權圖,則為權值型別 InfoType info;//該弧相關資訊指標 ArcCell(){ adj=0; info=0; } }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct MGraph{ VertexType vexs[MAX_VERTEX_NUM]; //頂點向量 AdjMatrix arcs; //鄰接矩陣 int vexnum,arcnum; //圖當前的頂點數和弧數 GraphKind kind; //圖的種類標誌 }MGraph; int LocateVex(MGraph G,char v1){ for(int i=0;i<MAX_VERTEX_NUM;++i){ if(G.vexs[i]==v1) return i; } return MAX_VERTEX_NUM+1; } Status CreateUDN(MGraph &G){//採用陣列(鄰接矩陣)表示法,構建無向網 G.kind=UDN; //手動賦值為無向網 int vexnumber=0,arcnumber=0; char info; cout<<"please input the vexnumber arcnumber and info:"; cin>>vexnumber>>arcnumber>>info; G.vexnum=vexnumber; G.arcnum=arcnumber; for(int i=0;i<G.vexnum;++i){ //構造頂點向量 cout<<"please input the vertex of number "<<i<<"(type char) "; cin>>G.vexs[i]; } for(int i=0;i<G.vexnum;++i) //初始化鄰接矩陣 for(int j=0;j<G.vexnum;++j){ G.arcs[i][j].adj=0; G.arcs[i][j].info=0; } char v1,v2; int weight=0,i=0,j=0; char infomation; for(int k=0;k<G.arcnum;++k){ //初始化鄰接矩陣 cout<<"please input the two vertexs of the arc and it's weight "<<k+1<<" "; cin>>v1>>v2>>weight; i=LocateVex(G,v1); j=LocateVex(G,v2); G.arcs[i][j].adj=weight; G.arcs[j][i].adj=weight; if(info!=48){//0的ascii碼為48 cout<<"please input infomation: "; cin>>infomation; G.arcs[i][j].info=infomation; G.arcs[j][i].info=infomation; } } return OK; } void DisMGraph(MGraph m){ for(int i=0;i<m.vexnum;++i){ for(int j=0;j<m.vexnum;++j){ cout<<m.arcs[i][j].adj<<" "; } cout<<endl; } } //樹的深度優先遍歷和廣度優先搜尋遍歷 bool visited[MAX_VERTEX_NUM] ;//訪問標誌陣列 Status VisitFunc(MGraph G,int v){ //函式變數 if(G.vexs[v]){ cout<<G.vexs[v]<<" "; return OK; } return ERROR; } int FirstAdjVex(MGraph G,int v){ //返回圖G中頂點V的第一個鄰接點 if(G.vexnum==0) return -1; //確定圖G存在 for(int j=0;j<G.vexnum;++j){ if(G.arcs[v][j].adj) return j; } return -1; } int NextAdjVex(MGraph G,int v,int w){ //返回頂點v的相對與w的下一個鄰接點 if(G.vexnum==0) return -1; //確定圖G存在 for(int j=w+1;j<G.vexnum;++j){ if(G.arcs[v][j].adj) return j; } return -1; } void DFS(MGraph G,int v){ //從第v個頂點出發,深度優先搜尋遍歷圖G visited[v]=true; VisitFunc(G,v); //訪問第v個結點 for(int w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)){ if(!visited[w]) DFS(G,w); //對v的尚未訪問的鄰接頂點W遞迴呼叫DFS } } void DFSTraverse(MGraph G,Status (*Visit)(MGraph G,int v)){ //對圖做深度優先遍歷 for(int v=0;v<G.vexnum;++v){ //訪問標誌陣列初始化 visited[v]=false; } for(int v=0;v<G.vexnum;++v){ if(!visited[v]) DFS(G,v); //對尚未訪問的結點呼叫DFS } } void BFSTraverse(MGraph G,Status (*Visit)(MGraph G,int v)){//廣度優先搜尋遍歷圖 for(int v=0;v<G.vexnum;++v) visited[v]=false; queue<char> que; char tempvex=0; for(int v=0;v<G.vexnum;++v){ if(!visited[v]) { visited[v]=true; Visit(G,v); que.push(G.vexs[v]); while(!que.empty()){ tempvex=que.front(); que.pop(); for(int w=FirstAdjVex(G,tempvex);w>=0;w=NextAdjVex(G,tempvex,w)){ if(!visited[w]){ visited[w]=true; Visit(G,w); que.push(G.vexs[w]); } } } } } } int main() { MGraph m; CreateUDN(m); DisMGraph(m); cout<<"DFS result:"; DFSTraverse(m,VisitFunc); cout<<endl<<"BFS result:"; BFSTraverse(m,VisitFunc); return 0; }
執行結果: