广度优先搜索算法
1.基本概念
BFS即从图中的某个顶点出发,将与该顶点相邻接且未被访问过的结点全部访问完,然后按照之前的访问顺序依次再访问它们自己的邻接结点,直到图中的所有已经被访问道的邻接结点都被访问到。如果此时还有结点没有被访问到,则选择该结点继续按照之前的方式进行访问。
如下图所示:
该广度优先搜索算法的遍历过程如下:
首先访问结点A,然后找到A的邻接结点B和C,访问这两个结点。然后从B出发,找到B的未被访问的结点邻接结点D和E,然后访问这两个结点,然后从结点C出发,找到C的未被访问的邻接结点F和G,然后访问这两个结点,然后从结点D出发,找到D的违背访问的邻接结点H,访问这个结点。然后从结点E出发…依此类推。
2.非递归实现
由于广度优先搜索需要记录某结点的所有未被访问的邻接结点,并且需要按照这些邻接结点的访问顺序获得邻接结点,因此在实现时需要用到队列。
其实现如下所示:
void BFSTraverse(ALGraph G){ //非递归形式宽度优先访问树 for(int i = 0; i<G.vertexNum; i++) visited[i] = false; queue<int> Q; for(int v = 0; v<G.vertexNum; v++){ if(!visited[v]){ visited[v] = true; cout<<"node: "<<G.vertices[v].data<<" "; Q.push(v); while(!Q.empty()){ int u = Q.front(); Q.pop(); for(int w = FirstAdjVex(G,u); w>= 0; w = NextAdjVex(G, u, w)){ if(!visited[w]){ visited[w] = true; cout<<"node: "<<G.vertices[w].data<<" "; Q.push(w); } } } } } }
测试全部代码如下所示:
扫描二维码关注公众号,回复:
162328 查看本文章
// BFS.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <string> #include <queue> #include <stack> #define MAX_VERTEX_NUM 20 using namespace std; typedef int infoType;//弧信息 typedef char vertexType;//顶点保存字符信息 typedef int Status; typedef struct ArcNode{ int adjvex; struct ArcNode *nextArc; infoType *info; }ArcNode; typedef struct VertexNode{ vertexType data; ArcNode *firstArc; }VertexNode, AdjList[MAX_VERTEX_NUM]; typedef struct ALGraph{ AdjList vertices; int vertexNum, arcNum; string kind; }ALGraph; int locateNode(ALGraph &G, VertexNode node){ for(int i=0; i<G.vertexNum;i++){ if(node.data == G.vertices[i].data) return i; } return -1; } void insertArcAction(ALGraph &G, int nodeNum1, int nodeNum2); Status insertArc(ALGraph &G, VertexNode node1, VertexNode node2); Status createGraph(ALGraph &G, string kind, int vertexNum, int arcNum){ //采用邻接表构造图(有向或无向图) G.kind = kind; G.vertexNum = vertexNum; G.arcNum = arcNum; //初始化顶点信息 for(int i = 0; i<G.vertexNum; i++){ cin>>G.vertices[i].data; G.vertices[i].firstArc = NULL; } cout<<"Try to input arcs info"<<endl; for(int j = 0; j<G.arcNum; j++){ cout<<"please input two nodes of "<<j+1<<"-th arc"<<endl; VertexNode node1, node2; cin>>node1.data>>node2.data; insertArc(G, node1, node2); } return 1; } void insertArcAction(ALGraph &G, int nodeNum1, int nodeNum2){ ArcNode *p; ArcNode *arc; arc = new ArcNode[1]; arc->adjvex = nodeNum2; p = G.vertices[nodeNum1].firstArc;//相当于链表的插入 if(!p){ G.vertices[nodeNum1].firstArc = arc; arc->nextArc = NULL; } else{ G.vertices[nodeNum1].firstArc = arc; arc->nextArc = p; } } Status insertArc(ALGraph &G, VertexNode node1, VertexNode node2){ int nodeNum1 = locateNode(G, node1);//i和j表示AdjList[MAX_VERTEX_NUM]中的位置 int nodeNum2 = locateNode(G, node2); if(nodeNum1<0 || nodeNum2<0) exit(-1); if(G.kind == "DG") insertArcAction(G, nodeNum1, nodeNum2); else{ insertArcAction(G, nodeNum1, nodeNum2); insertArcAction(G, nodeNum2, nodeNum1); } return 1; } Status printALGraph(ALGraph &G){ for(int i = 0; i<G.vertexNum; i++){ cout<<i<<" "<<G.vertices[i].data; ArcNode *arc = G.vertices[i].firstArc; while(arc){ cout<<"-->"<<arc->adjvex; arc = arc->nextArc; } cout<<"-->NULL"<<endl; } return 1; } bool visited[MAX_VERTEX_NUM]; int FirstAdjVex(ALGraph G, int j){ ArcNode *firstArc = G.vertices[j].firstArc; if(firstArc) return (firstArc->adjvex); else return -1; } int NextAdjVex(ALGraph G, int j, int k){ ArcNode *firstArc = G.vertices[j].firstArc; ArcNode *cur = firstArc; if(!firstArc) return -1; else{ while(cur){ if(cur->adjvex == k) break; cur = cur->nextArc; } } if(cur->nextArc) return (cur->nextArc->adjvex); else return -1; } void BFSTraverse(ALGraph G){ //非递归形式宽度优先访问树 for(int i = 0; i<G.vertexNum; i++) visited[i] = false; queue<int> Q; for(int v = 0; v<G.vertexNum; v++){ if(!visited[v]){ visited[v] = true; cout<<"node: "<<G.vertices[v].data<<" "; Q.push(v); while(!Q.empty()){ int u = Q.front(); Q.pop(); for(int w = FirstAdjVex(G,u); w>= 0; w = NextAdjVex(G, u, w)){ if(!visited[w]){ visited[w] = true; cout<<"node: "<<G.vertices[w].data<<" "; Q.push(w); } } } } } } int _tmain(int argc, _TCHAR* argv[]) { ALGraph G; string kind = "UDG"; int vertexNum = 9; int arcNum = 9; cout<<"Try to create a Adjacency list Graph ..."<<endl; createGraph(G, kind, vertexNum, arcNum); cout<<"Try to print a Adjacence list Graph ..."<<endl; printALGraph(G); cout<<"Try to traverse a undigraph in a regular form..."<<endl;//非递归 BFSTraverse(G); cout<<endl; system("pause"); return 0; }