圖的遍歷(廣度優先搜尋遍歷)
阿新 • • 發佈:2018-12-29
1、廣度優先搜尋遍歷過程
(1)從某個頂點V出發,訪問該頂點的所有鄰接點V1,V2..VN
(2)從鄰接點V1,V2...VN出發,再訪問他們各自的所有鄰接點
(3)重複上述步驟,直到所有的頂點都被訪問過
若此時圖中還有頂點未被訪問,則在外控演算法的控制下,另選一個未曾被訪問的頂點作為起始點,重複上述過程,直到圖中所有頂點都被訪問完為止。
2、示例
對圖7-28連通無向圖廣度優先搜尋(以v0為出發點):v0,v1,v2,v3,v4,v5,v6,v7,v8
對圖7-29非連通無向圖廣度優先搜尋(以v0為出發點):v0,v1,v2,v3,v4,v5,v6,v7,v4為另一個起始點
對圖7-30(a)有向圖的廣度優先搜尋(v2為出發點):v2,v1,v3,v0,v4
對圖7-30(b)有向圖的廣度優先搜尋(v0為出發點):v0,v1,v4,v3,v2,v2為另一出發點
3、連通圖的廣度優先搜尋遍歷演算法過程
基本思想:假設初始狀態圖中所有頂點未被訪問,從圖中某頂點v出發,訪問它的所有鄰接點w1,w2,...,wd,然後再依次訪問w1,w2,...,wd的鄰接點,直到所有與v有相通路 徑的所有頂點都被訪問完為止。
程式碼:
(1) 採用鄰接矩陣從v出發廣度優先搜尋遍歷連通圖
#include <iostream> using namespace std; #define INFINITY 65535 /* 表示權值的無窮*/ typedef int EdgeType;//邊上的權值型別 typedef int VertexType;//頂點型別 const int MaxSize=100; int visited[MaxSize];//全域性標識陣列 class MGraph//鄰接矩陣類 { public: MGraph(){vertexNum=0;edgeNum=0;} MGraph(VertexType a[],int n);//建構函式,初始化具有n個頂點的零圖 void CreateMGraph1(MGraph *Gp);//建立無向圖的鄰接矩陣 void BFS(int v);//從v出發廣度優先遍歷 public: int vertexNum,edgeNum;//頂點數和邊數 EdgeType adj[MaxSize][MaxSize];//鄰接矩陣 VertexType vertex[MaxSize];//頂點表 }; //建構函式,初始化具有n個頂點的零圖 MGraph::MGraph(VertexType a[],int n) { vertexNum=n;edgeNum=0; for(int i=0;i<n;i++) vertex[i]=a[i]; for(int i=0;i<n;i++) for(int j=0;j<n;j++) adj[i][j]=0; } //建立無向圖的鄰接矩陣表示 void MGraph::CreateMGraph1(MGraph *Gp) { int i, j, k; cout << "請輸入頂點數和邊數(空格分隔):" << endl; cin >> Gp->vertexNum >> Gp->edgeNum; cout << "請輸入頂點資訊(空格分隔):" << endl; for (i = 0; i < Gp->vertexNum; i++) cin >> Gp->vertex[i]; for (i = 0; i < Gp->vertexNum; i++) { for (j = 0; j < Gp->vertexNum; j++) Gp->adj[i][j] = 0; } for (k = 0; k < Gp->edgeNum; k++) { cout << "請輸入邊(vi, vj)的上標i,下標j(空格分隔):" << endl; cin >> i >> j; Gp->adj[i][j] = 1; Gp->adj[j][i] = 1;// 因為是無向圖,矩陣對稱 } } //從v出發廣度優先搜尋遍歷連通圖 void MGraph::BFS(int v) { int n=vertexNum,front,rear; int Q[MaxSize];//佇列 front=rear=-1; if(v<0||v>=n) throw "位置出錯"; cout<<vertex[v]<<" "; visited[v]=1; Q[++rear]=v;//被訪問過的頂點進入佇列 while(front!=rear) { v=Q[++front];//佇列首元素出佇列 for(int j=0;j<n;j++) { if(adj[v][j]==1&&visited[j]==0) { cout<<vertex[j]<<" "; visited[j]=1; Q[++rear]=j; } } } } int main() { MGraph grph; grph.CreateMGraph1(&grph); for(int i=0;i<MaxSize;i++) visited[i]=0; for(int i=0;i<grph.vertexNum;i++) { for(int j=0;j<grph.vertexNum;j++) {cout<<grph.adj[i][j]<<" ";} cout<<endl; } cout<<"廣度優先遍歷結果:"<<endl; grph.BFS(2); return 0; }
(2) 採用鄰接表從v出發廣度優先搜尋遍歷連通圖
#include <iostream> using namespace std; #define INFINITY 65535 /* 表示權值的無窮*/ typedef int EdgeType;//邊上的權值型別 typedef int VertexType;//頂點型別 const int MaxSize=100; int visited[MaxSize];//全域性標識陣列 //無向圖鄰接表。邊表結點結構 struct EdgeNode { int adjvex;//鄰接點域 EdgeNode *next;//指向下一個邊結點的指標 }; //無向圖鄰接表。表頭結點結構 struct VexNode { VertexType vertex;//頂點 EdgeNode *firstedge;//邊表的頭指標 }; //鄰接表類 class ALGraph { public: ALGraph()//無參建構函式 { vertexNum=0; edgeNum=0; for(int i=0;i<MaxSize;i++) adjlist[i].firstedge=NULL; } ALGraph(VertexType a[],int n);//有參建構函式 void createGraph(int start, int end);//建立圖,採取前插法 void BFSL(int v);//從v廣度優先搜尋 void displayGraph(int nodeNum);//列印 private: VexNode adjlist[MaxSize];//存放頂點表的陣列 int vertexNum,edgeNum;//圖的頂點數和邊數 }; //有參建構函式。構造頂點表 ALGraph::ALGraph(VertexType a[],int n) { vertexNum=n; edgeNum=0; for(int i=0;i<vertexNum;i++) { adjlist[i].vertex=a[i]; adjlist[i].firstedge=NULL; } } //建立圖,採取前插法 void ALGraph::createGraph(int start, int end) {//邊(start,end) //adjlist[start].vertex=start;//表頭結點中的頂點 EdgeNode *p=new EdgeNode;//邊結點 p->adjvex=end;//鄰接點 //p->weight=weight; p->next=adjlist[start].firstedge;//前插法插入邊結點p adjlist[start].firstedge=p; } //列印儲存的圖 void ALGraph::displayGraph(int nodeNum) { int i,j; EdgeNode *p; for(i=0;i<nodeNum;i++) { p=adjlist[i].firstedge; while(p) { cout<<'('<<adjlist[i].vertex<<','<<p->adjvex<<')'<<endl; p=p->next; } } } //從v廣度優先搜尋 void ALGraph::BFSL(int v) { int n=vertexNum; if(v>=n||v<0) throw "位置出錯"; int front,rear,j; int Q[MaxSize];//佇列 front=rear=-1;//假設佇列採用順序儲存,且不會發生溢位 EdgeNode *p;//邊結點 cout<<adjlist[v].vertex<<" "; visited[v]=1; Q[++rear]=v;//被訪問頂點進佇列 while(front!=rear) { v=Q[++front];//隊首元素出佇列 p=adjlist[v].firstedge;//邊表中的工作指標初始化 while(p) { j=p->adjvex;//頂點 if(visited[j]==0) { cout<<adjlist[j].vertex<<" "; visited[j]=1; Q[++rear]=j;//被訪問頂點進佇列 } p=p->next; } } } int main() { int a[5]={0,1,2,3,4}; ALGraph gr=ALGraph(a,5);//初始化表頭 gr.createGraph(0,1); gr.createGraph(0,3); gr.createGraph(1,0); gr.createGraph(1,2); gr.createGraph(2,1); gr.createGraph(2,3); gr.createGraph(2,4); gr.createGraph(3,0); gr.createGraph(3,2); gr.createGraph(3,4); gr.createGraph(4,2); gr.createGraph(4,3); cout<<"無向連通圖各個邊:"<<endl; gr.displayGraph(5); for(int i=0;i<MaxSize;i++) visited[i]=0; cout<<"廣度優先遍歷結果:"<<endl; gr.BFSL(0); return 0; }