廣度優先
廣度優先搜索遍歷連通圖
#include <iostream>
using namespace std;
#define MVNum 100 //最大頂點數
#define MAXQSIZE 100 //最大隊列長度
typedef char VerTexType; //假設頂點的數據類型為字符型
typedef int ArcType; //假設邊的權值類型為整型
bool visited[MVNum]; //訪問標志數組,其初值為"false"
//-----圖的鄰接矩陣存儲表示-----
typedef struct{
VerTexType vexs[MVNum]; //頂點表
ArcType arcs[MVNum][MVNum]; //鄰接矩陣
int vexnum,arcnum; //圖的當前點數和邊數
}Graph;
//----隊列的定義及操作--------
typedef struct{
ArcType *base; //初始化的動態分配存儲空間
int front; //頭指針,若隊列不空,指向隊頭元素
int rear; //尾指針,若隊列不空,指向隊尾元素的下一個位置
}sqQueue;
void InitQueue(sqQueue &Q){
//構造一個空隊列Q
Q.base = new ArcType[MAXQSIZE];
if(!Q.base) exit(1); //存儲分配失敗
Q.front = Q.rear = 0;
}//InitQueue
void EnQueue(sqQueue &Q, ArcType e){
//插入元素e為Q的新的隊尾元素
if((Q.rear + 1) % MAXQSIZE == Q.front)
return;
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXQSIZE;
}//EnQueue
bool QueueEmpty(sqQueue Q){
//判斷是否為空隊
if(Q.rear == Q.front)
return true;
return false;
}//QueueEmpty
void DeQueue(sqQueue &Q, ArcType &u){
//隊頭元素出隊並置為u
u = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXQSIZE;
}//DeQueue
//--------------------------------------------------
int LocateVex(Graph G , VerTexType v){
//確定點v在G中的位置
for(int i = 0; i < G.vexnum; ++i)
if(G.vexs[i] == v)
return i;
return -1;
}//LocateVex
void CreateUDN(Graph &G){
//采用鄰接矩陣表示法,創建無向網G
int i , j , k;
cout <<"請輸入總頂點數,總邊數,以空格隔開:";
cin >> G.vexnum >> G.arcnum; //輸入總頂點數,總邊數
cout << endl;
cout << "輸入點的名稱,如a" << endl;
for(i = 0; i < G.vexnum; ++i){
cout << "請輸入第" << (i+1) << "個點的名稱:";
cin >> G.vexs[i]; //依次輸入點的信息
}
cout << endl;
for(i = 0; i < G.vexnum; ++i) //初始化鄰接矩陣,邊的權值均置為極大值MaxInt
for(j = 0; j < G.vexnum; ++j)
G.arcs[i][j] = 0;
cout << "輸入邊依附的頂點,如a b" << endl;
for(k = 0; k < G.arcnum;++k){ //構造鄰接矩陣
VerTexType v1 , v2;
cout << "請輸入第" << (k + 1) << "條邊依附的頂點:";
cin >> v1 >> v2; //輸入一條邊依附的頂點
i = LocateVex(G, v1); j = LocateVex(G, v2); //確定v1和v2在G中的位置,即頂點數組的下標
G.arcs[i][j] = 1; //邊<v1, v2>的權值置為w
G.arcs[j][i] = G.arcs[i][j]; //置<v1, v2>的對稱邊<v2, v1>的權值為w
}//for
}//CreateUDN
int FirstAdjVex(Graph G , int v){
//返回v的第一個鄰接點
int i;
for(i = 0 ; i < G.vexnum ; ++i){
if(G.arcs[v][i] == 1 && visited[i] == false)
return i;
}
return -1;
}//FirstAdjVex
int NextAdjVex(Graph G , int u , int w){
//返回v相對於w的下一個鄰接點
int i;
for(i = w ; i < G.vexnum ; ++i){
if(G.arcs[u][i] == 1 && visited[i] == false)
return i;
}
return -1;
}//NextAdjVex
void BFS (Graph G, int v){
//按廣度優先非遞歸遍歷連通圖G
sqQueue Q;
ArcType u;
ArcType w;
// int u,w;
cout << G.vexs[v] << " "; visited[v] = true; //訪問第v個頂點,並置訪問標志數組相應分量值為true
InitQueue(Q); //輔助隊列Q初始化,置空
EnQueue(Q, v); //v進隊
while(!QueueEmpty(Q)){ //隊列非空
DeQueue(Q, u); //隊頭元素出隊並置為u
for(w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w)){
//依次檢查u的所有鄰接點w ,修改該語句使得能夠得到正確
if(!visited[w]){ //w為u的尚未訪問的鄰接頂點
cout << G.vexs[w] << " "; visited[w] = true; //訪問w,並置訪問標志數組相應分量值為true
EnQueue(Q, w); //w進隊
}//if
}//for
}//while
}//BFS
int main(){
cout << "************算法6.7 廣度優先搜索遍歷連通圖**************" << endl << endl;
Graph G;
CreateUDN(G);
cout << endl;
cout << "無向連通圖G創建完成!" << endl << endl;
cout << "請輸入遍歷連通圖的起始點:";
VerTexType c;
cin >> c;
int i;
for(i = 0 ; i < G.vexnum ; ++i){
if(c == G.vexs[i])
break;
}
cout << endl;
while(i >= G.vexnum){
cout << "該點不存在,請重新輸入!" << endl;
cout << "請輸入遍歷連通圖的起始點:";
cin >> c;
for(i = 0 ; i < G.vexnum ; ++i){
if(c == G.vexs[i])
break;
}
}
cout << "廣度優先搜索遍歷連通圖結果:" << endl;
BFS(G , i);
cout <<endl;
return 0;
}//main