BFS(广度优先搜索)是图的一个基本的也很简单的搜索算法,也是很多图的基本算法的原型。后面提到的最小生成树prim算法和Dijkstra的单源最短路径都是用了类似广度优先搜索的思想。
广度优先搜索的基本思想是给定一个图
G=(V,E)
和一个可以识别的源节点 S,BFS对图G中的边进行系统性的探测搜索来发现所有可以从源节点S到达的所有节点。具体的描述是:
while
Q≠∅
//当队列不为空
u=DeQueue(Q) //队首元素出队
for each
v∈G.Adj[u]
//对于每一个和u邻接的顶点
if(v.color==white)
v.color=gray
EnQueue(Q,v)
u.color=black
下面给一个简单的代码示例:
/*
Problem:BFS
Author:Shaocong Liang
Date:2015-3-29
*/
#include <iostream>
#include <vector>
#include <queue>
using std::vector;using std::queue;
#define N 4 //点数
#define INIFY -1 //初始化
enum Visit {
white,gray,black
};
struct Edge{
int from;
int to;
int weight;
Visit label;
Edge *next;
Edge():from(INIFY),to(INIFY),weight(INIFY),label(white),next(nullptr){
}
Edge(int u,int v,int w):from(u),to(v),weight(w){ }
};
Edge *edge[N]={nullptr,nullptr,nullptr};
void create_adj(){
int u,v,w;
std::cout<<"请输入顶点间的邻接关系(u,v,w),并以-2作为结束."<<std::endl;
Edge *p=nullptr;
while(std::cin>>u>>v>>w && u!=-2,v!=-2){
p=new Edge(u,v,w);
p->next=edge[u];
edge[u]=p;
//如果是无向图
p=new Edge(v,u,w);
p->next=edge[v];
edge[v]=p;
}
}
void BFS(Edge *edge[]){
//出发节点为0
int Queue[N],rear=0,front=0;
Queue[rear++]=0;
edge[Queue[front]]->label=gray;
while(front!=rear){
int v=Queue[front++]; //从第一个点出发探测
Edge *p=edge[v];
//对于每一个和v邻接的顶点
for(;p!=nullptr;p=p->next){
if(edge[p->to]->label==white){ //和该节点邻接且没有被访问过
edge[p->to]->label=gray;
Queue[rear++]=p->to; //进入队列
std::cout<<p->to<<"\t";
}
}
p->label=black;
}
}
int main(void){
create_adj();
BFS(edge);
}
参考书籍:算法导论