基於鄰接表儲存的圖的DFS與BFS遍歷
阿新 • • 發佈:2019-02-01
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <queue> using namespace std; #define MAXNODE 1000// 圖中頂點的最大個數 typedef int infotype; typedef char vertype; struct ArcNode//邊節點型別 { int adjvex;//該邊的終點編號 ArcNode *next;//指向下一條邊的指標 infotype *info;//該邊的相關資訊 }; struct VerNode//表頭結點 { vertype vertex;// 頂點資訊 ArcNode *firstarc;// 指向第一個鄰接點的指標 }; struct AlGraph//鄰接表 { VerNode vertices[MAXNODE];//鄰接表 int vexnum,arcnum;// 頂點和邊的數目 }; AlGraph CreatAdjList(AlGraph g)//建立有向圖的鄰接表儲存結構 { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>g.vertices[i].vertex;//輸入頂點資訊 g.vertices[i].firstarc=NULL;//初始化每個連結串列為空 } int v1,v2; cin>>v1>>v2;//輸入一條邊依附的兩個頂點序號 int e=0;//圖的邊數 while(v1!=0&&v2!=0)//題目要求兩頂點之一為0表示結束 { //i=GraphLocateVertex(g,v1); //j=GraphLocateVertex(g,v2); ArcNode *p= (ArcNode*)malloc(sizeof(ArcNode)); //用頭插法插入結點以建立連結串列 p->adjvex=v2; p->next=g.vertices[v1].firstarc; g.vertices[v1].firstarc=p; e++; cin>>v1>>v2; } g.vexnum=n; g.arcnum=e; return g; } int visited[MAXNODE];//訪問標誌陣列 void VisitFunc(AlGraph g,int v)//訪問v { cout<<g.vertices[v].vertex<<endl; } int GraphFirstAdj(AlGraph g,int v)//得到v的第一個鄰結點 { if(g.vertices[v].firstarc!=NULL) return g.vertices[v].firstarc->adjvex; else return 0; } int GraphNextAdj(AlGraph g,int v,int w)//返回v的(相對於w的)下一個鄰接點,若w是v的最後一個鄰接點,則返回0 { ArcNode *p= (ArcNode*)malloc(sizeof(ArcNode)); p=g.vertices[v].firstarc; while(p) { if(p->adjvex==w&&p->next!=NULL) return p->next->adjvex; p=p->next; } return 0; } void DFS(AlGraph g,int v)//dfs { visited[v]=1;VisitFunc(g,v);// 訪問v頂點(輸出v) for(int w=GraphFirstAdj(g,v);w!=0;w=GraphNextAdj(g,v,w)) { if(!visited[w])DFS(g,w);//對v的尚未訪問的鄰接頂點w遞規呼叫 } } void DFSTraverse(AlGraph g)//圖的dfs遍歷 { for(int i=1;i<=g.vexnum;i++)visited[i]=0;// 初始訪問陣列置未訪問標誌 for(int i=1;i<=g.vexnum;i++) { if(!visited[i])DFS(g,i);// 對未訪問過的頂點呼叫 DFS } } void BFSTraverse(AlGraph g)//圖的bfs遍歷 { for(int i=1;i<=g.vexnum;i++)visited[i]=0;// 初始訪問陣列 queue<int> q; for(int i=1;i<=g.vexnum;i++) { if(!visited[i]) { q.push(i); visited[i]=1; VisitFunc(g,i); while(!q.empty()) { int v = q.front();//對頭元素出佇列並置為v q.pop(); for(int w=GraphFirstAdj(g,v);w!=0;w=GraphNextAdj(g,v,w))//遍歷v的鄰結點 { if(!visited[w]) { q.push(w);//v的尚未訪問的鄰接頂點w入佇列Q visited[w]=1; VisitFunc(g,w); } } } } } }