思路:
用隊列實現圖的非遞歸BFS。首先把遍歷起始頂點push進隊列;然後每次從隊列中pop一個頂點時,都遍歷此頂點,並遍歷邊表,找出與此頂點相連接的頂點,若此連接頂點未被訪問,則入隊,若此頂點已被訪問,則繼續,直到隊列爲空,寬度遍歷結束。
注意:寬度遍歷圖時,所有頂點被訪問到的前提條件爲此圖爲連通圖。
代碼:
#include <iostream>
#include<vector>
#include<queue>
using namespace std;
typedef int T; //頂點的值類型 int, char, double and so on
struct Node
{
T value; //頂點值
int numbers; //頂點編號
bool operator==(const Node &other)
{
if((this->numbers==other.numbers)&&(this->value==other.value))
return true;
else
return false;
}
Node(int a1=0,int a2=0)
{
numbers=a1;
value=a2;
}
};
struct Edge
{
int num1; //起始頂點
int num2; //終止頂點
int weight; //邊所對應的權值
};
class Graph
{
private:
int vertex_nums; //頂點數
int edge_nums; //邊數Ss
vector<Node> vertex; //頂點表,強制設爲編號從0開始
vector<Edge> edge; //邊表
vector<vector<int> > edge_maze; //鄰接矩陣,存儲各個頂點連接關係
public:
Graph(int n1=10,int n2=10)
{
vertex_nums=n1;
edge_nums=n2;
for(int i=0;i<vertex_nums;i++)
{
Node a;
a.numbers=i;
a.value=0;
vertex.push_back(a);
}
for(int i=0;i<vertex_nums;i++) //鄰接矩陣初始化
{
vector<int> temp(vertex_nums,0);
edge_maze.push_back(temp);
}
cout<<"please input the edges about the graph: vertex_number1 vertex_number2 weight"<<endl;
int x,y,z;
for(int i=0;i<edge_nums;i++)
{
cin>>x>>y>>z;
Edge temp_edge;
temp_edge.num1=x;
temp_edge.num2=y;
temp_edge.weight=z;
edge.push_back(temp_edge);
edge_maze[x][y]=1;
edge_maze[y][x]=1;
}
}
void print_edge_maze()
{
cout<<endl;
cout<<"輸出鄰接矩陣"<<endl;
cout<<" ";
for(int i=0;i<vertex_nums;i++)
cout<<"v"<<i<<" ";
cout<<endl;
for(int i=0;i<vertex_nums;i++)
{
cout<<"v"<<i<<" ";
for(int j=0;j<vertex_nums;j++)
{
cout<<edge_maze[i][j]<<" ";
}
cout<<endl;
}
}
void print_edge_vec()
{
cout<<endl;
cout<<"輸出邊表:"<<endl;
cout<<"起始頂點-->結束頂點 邊權值"<<endl;
for(int i=0;i<edge_nums;i++)
{
cout<<" v"<<edge[i].num1<<" -->"<<" v"<<edge[i].num2<<" "<<edge[i].weight<<endl;
}
}
//基於BFS非遞歸遍歷圖
void BFS_Graph_nonrecursive(int start_vertex_num=0)
{
vector<int> if_output(vertex_nums,0); //指示頂點是否被遍歷
Node first(start_vertex_num);
queue<Node> qu;
qu.push(first);
if_output[start_vertex_num]=1; //入隊即表示即將被遍歷
cout<<endl;
cout<<"遍歷頂點路徑如下"<<endl;
while(!qu.empty())
{
Node temp=qu.front();
qu.pop();
cout<<"v"<<temp.numbers<<"---->";
//遍歷所有邊,找到與隊列頭結點連接的頂點,將所有與頭頂點連接的頂點加入隊列
for(int i=0;i<edge_nums;i++)
{
if(edge[i].num1==temp.numbers)
{
if(if_output[edge[i].num2]==0) //未被遍歷
{
Node temp_node(edge[i].num2); //將連接點加入隊列
qu.push(temp_node);
if_output[edge[i].num2]=1; //入隊即表示即將被遍歷
}
}
else if(edge[i].num2==temp.numbers)
{
if(if_output[edge[i].num1]==0) //未被遍歷
{
Node temp_node(edge[i].num1); //將連接點加入隊列
qu.push(temp_node);
if_output[edge[i].num1]=1;
}
}
else
continue;
}
}
cout<<"end"<<endl;
cout<<"遍歷結束"<<endl;
}
};
int main()
{
Graph graph(8,10);
graph.print_edge_vec();
graph.print_edge_maze();
graph.BFS_Graph_nonrecursive();
return 0;
}
輸出:
please input the edges about the graph: vertex_number1 vertex_number2 weight
0 1 0
1 2 1
2 3 2
3 4 3
4 5 4
5 6 5
6 7 6
7 3 7
7 4 8
6 4 9
輸出邊表:
起始頂點-->結束頂點 邊權值
v0 --> v1 0
v1 --> v2 1
v2 --> v3 2
v3 --> v4 3
v4 --> v5 4
v5 --> v6 5
v6 --> v7 6
v7 --> v3 7
v7 --> v4 8
v6 --> v4 9
輸出鄰接矩陣
v0 v1 v2 v3 v4 v5 v6 v7
v0 0 1 0 0 0 0 0 0
v1 1 0 1 0 0 0 0 0
v2 0 1 0 1 0 0 0 0
v3 0 0 1 0 1 0 0 1
v4 0 0 0 1 0 1 1 1
v5 0 0 0 0 1 0 1 0
v6 0 0 0 0 1 1 0 1
v7 0 0 0 1 1 0 1 0
遍歷頂點路徑如下
v0---->v1---->v2---->v3---->v4---->v7---->v5---->v6---->end
遍歷結束